Autor Tema: ¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)  (Leído 4860 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado jkcobain

  • PIC10
  • *
  • Mensajes: 18
¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« en: 03 de Diciembre de 2016, 02:29:58 »
Hola a todos.

Estoy trabajando en un proyecto, en el que pretendo establecer comunicación entre un PIC y un monedero (MDB). He hecho algunos avances, pero ahora me quedé trabado, porque no sé cómo almacenar y usar la cadena de datos que me envía como respuesta el monedero. Les doy un ejemplo:

Digamos que el PIC solicita el estatus del monedero mediante un hexadecimal (cualquiera que este sea), entonces el monedero responderá con uno o más bytes de datos mas un byte "check", por poner un ejemplo, la respuesta será: 0x013 0x00B 0x11E (el byte "check" siempre lleva el 9no bit puesto). Mi duda es: ¿cómo guardo eso que me llega, y cómo lo visualizo posteriormente?. Tengo una interrupción en la que puedo ver el byte que llega, pero solo cuando es un sólo byte, y en esta aplicación llegan varios bytes seguidos, por lo tanto no sé cómo analizarlos.

Estoy acostumbrado a las cadenas ("strings"), en C# y vb, pero en CCS no sé cómo manipular esos datos, y más aun, siendo datos de 9 bits y aparte datos que no corresponden al código ascii, por ejemplo.

Espero haberme explicado bien, de no ser así, por favor háganmelo saber.

¡Muchas gracias a todos de antemano!

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #1 en: 03 de Diciembre de 2016, 03:21:34 »
.

No se entiende muy bien lo que quieres hacer.

Si te llegan varios bytes, ve guardándolos en una matriz, y pon un breakpoint en una sesión de debug para ver el contenido de la matriz cuando hayas recibido el bloque completo de datos.

Lo que dices del byte "check", no tiene sentido, un byte son 8 bits, por lo tanto no puede haber un noveno bit en ese byte. Tampoco se entiende lo de los datos de 9 bits, con un byte tienes 255 opciones, y todos están en la tabla de códigos ASCII.

No existen bytes de 9 bits, por definición un byte son SIEMPRE 8 bits.

« Última modificación: 03 de Diciembre de 2016, 03:25:01 por planeta9999 »

Desconectado manwenwe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2211
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #2 en: 03 de Diciembre de 2016, 08:24:14 »
No tengo mucha idea de CCS (de hecho no me gusta nada) pero me da a mí que el problema no es de programación sino de configuración del PIC. ¿Qué PIC utilizas?, Doy por hecho que uno de 8bit(PIC16,PIC18,etc). Si trabajas con 9bit tiene que haber un bit de configuración para esto, la interrupción de la que hablas y dos registros para enviar (1+8) y dos para recibir(1+8). Mirate la documentación del PIC y busca cuales son esos registros.

Por eso no me gusta CCS, me parece como programar Arduino: todo lleno de funciones pre-compiladas que se supone que son mágicas y lo hacen todo por ellas solas.... luego cuando surge un problema llega la histeria!. Nunca entenderé que la gente utilice microcontroladores sin querer entender lo que hay dentro de ellos (no digo que sea tu caso jkcobain): para eso mejor comprar una placa con linux de 20$....

Saludos!
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #3 en: 03 de Diciembre de 2016, 10:53:50 »
Bueno como te dijeron no se exactamente como se puede obtener el 9no bit en CCS con alguna funcion, mas que definir el bit y listo es decir usar la directiva #BIT.

El principal problema es ... si es necesario guardar ese bit.. Tal ves ese bit solo sirva para dar paridad. Si es asi CCS ya te lo realiza de por si solo, cuando en la directiva seleccionas PARITY=E o PARITY=O..

¿Como almacenarlo?

Si es una paridad no hace falta, ya que se controla antes y si la paridad no es correcta simplemente se descartaria el dato ( todo por software obviamente ).
Si es otra cosa ese 9no bit entonces deberias tener al menos una variable de 16bits o en su defecto una estructura de 8bits + 1 bit. Luego haces un array de esa estructura.
Rogando que eso no ocupe lo mismo que los 16bits, sino seria complicarla sin sentido.

Pero estoy mas que seguro que ese CHECK tiene que ser algo de paridad, revisa el protocolo bien.

Desconectado jkcobain

  • PIC10
  • *
  • Mensajes: 18
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #4 en: 03 de Diciembre de 2016, 14:28:35 »
.

No se entiende muy bien lo que quieres hacer.

Si te llegan varios bytes, ve guardándolos en una matriz, y pon un breakpoint en una sesión de debug para ver el contenido de la matriz cuando hayas recibido el bloque completo de datos.

Lo que dices del byte "check", no tiene sentido, un byte son 8 bits, por lo tanto no puede haber un noveno bit en ese byte. Tampoco se entiende lo de los datos de 9 bits, con un byte tienes 255 opciones, y todos están en la tabla de códigos ASCII.

No existen bytes de 9 bits, por definición un byte son SIEMPRE 8 bits.

Había pensado lo de la matriz, lo que no sé es cómo "visualizarlos" una vez guardados, ya que algunos no son fáciles de identificar, es decir: puede ser un NULL un ACK, etcétera, no es como encontrarme con un "a" o un "f". Otra cosa es que no sé cómo saber cuando ya recibí el último dato (lo llamaré dato, no bit, debido a lo que dices de los bytes), ya que la cantidad de datos es indefinida, la manera de saber si fue el último, es cuando el 9no bit está en 1, pero regreso al problema anterior, que no sé cómo visualizar los datos que me llegan.

Explicaré un poco lo de los 9 bits en un momento, en una respuesta general.

¡Gracias!

Desconectado jkcobain

  • PIC10
  • *
  • Mensajes: 18
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #5 en: 03 de Diciembre de 2016, 14:37:33 »
No tengo mucha idea de CCS (de hecho no me gusta nada) pero me da a mí que el problema no es de programación sino de configuración del PIC. ¿Qué PIC utilizas?, Doy por hecho que uno de 8bit(PIC16,PIC18,etc). Si trabajas con 9bit tiene que haber un bit de configuración para esto, la interrupción de la que hablas y dos registros para enviar (1+8) y dos para recibir(1+8). Mirate la documentación del PIC y busca cuales son esos registros.

Por eso no me gusta CCS, me parece como programar Arduino: todo lleno de funciones pre-compiladas que se supone que son mágicas y lo hacen todo por ellas solas.... luego cuando surge un problema llega la histeria!. Nunca entenderé que la gente utilice microcontroladores sin querer entender lo que hay dentro de ellos (no digo que sea tu caso jkcobain): para eso mejor comprar una placa con linux de 20$....

Saludos!

Así es, uso uno de 8 bits, un PIC16. Los 9 bits se trabajan con el registro TXSTA y RCSTA, eso lo tengo sin problemas. Incluso, como mencioné, puedo manipular los datos que me llegan, pero solo uno por uno; solo que lo que me llega, me llega en un bloque de datos (algo así como una cadena/string), y ahí es donde surge mi problema.

Desconectado jkcobain

  • PIC10
  • *
  • Mensajes: 18
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #6 en: 03 de Diciembre de 2016, 14:52:13 »
Bueno como te dijeron no se exactamente como se puede obtener el 9no bit en CCS con alguna funcion, mas que definir el bit y listo es decir usar la directiva #BIT.

El principal problema es ... si es necesario guardar ese bit.. Tal ves ese bit solo sirva para dar paridad. Si es asi CCS ya te lo realiza de por si solo, cuando en la directiva seleccionas PARITY=E o PARITY=O..

¿Como almacenarlo?

Si es una paridad no hace falta, ya que se controla antes y si la paridad no es correcta simplemente se descartaria el dato ( todo por software obviamente ).
Si es otra cosa ese 9no bit entonces deberias tener al menos una variable de 16bits o en su defecto una estructura de 8bits + 1 bit. Luego haces un array de esa estructura.
Rogando que eso no ocupe lo mismo que los 16bits, sino seria complicarla sin sentido.

Pero estoy mas que seguro que ese CHECK tiene que ser algo de paridad, revisa el protocolo bien.

Me parece muy interesante lo que me comentas. El único detalle es que no sé cómo descartar ese 9no bit. Bueno, me explico:

El 9no bit sirve únicamente para identificar que se trata del byte/dato "check", estando en 1 en estos casos, y en cero para todos los demás bytes que no sean el check. El dato check es la suma de todos los bytes anteriores (checksum), y sirve para comprobar que toda la información se recibió correctamente. Así que ese 9no bit, no me sirve mas que para identificar el final de la transmisión de los datos.

Como dice planeta9999, puedo ir guardando los bytes en una matriz, pero no sé cómo identificar el último bit, para en ese momento analizar la información que me llegó antes. Así mismo no sé si en una matriz se puedan guardar los datos a pesar de ser de 9 bits...

¡Agradezco cualquier ayuda que puedas brindarme!

Desconectado jkcobain

  • PIC10
  • *
  • Mensajes: 18
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #7 en: 03 de Diciembre de 2016, 15:02:00 »
Me explico un poco mejor:

El monedero envía un bloque de datos de información, seguido de un "checksum".

(A pesar de que los bytes son de 8 bits por definición, me tomaré la libertad de llamarlos así, a pesar de ser de 9 bits, para hacer más entendible la redacción.)

Todos los bytes que se trabajan en este protocolo, son de 9 bits.
El 9no bit NO es de paridad.
Todos los bytes, excepto el último, llevan en 0 el 9no bit (que son los de información).
El último byte, que generalmente es el checksum, lleva 9no bit en 1.
Ese 9no bit en 1, indica el final de la transmisión de datos.

No sé cómo almacenar mis "bytes" de 9 bits con el CCS, y no sé cómo identificar en mi código el final de la transmisión de datos. (por dar un ejemplo tonto (if 9bit==1 then....), no sé cómo comprobar esa condición)

Espero que con esto puedan comprender mejor mi problema, y ojalá que puedan ayudarme.

De nuevo, ¡gracias de antemano!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #8 en: 03 de Diciembre de 2016, 15:16:34 »
Bien. es decir que el 9no bit te marca el final de los datos, es como si fuera un bit de control nada mas. Mientras que los 8 son datos en si.

Esto seria demasiado FACIL en otro compilador ya que los registros estan definidos, pero elegiste CCS y en esa parte tiene algunas directivas especiales. Asi que tendrias que hacer:

Código: C
  1. #bit CHK = 0x42.2

Siendo 0x42 la direccion de memoria del registro donde se almacena el 9no bit y el 2 la posicion del bit.
Como no nombraste cual PIC estas usando no te podria poner exactamente la direccion que es. Pero si miras el datasheet te vas a dar cuenta. Entonces lo unico que te queda en la parte de la interrupcion es:

Código: C
  1. if ( !CHK )
  2. {
  3.       //Aca guardo mi dato
  4. }
  5. else
  6. {
  7.      //Calculo cheksum aca, si es correcto activo flag
  8.      dato_completo = 1;
  9. }

Luego para mostrarlo o "visualizarlo" depende que tengas.. pero lo mas seguro es que debas pasar los datos que estan en hexa a ascii si es un LCD, y de esa forma poder verlos facilmente.
Si lo estas simulando entonces podrias simplemente poner algo que reciba el UART ademas del PIC.

Desconectado jkcobain

  • PIC10
  • *
  • Mensajes: 18
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #9 en: 05 de Diciembre de 2016, 14:45:14 »
Bien. es decir que el 9no bit te marca el final de los datos, es como si fuera un bit de control nada mas. Mientras que los 8 son datos en si.

Esto seria demasiado FACIL en otro compilador ya que los registros estan definidos, pero elegiste CCS y en esa parte tiene algunas directivas especiales. Asi que tendrias que hacer:

Código: C
  1. #bit CHK = 0x42.2

Siendo 0x42 la direccion de memoria del registro donde se almacena el 9no bit y el 2 la posicion del bit.
Como no nombraste cual PIC estas usando no te podria poner exactamente la direccion que es. Pero si miras el datasheet te vas a dar cuenta. Entonces lo unico que te queda en la parte de la interrupcion es:

Código: C
  1. if ( !CHK )
  2. {
  3.       //Aca guardo mi dato
  4. }
  5. else
  6. {
  7.      //Calculo cheksum aca, si es correcto activo flag
  8.      dato_completo = 1;
  9. }

Luego para mostrarlo o "visualizarlo" depende que tengas.. pero lo mas seguro es que debas pasar los datos que estan en hexa a ascii si es un LCD, y de esa forma poder verlos facilmente.
Si lo estas simulando entonces podrias simplemente poner algo que reciba el UART ademas del PIC.

Tiene mucho sentido tu respuesta. Muchas gracias! Lo voy a probar

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1297
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #10 en: 05 de Diciembre de 2016, 14:59:50 »
Que tal jkcobain,

Lo que intentas hacer en relidad es sencillo, simplemente tienes que configurar el puerto serial del microcontrolador con 9 bits de recepción. Si observas en el datasheet del PIC16F627A (por ejemplo), en el registro RCSTA bit 6 se habilita la recepción de 9 bits y el estado del noveno bit se almacena en el bi 0 del mismo registro.

Espero esto te sirva para lo que necesitas hacer.

Elreypic.

Desconectado jkcobain

  • PIC10
  • *
  • Mensajes: 18
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #11 en: 08 de Diciembre de 2016, 15:48:53 »
Hola a todos de nuevo.

Estoy tratando de implementar las soluciones que me recomendaron, pero no logro hacerlas funcionar. He estado tratando de encontrar mi falla, pero no lo he conseguido. Lo más que se me ocurre es que haya algún problema por estar usando el #USE RS232. Les dejo las partes esenciales de mi código, y espero que alguien me pueda ayudar.

Es un PIC16F887
Código: [Seleccionar]
#USE RS232(baud=9600, parity=N, bits=9, uart1, long_data, stream=rs485) //Esto es la configuración que tengo del #use rs232

//aquí viene donde nombro los bits para la recepción
#bit rcv=0x18.0 //Este es el 9no bit, de acuerdo a la hoja de datos del pic
#bit rcven=0x18.6//Este es el bit para habilitar la recepción de 9 bits

#INT_RDA
inte(){
led=1;
  if(rcv==0){
    led2=0;
  }
  if(rcv==1){
    led2=1;
  }

Solo pongo la parte de código que considero necesaria para esto. Al principio de mi código principal, hago rcven=1; para habilitar la recepción de 9 bits. "led" lo uso para saber que entró a la interrupción (todo bien hasta ahí). Después pretendo usar el "led2" para ver si el pic logra distinguir entre un byte con el 9no bit en 1, o en 0; pero ahí empieza mi problema, ya que "led2" nunca cambia de estado.

Por otro lado, puedo decir que la transmisión de 9bits, es correcta, incluso la recepción. Ya que probé con algo mas o menos así:

Código: [Seleccionar]
//envío al pic en cuestión el dato siguiente
putchar(0x100);
//o el siguiente
putchar(0x000);

//En el pic en cuestión, tenía algo así

#INT_RDA
inte(){
 char=getc();
 if(char==0x100){
   led=1;
 }
 if(char==0x000){
 led=0;
}
}

Eso es solo un ejemplo, ya que ese código ya lo deseché. Pero la idea principal, era esa.
Así que mi problema, por lo que veo, es a la hora de identificar exclusivamente el 9no bit.

Espero que puedan ayudarme. ¡Muchas gracias de nuevo!

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1297
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #12 en: 08 de Diciembre de 2016, 18:57:13 »
Que tal jkcobain,

De hecho lo que tienes incorecto es la transmisión. Ya que putchar(0x100); siempre enviará 0x00, esta funcion es para enviar un dato de 8 bits, asi que esa no es la forma correcta de hacerlo. Como te mencione anteriormente tienes que habilitar la transmisión de 9 bits y entonces colocar el 9no bit en 0 o 1.
Esto se encuentra en el registro TXSTA. En el bit 6 de ese registro se habilita la transmision de 9 bits y el bit 0 de ese registro contiene el 9no bit que deseas enviar. Ahora bien el datasheet dice que primero tienes que colocar el valor de ese 9no bit en el bit 0 del registro TXSTA y luego enviar el dato (usando el putchar).

Espero que haya sido claro.

Saludos.

Elreypic.

Desconectado jkcobain

  • PIC10
  • *
  • Mensajes: 18
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #13 en: 08 de Diciembre de 2016, 19:54:11 »
Que tal jkcobain,

De hecho lo que tienes incorecto es la transmisión. Ya que putchar(0x100); siempre enviará 0x00, esta funcion es para enviar un dato de 8 bits, asi que esa no es la forma correcta de hacerlo. Como te mencione anteriormente tienes que habilitar la transmisión de 9 bits y entonces colocar el 9no bit en 0 o 1.
Esto se encuentra en el registro TXSTA. En el bit 6 de ese registro se habilita la transmision de 9 bits y el bit 0 de ese registro contiene el 9no bit que deseas enviar. Ahora bien el datasheet dice que primero tienes que colocar el valor de ese 9no bit en el bit 0 del registro TXSTA y luego enviar el dato (usando el putchar).

Espero que haya sido claro.

Saludos.

Elreypic.

Gracias por responder.

Tengo entendido que el "long_data" en el #use rs232 se encarga de hacer esa configuración. De hecho el putchar me funciona correctamente así como está. Aquí está una captura de la señal digital:



Usé 0x0AA y 0x1AA, para que fuera más fácil visualizar los bits. De esa manera queda 0x0AA = 0b010101010, y 0x1AA = 0b110101010

Desconectado jkcobain

  • PIC10
  • *
  • Mensajes: 18
Re:¿Cómo almacenar los bytes recibidos en el UART? (bytes de 9 bits)
« Respuesta #14 en: 10 de Diciembre de 2016, 16:54:28 »
Ya resolví mi problema. Mi error era que que el buffer de entrada era de 0 bytes, por lo que no se guardaba nada, y por eso el 9no bit era siempre 0. Solo fue cuestión de darle un valor al tamaño del buffer.

Muchas gracias a todos. ¡Fueron de gran ayuda!  :-)


 

anything