PicManía by RedRaven
 

Búsqueda personalizada

 

PROYECTOS : Analizador Lógico

 

 

Analizador Lógico de 3 canales con un PIC 18F4550 (RRLogicalAnalyzer)

 

(Ver el Histórico de realización) donde detallo, día a día, lo que voy realizando con este proyecto ...

 

Descripción:
 

   La conclusión de este proyecto (siempre provisional) ya está disponible. Insisto en recomendar ver el Histórico de realización ya que es en él donde podéis ver todo lo realizado y cómo se ha llegado hasta este estado final.

 

 

El Firmware del PIC 18F4550 y el Software del PC hablan el mismo idioma ...

El PIC dispone de una recepción de comandos de dos tipos:

1.- Comandos destinados a volcar información a un Monitor RS232 Así puedo analizar los datos numéricamente si necesidad de Soft alguno (mas allá de un Siow, Hyperterminal o similar) Este grupo de comandos dispara el envío de la información de forma "amigable", tabulada y con cabeceras de explicación de qué es lo que está enviado. Le llamo "friendly_trans"

2.- Comandos destinados a enviar la información "formateada" al Soft del PC en la que se define una trama con: inicio de transmisión, datos encapsulados con inicio y fin de cada "churrete" y fin de transmisión. Este grupo de comandos dispara el envío de la información de forma sistemática con una estructura definida, fácil de procesar por el Soft del PC. Le llamo "hardy_trans".

Ejemplo de recepción de los mismos datos en formatos "amigable" y "duro" ...

Con el Monitor Siow de CCS C:

Y con el RRLOGICANALYZER.EXE del PC que ya recibe correctamente los datos recopilados por el PIC y es capaz de mostrármelos ... listos para dibujarlos.
1º Lista de comandos PC -> PIC

COMMAND_RESET = 'R';
COMMAND_FIRMWARE = 'W';
COMMAND_DATA = 'X';
COMMAND_CONFIG = 'C';
COMMAND_CONFIG1 = '1';
COMMAND_CONFIG2 = '2';
COMMAND_CONFIG3 = '3';

2º Comando de ACK (Acknowledge Receipt of a Packet) PIC -> PC

char const RESPONSE_ACK = '^';

printf("^\r\n");

3º Estructura de transmisión datos PIC -> PC

CI (Carácter de Inicio) = '{'
CF (Carácer de Finalizacion) = '}'

Estructura de envío : n * (CI + m * (data) + CF + '\r\n') + ACK

4º Estructura de datos de configuración, 1 byte:

Codificacion en Delphi:

  c.compreso := 0;
  if c.Active then c.compreso := c.compreso + 128;
  if c.Raising then c.compreso := c.compreso + 64;
  if c.Falling then c.compreso := c.compreso + 32;
  if c.Trigger then c.compreso := c.compreso + 16;
  if c.Invert then c.compreso := c.compreso + 8;

Decodificacion en CSS C por Bit

  // Habilito Canal 1
  if(bit_test(C1_SETTINGS,7)==1){
    enable_interrupts(int_ext);
  }
  ...
  // Configuro Channel1 Flanco inicial
  if(bit_test(C1_SETTINGS,7)==1){
    if(bit_test(C1_SETTINGS,5)==1){
      fedge1=0;
      ext_int_edge(0,H_TO_L);
    }
    if(bit_test(C1_SETTINGS,6)==1){
      fedge1=1;
      ext_int_edge(0,L_TO_H);
    }
  }

y 5º Estructura de datos de muestreo

CI + NumPulso + Canal + nRTCC raise + Timer raise + nRTCC fall + Timer fall + CF + "\r\n"

Emisión en CSS C:

  for(i=0;i<NMUESTRAS;i++){
    printf("{ %3u %1u %5lu %5lu %1u %5lu %5lu }\r\n",i+1,tUpC[ i ],tUpI[ i ],tUpT[ i ],tDownC[ i ],tDownI[ i ],tDownT[ i ]);
  }
  delay_ms(10);
  ack_trans();

===========================================================

E j e m p l o s


