PicManía by RedRaven
 

Búsqueda personalizada

 

PROYECTOS : Analizador Lógico (Histórico)

 

EN CONSTRUCCIÓN

 

Histórico del proyecto Analizador Lógico de 3 canales con un PIC 18F4550

05 de Abril de 2006, 08:40:54
 
Analizador lógico de 4 Canales (Simple) con monitorización/edición en PC

Esto que os escribo es más una declaración de intenciones que un avance de proyecto. Pero en fin, tengo la necesidad de compartirlo con todos ustedes.

Primero explico la necesidad.

Tanto para mi anterior proyecto, el Teclado PS/2 para el PIC, como para otros que tengo en mente, como la lectura conexión de dispositivos con transmisión síncrona con protocolos OMROM y Wiegand26 (lectores de tarjetas magnéticas, de proximidad, chip y Mifare ...) o los asuntos de lecturas de dispositivos IR (infrarrojos como los que ha usado M. Nocturno en su proyecto del Dimmer con Mando), el tema de poder analizar una trama me fascina, me subyuga y me trae por la vía de la amargura.

Segundo la disponibilidad.

He visto montajes muy sencillos para poder monitorizar ocho señales distintas por medio del puerto paralelo del PC, con programas hechos en C++ para DOS incluso con fuentes, pero para los que usamos S.O. con núcleo Windows/NT la cosa se nos complica un poco/mucho. El NT no permite el acceso tan directo al puerto paralelo como es necesario para medir tiempos de uS simultáneamente en ocho pines ....

Los que hay para ventana Windows deben llevar además un programa/driver ... total que no. Por otro lado hay verdaderas virguerías tanto comerciales como otros proyectos en curso por parte de Picmaníacos. Imagino que lo que está montando M. Nocturno con su Scope y Labview es una cosa de verdad y de una vez.

Yo quizás no aspire a tanto.

Tercero mis intenciones.

Por mas vueltas que le doy yo solo soy capaz de encontrar que necesito analizar tres señales ... así que la voy a hacer de cuatro por si acaso y así me curo en salud.

Lo que deseo es ver en la pantalla de mi PC es el cronograma de cuatro señales simultáneas (mas o menos) con periodos desde unas decenas de uS hasta algunos milisegundos, digamos que ... hummm ... el pulso mas corto sea de 25 uS y el más largo de 25 mS; durante un lapso máximo de tiempo de muestreo de dos o tres segundos (o incluso menos).

No creo necesitar mucho mas que esto. Para ello me gustaría usar un PIC 18F4550 (de ahí lo que comentaba en otro hilo sobre el tener que acabar lo de la RRBOARD2 ya que ésta es para 16F877/18F4550)

Este PIC tiene 3 interrupciones externas, RB0, RB1 y RB2 y un módulo CCP con lo que cuatro señales pueden "digerirse" razonablemente bien. Tiene además amplio espacio para programas y 2 Kbytes completos de RAM que pueden darme juego para el muestreo.

Intento realizar un buffer cíclico, como la pescadilla que se muerde la cola, con el máximo de RAM que pueda, y los datos recopilados enviarlos tan rápido como pueda al PC vía RS232, o mejor aún vía USB 2.0 de tal forma que vaya vaciando el buffer de muestreo a la mayor prontitud posible, con el fin de liberar memoria RAM para seguir muestreando ....

El PC se encargaría de almacenar los datos y representarlos gráficamente. Con medidor de tiempos, lupa, marcha adelante y atrás, sincronismos ... y todas las herramientas de análisis que se me ocurran.

He pensado ponerle al PIC distintas formas de disparo (trigger) pudiendo elegir una de las líneas, o por el contrario generando él un pulso de reloj de disparo, o que espere a la primer interrupción en una de las líneas para empezar a samplear ... o .... mil maneras de hacerlo.

Quiero también poder decirle que tal o cual señal la tome de forma directa o invertida, con o sin pull-up o pull-down, fundamental para un montón tipos de señales que lo necesitan.