Ejemplo: Orden de "envíame" la versión del firmware actual.

Al recibir el PIC el comando 'W' envía el string "{1.2.0}[13][10]^\r\n"

Ejemplo : Conversación completa PC <-> PIC comentada

Transmit: W Receive: {1.2.0}[13][10]^[13][10] Pregunta firmare y recibe firmware

Transmit: C Receive: { 177 209 209 }[13][10]^[13][10] Pregunta configuración y recibe settings de los tres canales

Transmit: 1 Receive: ^[13][10] Envía "prepárate para recibir configuración canal 1" recibe ACK

Transmit: [177] Receive: ^[13][10] Envía "configuración canal 1" recibe ACK

Transmit: 2 Receive: ^[13][10] Envía "prepárate para recibir configuración canal 2" recibe ACK

Transmit: [177] Receive: ^[13][10] Envía "configuración canal 2" recibe ACK

Transmit: 3 Receive: ^[13][10] Envía "prepárate para recibir configuración canal 2" recibe ACK

Transmit: [177] Receive: ^[13][10] Envía "configuración canal 3" recibe ACK

Transmit: R Receive: ^[13][10] Envía "reseteate, limpia muestreos anteriores y reconfigúrate" recibe ACK

Transmit: C Receive: { 177 177 177 }[13][10]^[13][10] Envía "dame configuraciones" recibe configuraciones de los tres canales y ACK

Transmit: X

Receive: { 1 1 11 32930 1 0 8 }[13][10] Envía "dame muestreos" y recibe tabla de datos
{ 2 1 46 52262 1 37 43339 }[13][10]
{ 3 0 0 0 0 0 0 }[13][10]
{ 4 0 0 0 0 0 0 }[13][10]
{ 5 0 0 0 0 0 0 }[13][10]
...
{ 65 0 0 0 0 0 0 }[13][10]
^[13][10]



Nota 1: Todo el código completo al final de este proyecto.

Nota 2: Todo este control desarrollado para comunicar con un Soft específico que dibuje los pulsos en pantalla está disponible en el Firmware del 18F4550 para ser accedido numéricamente desde un simple terminal serie (Siow, Hyperterminal ... etc) estilo Telnet.
 

 

 
Recursos:
 
Descargar Firmware para el 18F4550 y Software para el PC del RRLogicalAnalyzer (ZIP 667 Kbytes)

 

 

 
 
  Firmware para el 18F4550  
  // RR Logical Analyzer v.1.2.2d

#include <18f4550.h>
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)

int const NMUESTRAS=192;

char const SOFT_COMMAND_RESET = 'r';
char const SOFT_COMMAND_FIRMWARE = 'w';
char const SOFT_COMMAND_DATA = 'x';
char const SOFT_COMMAND_CONFIG = 'c';
char const SOFT_COMMAND_EEPROM = 'e';

char const HARD_COMMAND_RESET = 'R';
char const HARD_COMMAND_FIRMWARE = 'W';
char const HARD_COMMAND_DATA = 'X';
char const HARD_COMMAND_CONFIG = 'C';
char const HARD_COMMAND_CONFIG1 = '1';
char const HARD_COMMAND_CONFIG2 = '2';
char const HARD_COMMAND_CONFIG3 = '3';
char const RESPONSE_ACK = '^';

int const DIR_C1_SETTINGS = 0;
int const DIR_C2_SETTINGS = 1;
int const DIR_C3_SETTINGS = 2;

// Variables en RAM /////////////////////////////////////////////////

char Version[]="1.2.2d\0";
char CharRcv=0;
char Command=0;

int i=0x00;
int uTimeUp=0;
int uTimeDown=0;
int nTintext=0;
int tUpC[NMUESTRAS];
long tUpT[NMUESTRAS];
long tUpI[NMUESTRAS];
int tDownC[NMUESTRAS];
long tDownT[NMUESTRAS];
long tDownI[NMUESTRAS];
long nTimer1Overflow;
int1 fedge1=0;
int1 fedge2=0;
int1 fedge3=0;
int1 flag_recibe_config1=0;
int1 flag_recibe_config2=0;
int1 flag_recibe_config3=0;

// Settings x CANAL /////////////////////////////////////////////////

int C1_Settings= 0;
int1 C1_Active = 0;
int1 C1_Raising = 0;
int1 C1_Falling = 0;
int1 C1_Trigger = 0;
int1 C1_Invert = 0;

int C2_Settings= 0;
int1 C2_Active = 0;
int1 C2_Raising = 0;
int1 C2_Falling = 0;
int1 C2_Trigger = 0;
int1 C2_Invert = 0;

int C3_Settings= 0;
int1 C3_Active = 0;
int1 C3_Raising = 0;
int1 C3_Falling = 0;
int1 C3_Trigger = 0;
int1 C3_Invert = 0;

// Definicion de funciones //////////////////////////////////////////

void menu_trans(void);
void friendly_eeprom_trans(void);
void friendly_firmware_trans(void);
void hardy_firmware_trans(void);
void friendly_data_trans(void);
void hardy_data_trans(void);
void friendly_config_trans(void);
void hardy_config_trans(void);
void on_reset(int1 verbose);
void ack_trans(void);
void set_channel1(void);
void set_channel2(void);
void set_channel3(void);
void config_channels(int1 verbose);

#int_rda
void rda_handler() {

  CharRcv=0;
  if(kbhit()){
    CharRcv=getc();
    if(CharRcv!=0){
      Command=CharRcv;
    }
  }
}

#int_ext
ext_handler() {

long t;
long n;

disable_interrupts(int_timer1);
disable_interrupts(int_ext1);
disable_interrupts(int_ext2);
++nTintext;
if(nTintext==1){
set_timer1(0);
nTimer1Overflow=0;
}
n=nTimer1Overflow;
t=get_timer1();

if(fedge1==0){
ext_int_edge(0,L_TO_H);
tDownI[uTimeDown]=n;
tDownT[uTimeDown]=t;
tDownC[uTimeDown]=1;
++uTimeDown;
}else
{
ext_int_edge(0,H_TO_L);
tUpI[uTimeUp]=n;
tUpT[uTimeUp]=t;
tUpC[uTimeUp]=1;
++uTimeUp;
}
++fedge1;
if(bit_test(C2_SETTINGS,7)==1){
enable_interrupts(int_ext1);
}
if(bit_test(C3_SETTINGS,7)==1){
enable_interrupts(int_ext2);
}
enable_interrupts(int_timer1);
}

#int_ext1
ext1_handler() {

long t;
long n;

disable_interrupts(int_timer1);
disable_interrupts(int_ext);
disable_interrupts(int_ext2);
++nTintext;
if(nTintext==1){
set_timer1(0);
nTimer1Overflow=0;
}
n=nTimer1Overflow;
t=get_timer1();

if(fedge2==0){
ext_int_edge(1,L_TO_H);
tDownI[uTimeDown]=n;
tDownT[uTimeDown]=t;
tDownC[uTimeDown]=2;
++uTimeDown;
}else
{
ext_int_edge(1,H_TO_L);
tUpI[uTimeUp]=n;
tUpT[uTimeUp]=t;
tUpC[uTimeUp]=2;
++uTimeUp;
}
++fedge2;
if(bit_test(C1_SETTINGS,7)==1){
enable_interrupts(int_ext);
}
if(bit_test(C3_SETTINGS,7)==1){
enable_interrupts(int_ext2);
}
enable_interrupts(int_timer1);
}

#int_ext2
ext2_handler() {

long t;
long n;

disable_interrupts(int_timer1);
disable_interrupts(int_ext);
disable_interrupts(int_ext1);
++nTintext;
if(nTintext==1){
set_timer1(0);
nTimer1Overflow=0;
}
n=nTimer1Overflow;
t=get_timer1();

if(fedge3==0){
ext_int_edge(2,L_TO_H);
tDownI[uTimeDown]=n;
tDownT[uTimeDown]=t;
tDownC[uTimeDown]=3;
++uTimeDown;
}else
{
ext_int_edge(2,H_TO_L);
tUpI[uTimeUp]=n;
tUpT[uTimeUp]=t;
tUpC[uTimeUp]=3;
++uTimeUp;
}
++fedge3;
if(bit_test(C1_SETTINGS,7)==1){
enable_interrupts(int_ext);
}
if(bit_test(C2_SETTINGS,7)==1){
enable_interrupts(int_ext1);
}
enable_interrupts(int_timer1);
}