Y para ampliaciones poner ponerle adaptadores de niveles de tensión o amplificaciones ....

En fin, es tan fácil y barato soñar. 8)
 


 

06 de Abril de 2006, 10:42:13
 
En primer lugar me gustaría definir dos métodos de sampleo:

a.- Periódico ajustable. Se determinan los Canales activos y se le envía al PIC un valor para la frecuencia de sampleo. Cada vez que se cumple el periodo se testean los Canales activos y se guardan los valores de estado y el tiempo transcurrido (número de periodos consumidos). No se usan las interrupciones.

b.- Por cambio de estado. Se programan los flancos a detectar (de subida, de bajada, o ambos) Cada vez que se produce un evento del tipo programado se guarda el estado al que llega y el tiempo transcurrido desde el inicio. Se usan las interrupciones.

Ahora en segundo lugar quiero pensar sobre el método de disparo del inicio del sampleo (ya veremos mas tarde el método para guardar y transmitir los datos sampleados).

He pensado en poder elegir entre:

a.- Inicio retardado programable. Desde el PC de control se le envía el retardo para iniciar el sampleo, el PIC realiza una cuenta atrás monitorizándolo mediante el Soft del PC y al llegar a 0 comienza el sampleo, empezando a guardar valores leídos.

b.- Inicio de sampleo al recibir una interrupción en un Canal predefinido, de los 3 disponibles con INT EXT, a partir de esta señal se guardan los valores leídos.

c.- Inicio de sampleo al recibir una interrupción en cualquiera de los Canales activos, a partir de cualquiera de estas señales se guardan los valores leídos.

Cualquiera de los metodos b y c puede configurarse para empezar el sampleo a partir de la n-ava interrupción recibida.

Y por último los métodos para finalizar el sampleo:

a.- Final retardado programable. Desde el PC de control se le envía el retardo para finalizar el sampleo, el PIC deja de samplear al consumirse el tiempo programado.

b.- Tiempo máximo sin cambio de señal en un Canal activo predefinido. Se le envía al PIC un periodo en el cual si no cambia el estado de un Canal determinado cesa el guardar valores y da por finalizado el sampleo.

c.- Tiempo máximo sin cambio de señal en cualquier Canal activo. Se le envía al PIC un periodo en el cual si no cambia el estado de ningún Canal activo cesa el guardar valores y da por finalizado el sampleo.
 
15 de Abril de 2006, 02:33:26
 
Continuamos avanzando ....

Como nunca había trabajado con ningún PIC de la serie 18F estoy intentando quemar etapas una a una y no querer saltar directamente del punto de salida hasta la meta, por que si así lo hiciese solo estaría abocado a darme una soberana torta con cualquier problemilla que me encuentre por el camino. Así que ....

1º He adaptado, programado y probado el universal wink.c (parpadeo de un led). Todo Ok.

2º He adaptado, programado y probado el no menos universal echo.c (Eco mediante la RS232). Todo Ok.

3º He adaptado, programado y probado mi propio test para la Interrupción Externa por RB0. Todo Ok.

y 4º He jugado con este último programa para empezar a probar cómo detectar un único tren de pulsos por esta misma RB0.

La entrada que utilizo tiene conectada una pull-up externa por lo que inicialmente configuro la interrupción externa para detectar el flanco de bajada.

Cuando aparece el primer flanco inicializo a 0 el Timer_1 y habilito la interrupción por desbordamiento de este mismo Timer_1.

Cada vez que me llega un flanco conmuto al flanco contrario la configuración de la interrupción para detectar convenientemente cada flanco que me llegue.

Cada vez que me llega un flanco guardo el valor del Timer_1 en ese momento y el número de veces que se ha desbordado dicho Timer 1.

Si el flanco es de subida lo guardo en la tabla de Flancos de Subida, si el flanco es de bajada lo guardo en la tabla de Flancos de Bajada.

Si le envío por la RS232 cualquier carácter me vuelca en la misma el contenido de ambas tablas ....