#int_timer1
timer1_handler(){
++nTimer1Overflow;
}

// ON_RESET /////////////////////////////////////////////////////////

void on_reset(int1 verbose){

disable_interrupts(global);
disable_interrupts(int_timer1);
disable_interrupts(int_rda);
disable_interrupts(int_ext);
disable_interrupts(int_ext1);
disable_interrupts(int_ext2);

setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_psp(PSP_DISABLED);
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_0(RTCC_OFF);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
port_b_pullups(FALSE);
set_tris_b(0b00000111);

for(i=0;i<NMUESTRAS;i++){ tUpT[i]=0; tUpI[i]=0; tUpC[i]=0; tDownT[i]=0; tDownI[i]=0; tDownC[i]=0;}

nTintext=0;
uTimeUp=0;
uTimeDown=0;
flag_recibe_config1=0;
flag_recibe_config2=0;
flag_recibe_config3=0;

config_channels(verbose);

delay_ms(100);
// Habilito Canal 1
if(bit_test(C1_SETTINGS,7)==1){
enable_interrupts(int_ext);
if(verbose){ printf("\r\nint_ext enabled\r\n");}
}
// Habilito Canal 2
if(bit_test(C2_SETTINGS,7)==1){
enable_interrupts(int_ext1);
if(verbose){ printf("\r\nint_ext1 enabled\r\n");}
}
// Habilito Canal 3
if(bit_test(C3_SETTINGS,7)==1){
enable_interrupts(int_ext2);
if(verbose){ printf("\r\nint_ext2 enabled\r\n");}
}
// Habilito Recepción RS232
enable_interrupts(int_rda);

// Habilito Interrupciones Global
enable_interrupts(global);
}

// MAIN //////////////////////////////////////////////////////////////////

void main() {

on_reset(0);

do{

if(Command!=0){

// Accepta byte de configuracion para Channel 1
if(flag_recibe_config1==1){
set_channel1();
}
// Accepta byte de configuracion para Channel 2
if(flag_recibe_config2==1){
set_channel2();
}
// Accepta byte de configuracion para Channel 3
if(flag_recibe_config3==1){
set_channel3();
}

// Procesa cxommandos
switch(Command){

// Commands Telnet - SOFT COMMANDS ---------------------

case '?': menu_trans();
break;
case SOFT_COMMAND_RESET :
on_reset(1); // Reset
break;
case SOFT_COMMAND_FIRMWARE:
friendly_firmware_trans(); // Send Firmaware
break;
case SOFT_COMMAND_DATA :
friendly_data_trans(); // Send Data
break;
case SOFT_COMMAND_CONFIG :
friendly_config_trans(); // Send Config
break;
case SOFT_COMMAND_EEPROM :
friendly_eeprom_trans(); // Send EEPROM
break;

// Commands Soft PC - HARD COMMANDS ---------------------

case HARD_COMMAND_RESET :
on_reset(0); // Reset
ack_trans();
break;
case HARD_COMMAND_FIRMWARE:
hardy_firmware_trans(); // Send Firmaware
break;
case HARD_COMMAND_DATA :
hardy_data_trans(); // Send Data
break;
case HARD_COMMAND_CONFIG :
hardy_config_trans(); // Send Config
break;
case HARD_COMMAND_CONFIG1 : // Atento : siguiente recepción de Cfg Channel 1
flag_recibe_config1=1;
ack_trans();
break;
case HARD_COMMAND_CONFIG2 : // Atento : siguiente recepción de Cfg Channel 2
flag_recibe_config2=1;
ack_trans();
break;
case HARD_COMMAND_CONFIG3 : // Atento : siguiente recepción de Cfg Channel 3
flag_recibe_config3=1;
ack_trans();
break;
}
Command=0;
}

} while (TRUE);
}

// menu_trans ///////////////////////////////////////////////////////

void menu_trans(void){

friendly_firmware_trans();

printf("Telnet format:\r\n\n");
printf(" %c reset tables\r\n", SOFT_COMMAND_RESET);
printf(" %c version firmware\r\n", SOFT_COMMAND_FIRMWARE);
printf(" %c config transmit\r\n", SOFT_COMMAND_CONFIG);
printf(" %c data transmit\r\n", SOFT_COMMAND_DATA);
printf(" %c eeprom transmit\r\n", SOFT_COMMAND_EEPROM);
printf("\r\n");
printf("Hardware format:\r\n\n");
printf(" %c reset tables\r\n", HARD_COMMAND_RESET);
printf(" %c version firmware\r\n", HARD_COMMAND_FIRMWARE);
printf(" %c data transmit\r\n", HARD_COMMAND_DATA);
printf(" %c config transmit\r\n", HARD_COMMAND_CONFIG);
printf(" %cb config Channel1\r\n", HARD_COMMAND_CONFIG1);
printf(" %cb config Channel2\r\n", HARD_COMMAND_CONFIG2);
printf(" %cb config Channel3\r\n", HARD_COMMAND_CONFIG3);
printf("\r\n");

}

// Set Canal ////////////////////////////////////////////////////////

void set_channel1(void){

flag_recibe_config1=0;
C1_Settings=Command;
Command=0;
write_eeprom(DIR_C1_SETTINGS,C1_SETTINGS);
delay_ms(10);
ack_trans();
}

void set_channel2(void){

flag_recibe_config2=0;
C2_Settings=Command;
Command=0;
write_eeprom(DIR_C2_SETTINGS,C2_SETTINGS);
delay_ms(10);
ack_trans();
}

void set_channel3(void){

flag_recibe_config3=0;
C3_Settings=Command;
Command=0;
write_eeprom(DIR_C3_SETTINGS,C3_SETTINGS);
delay_ms(10);
ack_trans();
}

void config_channels(int1 verbose){

// Recupero configuracion desde la EEPROM
C1_SETTINGS = read_eeprom(DIR_C1_SETTINGS);
C2_SETTINGS = read_eeprom(DIR_C2_SETTINGS);
C3_SETTINGS = read_eeprom(DIR_C3_SETTINGS);
if(verbose){ printf("\r\Config 1=%u 2=%u 3=%u\r\n",C1_SETTINGS,C2_SETTINGS,C3_SETTINGS);}
// Configuro Channel1 Flanco inicial
if(bit_test(C1_SETTINGS,7)==1){
if(bit_test(C1_SETTINGS,5)==1){
fedge1=0;
ext_int_edge(0,H_TO_L);
if(verbose){ printf("\r\nint_ext 0 H_to_L\r\n");}
}
if(bit_test(C1_SETTINGS,6)==1){
fedge1=1;
ext_int_edge(0,L_TO_H);
if(verbose){ printf("\r\nint_ext 1 L_to_H\r\n");}
}
}
// Configuro Channel2 Flanco inicial
if(bit_test(C2_SETTINGS,7)==1){
if(bit_test(C2_SETTINGS,5)==1){
fedge2=0;
ext_int_edge(1,H_TO_L);
if(verbose){ printf("\r\nint_ext1 0 H_to_L\r\n");}
}
if(bit_test(C2_SETTINGS,6)==1){
fedge2=1;
ext_int_edge(1,L_TO_H);
if(verbose){ printf("\r\nint_ext1 1 L_to_H\r\n");}
}
}
// Configuro Channel3 Flanco inicial
if(bit_test(C3_SETTINGS,7)==1){
if(bit_test(C3_SETTINGS,5)==1){
fedge3=0;
ext_int_edge(2,H_TO_L);
if(verbose){ printf("\r\nint_ext2 0 H_to_L\r\n");}
}
if(bit_test(C3_SETTINGS,6)==1){
fedge3=1;
ext_int_edge(2,L_TO_H);
if(verbose){ printf("\r\nint_ext2 1 L_to_H\r\n");}
}
}
}