Como puede verse en la imagen que os muestro a cada entrada de una tabla corresponde una en la otra tabla, con lo que tengo perfectamente definido el pulso. Como sé cuanto dura cada interrupción por desbordamiento, y cada incremento del Timer tengo perfectamente delimitado tanto la duración de cada pulso como la separación entre ellos ...
 


 

15 de Abril de 2006, 08:05:44
 
Bueno, como veo que tengo la detección del Canal 0 mas o menos controlada le he implementado ya unas funciones de transmisión de las tablas de valores "formateada" para poder recibirla desde el PC ...

Me lanzo ahora a continuar con el programa EXE del PC para ver si detecto y muestro la primera señal en la pantalla ....
 


 

16 de Abril de 2006, 01:48:30
 
Continuamos avanzando ...

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

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

1.- Comandos destinados a volcar información a un Monitor RS232 (me ha dado la idea Radon con su comentario de un par de post mas abajo) 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 lanzarme a la siguiente fase del proyecto: ¡¡¡ Dibujarlos !!!

Como podéis comprobar en ambos casos los datos son exactamente los mismos ....

Os tendré al tanto de los nuevos avances ...
 


 


 

16 de Abril de 2006, 10:24:13
 
Un solo detalle que creo que no he puesto aún en todo este desarrollo que llevamos visto.

Es la base de tiempos que estamos utilizando, y a los que se refieren las tablas de datos capturados por el PIC, que pueden verse en la imagen del post anterior.

Si os fijáis además de la columna de orden de detección hay otras dos que nos indican respectivamente el Número de Overflows completos que se han producido en el TIMER1 y el valor del Timer en el momento de producirse la interrupción.

Como las señales utilizadas en el ejemplo de dicha imagen están invertidas, esto es: que primero se produce la interrupción por flanco de bajada y después viene la de subida, la primera línea de datos a tener en cuenta es precisamente la numero 0 de la tabla de Falling Edges, seguida de la número 0 de la de Rising Edges, a continuación se produce la numero 1 de la de Falling Edges y después la 1 de la otra tabla ... y así hasta las números 9 de ambas que definen el último pulso detectado.

Todos estos números estan expresados en Overflows y Ticks del Timer1, que a su vez está configurado con:

setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);

Por lo que va exactamente a "toda pastilla" y esto significa que se incrementa, un Tick cada (FOSC/4).

Como el Cristal generador del Clock es de 20 Mhz tenemos un Ciclo de instrucción de 1/2000000*4=0.0000002 segundos
o lo que es lo mismo 0.2 uS (microsegundos) por Tick, valor por el que tenemos que multiplicar la columna Timer para expresarla en Tiempos.

Como el TIMER1 es un contador de 16 Bits, de 0 a 65535, cada desbordamiento se produce cada 65536 Ticks, o sea cada 0.2 uS * 65536 = 13107,2 uS, o lo que es lo mismo cada 13.1072 mS (milisegundos), valor por el que tenemos que multiplicar la columna Overflows para expresarla en Tiempos.

Así, desde el inicio del muestreo. se puede calcular cada flanco de subida o bajada con:

X (en uS) = 13107,2 * Overflow + 0.2 uS * Timer

y esta X es la muestra que hay que representar gráficamente, desplazando la correspondiente línea vertical del flanco, tras transformarla para adecuarla la escala de tiempos, establecida para cada división de la regla de medida (dibujada con pequeños puntos blancos sobre la imagen y que puede ser ajustada mediante Escala (t))

Continuamos para bingo

Os mantendré informados
 

16 de Abril de 2006, 10:57:18
 

Otra pequeña reflexión técnica antes de dar por finalizada la jornada Picmaníaca de hoy ...

Fijaos que en todos los ejemplos que he posteado hasta ahora (podéis ver las imágenes de los Monitores Siow que he pegado en los distintos mensajes) siempre la primera interrupción se produce a los 21 Ticks del TIMER1, los siguientes son cada uno de su padre y de su madre ...

Y me he preguntado ¿por qué es esto así?

La respuesta es fácil y tiene que ver por la forma en que he programado en el PIC la ext_handler() o rutina de manejo de la interrupción externa.

Con el fin de tener siempre unos valores coherentes desde un valor conocido del estado del TIMER1, y no dejar a éste correr alocadamente desde que el PIC se resetea, he implementado un trozo de código que es el causante de que esta primer interrupción llegue siempre con el mismo "retraso" y se registre con ese valor ....

Mi idea es cuando se produzca la primer interrupción, y solo en la primera interrupción, pongo el TIMER1 a 0 y habilito la interrupción por desbordamiento de dicho timer. Así todas las muestras parten exactamente del mismo tiempo de referencia. Esté como esté el TIMER1 al llegar la primera interrupción éste es inicializado y así todas las interrupciones posteriores serán expresadas como distancias, en tiempo, que las separa de la primera que se ha producido.

La rutina completa es:
 



#int_ext
ext_handler() {

  if(nTintext==0){
    set_timer1(0);
    nTimer1Overflow=0;
    enable_interrupts(int_timer1);
  }

  ++nTintext;

  switch(fedge){

    case 0: TimesDown[uTimeDown][0]=get_timer1();
            TimesDown[uTimeDown][1]=nTimer1Overflow;
            ++uTimeDown;
            fedge=1;
            ext_int_edge(0,L_TO_H);
            break;

    case 1: TimesUp[uTimeUp][0]=get_timer1();
            TimesUp[uTimeUp][1]=nTimer1Overflow;
            ++uTimeUp;
            fedge=0;
            ext_int_edge(0,H_TO_L);
            break;
  }
}
 

Luego los famosos 21 Ticks de TIMER1, que me muestra como valor recogido para la primera interrupción, son exactamente lo que el PIC necesita para procesar , recordad que sólo en la primera interrupción detectada, desde el código if(nTintext==0) hasta el registro del valor en TimesDown[uTimeDown][0]=get_timer1();

Calcularé en tiempos tanto este valor para la primera interrupción, como el salto de ese mismo if(nTintext==0) para las ulteriores interrupciones, con el fin de corregir las tablas de tiempos recogidas, y que se ajusten así mas a la realidad de lo que está ocurriendo en esos pines de Dios.

Os mantendré informados
 
17 de Abril de 2006, 10:38:51
 
Sin palabras ...
 


 

18 de Abril de 2006, 08:55:42
 

Otro palito a la burra ....

He realizado un nuevo muestreo (realizado con un simple botón rebotando ...)
Lo cargo con el Soft del PC y lo dibujo (como en las pruebas anteriores )
Tal como puede comprobarse en la imagen que acompaño la primera interrupción llega hasta los valores:
9 Overflows de Timer1 + 37752 Ticks de Timer 1
con lo que aplicando la formula correspondiente de
X (en uS) = 13107,2 * Overflow + 0.2 uS * Timer
Nos dá un valor del flanco de subida de X (en uS) = 13107,2 * 9 + 0.2 uS * 37752 = 125511 uS tras comenzar el muestreo.
O sea 125,511 milisegundos.
He añadido este cálculo a la ventana de Valores.
He seleccionado en la Escala de Tiempos el valor de 50 ms por división (raya grande en la regla)
He realizado los correspondientes cálculos para encontrar cuantos microsegundos le corresponden a cada píxel.
Y he añadido el cálculo inverso para que al mover el ratón sobre el gráfico me indique a qué valor de tiempo corresponde.

Ea, el Analizador lógico de 3 Canales (simple) ya mide en tiempos sobre la pantalla
 


 

23 de Abril de 2006, 02:56:04
 
No, no creáis que este proyecto está durmiendo el sueño de los justos, nada de eso ...

Estoy solucionando algunos asuntos muy importantes antes de acometer nuevas fases.