// ack_trans ////////////////////////////////////////////////////////

void ack_trans(void){

printf("%c\r\n",RESPONSE_ACK);
}

// eeprom_trans /////////////////////////////////////////////////////

void friendly_eeprom_trans(void){

int i,j,u;

printf("\r\n");
for(i=0;i<16;i++) printf("%X ",i);
printf("\r\n");
for(i=0;i<16;i++) printf("== ");
printf("\r\n");
j=0;
for(i=0;i<255;i++){
u=read_eeprom(i);
printf("%X ",u);
if(++j>15){
j=0;
printf("\r\n");
}
}
u=read_eeprom(255);
printf("%X ",u);
printf("\r\n\r\n");
}

// firmware_trans ///////////////////////////////////////////////////

void friendly_firmware_trans(void){

printf("\r\nLogical Analyzer v.%s by Redpic\r\n\n",Version);
}

void hardy_firmware_trans(void){

printf("{%s}\r\n",Version);
delay_ms(10);
ack_trans();
}

// data_trans ///////////////////////////////////////////////////////

void friendly_data_trans(void){

disable_interrupts(int_timer1);

printf("\r\nResults Table:\r\n\n");

printf("Total INT_EXT detected %2u\r\n",nTintext);

printf("\r\nFalling edges Table\r\n\n");
printf("Nº C Overflows Timer\r\n");
printf("=======================\r\n");
for(i=0;i<NMUESTRAS;i++){
printf("%2u %1u %5lu %5lu\r\n",i,tDownC[i],tDownI[i],tDownT[i]);
}
printf("\r\n\nRising edges Table\r\n\n");
printf("Nº C Overflows Timer\r\n");
printf("=======================\r\n");
for(i=0;i<NMUESTRAS;i++){
printf("%2u %1u %5lu %5lu\r\n",i,tUpC[i],tUpI[i],tUpT[i]);
}
}

void hardy_data_trans(void){

disable_interrupts(int_timer1);

for(i=0;i<NMUESTRAS;i++){
printf("{ %3u %1u %5lu %5lu %1u %5lu %5lu }\r\n",i+1,tUpC[i],tUpI[i],tUpT[i],tDownC[i],tDownI[i],tDownT[i]);
}
delay_ms(10);
ack_trans();
}

// config_trans /////////////////////////////////////////////////////

void friendly_config_trans(void){

disable_interrupts(int_timer1);

printf("\r\nConfig Channels :\r\n\n");

printf("Channel 1 = %2u\r\n\n",C1_Settings);
printf("Channel 2 = %2u\r\n\n",C2_Settings);
printf("Channel 3 = %2u\r\n\n",C3_Settings);
}

void hardy_config_trans(void){

disable_interrupts(int_timer1);

printf("{ %3u %3u %3u }\r\n",C1_Settings,C2_Settings,C3_Settings);
delay_ms(10);
ack_trans();
}
///////////////////////////////////////////////////////////////////////////////////////////////////

 
 
 

 

 

 

 

Esta página se modificó el 27/12/2008


Esta página usa la letra Ñ

Nota pública importante sobre las consultas al Webmaster de PicManía.


Sugerencias a Picmanía... (que serán leídas pero seguramente no podrán ser contestadas)

Esta página pertenece al grupo de páginas de Diego RedRaven

 

 



Nota: Esta página Web esta repleta de imágenes, textos, logotipos y demás material extraídos de los mas variados medios de los que no soy ni autor ni depositario de los correspondientes derechos de autor, uso y/o reproducción. Si Ud. es depositario de dichos derechos y desea que el material correspondiente sea eliminado de esta Web no dude en ponerse en contacto conmigo mediante e-mail y será inmediatamente retirado. Gracias.
 
Visitas
Totales : 13774 Hoy: 5 Activas: 1 Vistas: 13774

Esta página fue modificada el 07-08-2010 22:41:25

           
 DmSoft WAMP Escribir Unreal