En concreto estoy liado con la representación gráfica (en detalle) de la señal escaneada. En post anteriores pudisteis ver cómo se podía ya medir en pantalla con solo mover el puntero del ratón ... pero había un pequeño fallo, o mejor dicho una importante carestía, y era que cuando cambiaba la base de tiempos, con el "t / div" y la ponía muy corta o lo que es lo mismo que ampliaba la escala de representación, se me salía el gráfico del área de dibujo por la derecha.

Natural, si tengo un testeo que dura 200 ms y estoy representándolo a una escala que hace que en pantalla solo aparezcan, digamos que por ejemplo unos 100 ms, la señal no cabe y ... pues no se ve.

Ahora ya si se ve.

Lo que he hecho es añadir tantos bloques del tamaño de una "t/div" como me hagan falta a la imagen, y ésta montarla sobre un Scrollbox para que con las barras de desplazamiento pueda ver cualquier porción de ella.

Y funciona de maravilla ....

En el ejemplo que podéis ver a continuación muestro una ampliación a lo bestia de una imagen hasta ser capaz de visualizar un micropulso de 37 microsegundos, muestreado entre otros del orden de más de una centena de milisegundos, de hecho es un rebote del botón pulsador en el momento de soltar el pulsador y cerrarse éste ...

... una gozada :
 


 

28 de Abril de 2006, 11:37:36
 
Continuamos avanzando, muy poco a poco, pero avanzando al fin y al cabo ...

Le he añadido un par de detalles, una pantalla de Log para ir enviando mensajes y un sistema de medida sobre la representación gráfica.

Con esto doy por concluido el asunto de la representación gráfica. Hace lo que quería que hiciese así que se acabó lo que se daba ...
 


 

30 de Abril de 2006, 22:36:17

¡¡¡ Necesito de vuestra capacidad de análisis !!!

Os ruego que pongáis vuestros cerebros a destilar jugo de neuronas y me echéis una mano sobre un efecto que me está desquiciando los nervios, y no le veo el por qué por ninguna parte ... no sé si es que estoy mas obtuso de lo normal o es que he alcanzado mi nivel de incompetencia, y en él me mantengo. Estoy atascado

Voy a intentar explicaros lo mas claramente posible el problema a ver si podéis arrojar luz sobre lo que está pasando:

Descripción del problema: Como sabéis, la sonda lógica detecta un tren de pulsos, guardando y transmitiendo posteriormente los tiempos en que ocurren los distintos y alternados flancos de subida y bajada. Esto lo hace perfectamente el 90% de las veces, pero hay un 10% de error, de muestreos en que se solapan dos pulsos consecutivos .... ante la imposibilidad física de que me lleguen dos flancos del mismo tipo sin pasar antes por un flanco contrario imagino que el problema estriba en la forma de detectarlo y/o guardar los valores de tiempo correspondientes, pero no veo dónde está el error ....

Elementos que intervienen:

1º.- El hardware que genera el pulso a detectar es un simple pulsador, conectado al PIN B0 mediante una resistencia Pull-Up que tira a masa cuando es pulsado. Por ello los pulsos son inversos, flanco de bajada -> flanco de subida, tantas veces como pulsaciones-rebotes se produzcan.

2º.- La Interrupción Externa en el PIC está configurada al Reset para detectar primero un flanco de bajada.

3º.- Al llegar la primera interrupción, y solo en esa primera interrupción, se pone a 0 el valor del Timer1 y se habilita la Interrupción por Desbordamiento del Timer1.

4º.- Al aparecer una Interrupción Externa se conmuta el flanco para detectar el opuesto que configura un pulso completo.

5º.- Cada flanco detectado se guarda en una tabla con dos valores: El valor en ese instante del Timer1 y el número de veces que dicho Timer1 se ha desbordado.

6º.- Al recibir el PIC cierto comando via RS232 envía al PC las tablas de datos recogidos ...

El código concreto que realiza la detección de pulsos (y que sospecho es el responsable del problema) es exactamente este:
 
1º.- En Reset
 
void On_reset(void){

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

  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);

  for(i=0;i<NMUESTRAS;i++){ TimesUpT[i]=0; TimesUpI[i]=0;}
  for(i=0;i<NMUESTRAS;i++){ TimesDownT[i]=0; TimesDownI[i]=0;}

  nTintext=0;
  uTimeUp=0;
  uTimeDown=0;

  ext_int_edge(0,H_TO_L);
  fedge=0;

  delay_ms(100);

  enable_interrupts(int_rda);
  enable_interrupts(int_ext);
  enable_interrupts(global);

  set_timer0(0);
}
 
2º.- En tratamiento de interrupciones :
 
#int_ext
ext_handler() {

  long t;
  long n;

  ++nTintext;
  if(nTintext==1){
    set_timer1(0);
    nTimer1Overflow=0;
    enable_interrupts(int_timer1);
  }
  n=nTimer1Overflow;
  t=get_timer1();
  if(fedge==0){
    ext_int_edge(0,L_TO_H);
    TimesDownI[uTimeDown]=n;
    TimesDownT[uTimeDown]=t;
    ++uTimeDown;
  }
  else
  {
    ext_int_edge(0,H_TO_L);
    TimesUpI[uTimeUp]=n;
    TimesUpT[uTimeUp]=t;
    ++uTimeUp;
  }
  ++fedge;
}

#int_timer1
timer1_handler(){
  ++nTimer1Overflow;
}
 
Este soft en el PIC funciona correctamente, como ya os he dicho el 90% de las veces, lamentablemente el restante 10% hace "cosas raras" tal como podéis ver en la imagen inferior, y estimo que un 10% de error es excesivo y tengo que corregirlo antes de continuar con este proyecto.
 

Fijaos que los pulsos van sucediéndose de forma correcta uno tras otro, primero los flancos de bajada después los de subida. Cada uno de ellos mas "lejos" del inicio, 0 Interrupciones + 0 Tick's, conforme van llegando ... Por ejemplo el pulso número 04 comienza en el desbordamiento 30 y con el Timer1 a 412 ticks y se acaba en el mismo desbordamiento 30 pero con el Timer1 a 681 por lo que dura 54 uS, y el siguiente pulso, el número 5, comienza también en el desbordamiento 30 pero con el Timer1 a 813 ticks, por lo que comienza exactamente 132 ticks de Timer1 mas tarde, o sea 26,4 uS después; y acaba en el desbordamiento 33 con Timer1 a 7271 ... Todo correcto ....

Pero los pulsos 06 y 07 se solapan .... el 06 va desde los valores de desbordamiento y timer 43/687 hasta los 43/30923 y el 07 va desde los valores 43/1055 hasta los 46/15067 ¡¡¡ Mal !!!

Según estos datos el pulso 07 ha llegado antes de que termine el 06 ¡¡¡ Mal !!!

Parece como si realmente los datos estuviesen intercambiados y el fin del pulso 06 fuese realmente el comienzo del 07 y simétricamente como si el inicio del 07 fuese realmente el final del 06 ¿¿¿¿¿ ??????

Y por mas vueltas que le doy al código no encuentro el por qué ocurre esto ....

¿Se os ocurre algo? ¿tenéis piedad de un pobre programador desesperado? ¿eh?
02 de Mayo de 2006, 19:22:50
 
Bicheando por el Foro he dado con esto del maestro, y sin embargo amigo, J1M : Módulo USB del 18Fx550 usado para sus inventos USBianos ...
 
...
Para vuestro caso que es de 4Mhz tendríais:

#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN
#use delay(clock=48000000)
...
 
Me he ido a la página 32 del Datasheet del 18F4550 y ....
 


Entonces la pregunta sería ... ¿me sirve esto para poner mi 4550 a tó lo que dé? ....

Si me ayudáis a encontrar los fuses correctos ... ¿podemos hacer andar el 4550 a 48Mhz con mi cristal de 20Mhz?

¿Es a esto a lo que se refería el maestro Sisco?
 
06 de Mayo de 2006, 14:35:33
 
Teoría y práctica para la implementación de un protocolo cutre, chapucero y venido a menos, entre un Pic 18F4550, programado en CSS C, sobre tarjeta de desarrollo Edumic con un cristal de 20MHZ y un PC AMD Semprom +2600 con 1 GByte de RAM, dotado operativamente de Windows XP Professional Service Pack II, sobre el que se ejecuta un programa aplicativo desarrollado en Borland Delphi 6.0 Enterprise Update Pack 2, mediante el VCL ApdComPort de la librería TpaPro (TurboPower Async Professional Package en Sourceforgue.net) mediante interface RS-232-C estándar en ambos extremos.
 
ja, ja, ja ... con el título sólo mas de uno se hace una tesis doctoral .... ja, ja, ja
 
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 configuracion y recibe settings de los tres canales

Transmit: 1 Receive: ^[13][10] Envia "preparate para recibir configuracion canal 1" recibe ACK

Transmit: [177] Receive: ^[13][10] Envia "configuracion canal 1" recibe ACK

Transmit: 2 Receive: ^[13][10] Envia "preparate para recibir configuracion canal 2" recibe ACK

Transmit: [177] Receive: ^[13][10] Envia "configuracion canal 2" recibe ACK

Transmit: 3 Receive: ^[13][10] Envia "preparate para recibir configuracion canal 2" recibe ACK

Transmit: [177] Receive: ^[13][10] Envia "configuracion canal 3" recibe ACK

Transmit: R Receive: ^[13][10] Envia "reseteate, limpia muestreos anteriores y reconfigurate" recibe ACK

Transmit: C Receive: { 177 177 177 }[13][10]^[13][10] Envia "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 en el post 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.
 
7 de Mayo de 2006 01:10:59

Lo prometido es deuda. Aquí está el final de este proyecto.

¡¡¡ Que suenen las trompetas !!!! ¡¡¡¡ Que repiquen las campanas !!!!

Una imagen vale mas que mil palabras
 

Le he conectado un Lector de Tarjetas de Proximidad marca Ápice utilizando el protocolo OMROM C&D; cuya transmisión de datos la efectúa con tres señales, Clock (CK), Data (DT) y Card Present (CP).

Ésta última señal de CP se activa antes de comenzar la transmisión y se desactiva la última tras haber concluído con la misma.

La señal de reloj CK es una serie de pulsos síncronos con un periodo de 500 uS y un Duty Cicle del 50%.

Cada señal de CK muestra el valor de un bit de Datos en DT.

La transmisión de datos se inicia y se finaliza con 8 bits "cero".

La transmisión de los datos relativos al código grabado en la tarjeta se compone de tantos grupos de 4 bits (nibble LSB) mas paridad par como dígitos tenga éste. En el caso concreto de esta trasmisión monitorizada por la Sonda Lógica es el número 79127.

He utilizado este ejemplo en concreto porque profesionalmente soy el padre del firmware del lector que realiza la transmisión, y por lo tanto conozco perfectamente el tipo de señales que iba a recibir en la sonda, con lo que el evaluar si funciona correctamente era mucho mas fácil. A esto le he llamado la "fase de calibración" cuyos resultados podéis ver en la imagen anterior.

Buenoooooo .... sé que a este proyecto se le pueden (y deben) hacer docenas de ampliaciones y mejoras. Algunas ya las tengo claras como por ejemplo la de colocarle un delay ajustable antes de comenzar a samplear, es fundamental para señales que tienen un periodo de latencia alto y de la que queremos investigar partes mas avanzadas de las que la sonda tiene posibilidad de rastrear, también se debería poder ajustar que el sampleado comience a partir de un número determinado de interrupciones recibidas por un canal en concreto. también ....

Pero por ahora se va a quedar así. Hay otros proyectos que esperan que les meta mano y ... hay que seguir avanzando, hasta llegar allí donde nunca antes nadie ha estado.

Os mantendré informados.
 

 

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 : 9019 Hoy: 2 Activas: 1 Vistas: 9019

Esta página fue modificada el 07-08-2010 15:42:20

           
 DmSoft WAMP Escribir Unreal