Autor Tema: captura de datos con int_RDA sin caracter de control  (Leído 2748 veces)

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

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
captura de datos con int_RDA sin caracter de control
« en: 30 de Enero de 2017, 01:46:55 »
Hola,estoy intentando capturar una pequeña trama por la interrupcion int_RDA. Los datos los envía un pequeño modulo mini RFID de 125K, este modulo envía esto cada vez que se pone un tag:
002e7593  tag amarillo
002E7593 tag verde
002602d6 tag rojo
Esos datos los tomo, con un simple código "leer caracter-escribir caracter."
Código: C
  1. c=getc(RFID);      
  2. fprintf(debug,"%x",c);

El problema es que no hay ningún control, no puedo saber cuando empieza ni cuando termina. Por lo que veo el UID es hex 00-00-00-00.
Hice este código, pero solo me funciona a la primera vez, de ahí en adelante va leyendo el tag con el valor desplazado.

Código: C
  1. #DEFINE SIZE_UID   4                  // Serial Buffer Size
  2. int  counter_read2 = 0x00;            // Serial Buffer Counter
  3. char c=0x00;  
  4. char UID[SIZE_UID];                    // ID 125 K
  5. int isCard=0x00;
  6. int k=0;
  7.  
  8.  #int_RDA                                                // Interrupción por recepción de datos UART1
  9. void RDA_isr1(void) {                              // Interrupción recepción serie USART
  10.    c=0x00;                                                // Inicializo caracter recibido                    
  11.    if(kbhit(RFID)){                                    // Si hay algo pendiente de recibir ...
  12.       c=getc(RFID);                                   //
  13.          UID[counter_read2++]=c;
  14.           if(counter_read2==4) {                         // 00 00 00 00
  15.             disable_interrupts(INT_RDA);             // Deshabilito Interrupcion, miestras proceso la trama
  16.              counter_read2=0x00;                         // Reincio contador
  17.              isCard=1;                                           // Tarjeta presente
  18.           }
  19.    }        
  20. }
  21.  
  22. /************************  FUNCIÓN PRINCIPAL  *********************************/
  23. void main () {
  24.    enable_interrupts(global);                     // Habilita interrupciones
  25.    enable_interrupts(int_rda);                    // Habilita Interrupción RDA UART1
  26.    memset(UID,NULL,sizeof(UID));           // Set all elements to NULL
  27.  
  28.    while(1){
  29.          if (isCard){                                            // Comprobar si hay alguna tarjeta
  30.               for (k=0;k<4;k++) fprintf(debug,"%X",UID[k]);       // IUD
  31.                fprintf(debug,"\r\n");                      
  32.                memset(UID,NULL,sizeof(UID));        
  33.                isCard=0;                                          
  34.                counter_read2=0x00;                      
  35.                enable_interrupts(INT_RDA);              // Habilitación interrupción por recepción UART1
  36.      }
  37.    }
  38. }
Esto sucede cuando pongo el tag azul "002FB39C" por ejemplo, la primera vez esta bien, pero de ahí se sigue desplazando.
002FB39C
00002FB3
9C00002F
B39C002F

¿Cómo  soluciono esto?


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:captura de datos con int_RDA sin caracter de control
« Respuesta #1 en: 30 de Enero de 2017, 02:30:46 »
Si lo recibis asi:

Citar
002e7593
002E7593
002602d6
Quiere decir que hay un salto de linea entre cada codigo

Si lo recibis asi:
Citar
002e7593002E7593002602d6

Es medio complejo. Te queda 2 formas de solucionarlo.
La primera es esperar los 2 ceros.  Y luego tomar lo que sigue. El tema es que no se si todos van a empezar con 00, tiene que existir un caracter de finalizacion de trama.
Donde lo estes viendo fijate si lo podes ver en hexa.

----------------------------

Respecto al error del codigo, realmente no lo veo. Es como si counter_read2 no se reiniciara.
¿Tendra algo que ver con el que desactivas las interrupciones?
O tal ves esta enviando un 0x00 mas y que vos estas omitiendo, y que luego terminas agregando al array sin querer.
« Última modificación: 30 de Enero de 2017, 02:50:10 por KILLERJC »

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re:captura de datos con int_RDA sin caracter de control
« Respuesta #2 en: 30 de Enero de 2017, 12:47:21 »
...
Gracias por responder,  cuando uso esto:
Código: [Seleccionar]
c=getc(RFID);     
fprintf(debug,"%x",c);
capturo por ejemplo "002e7593002E7593002602d6" que separando los tag, seria:
002e7593
002E7593
002602d6

he probado con muchos tag y siempre empiezan con "00",  pero no se si eso sea mera coincidencia o si realmente empiezan por "00" (Así seria mas fácil) ... porque entonces los tag serian de 3 hex, creo que eso seria demasiado corto.



https://es.aliexpress.com/store/product/Free-Shipping-Mini-RFID-Reader-ID-Card-RF-Module-125KHz-UART-Serial-Wiegand-with-Round-Coil/521135_32430957256.html?spm=2114.12010408.1000016.1.ng8iSm&isOrigTitle=true
El fabricante me envió este código
Código: C
  1. #include<reg51.h>
  2. #include<intrins.h>
  3. /* 宏定义 ---------------------------------------------------------------------*/
  4. #define LCD_DATA P0
  5. /* 本文件使用的变量 -----------------------------------------------------------*/
  6. unsigned long LEDTiming = 0;    //LED计时器
  7. unsigned char LEDValue = 1;             //LED显示出来的值
  8. unsigned long BUZZTiming = 0;   //蜂鸣器计时器
  9. unsigned long DelayTiming = 0;//延时计时器
  10.  
  11. unsigned char KeyCode = 0;
  12. sbit BUZZ = P2^0;
  13. sbit KEY  = P3^3;
  14.  
  15. sbit LCD_RS  = P2^4;
  16. sbit LCD_RW  = P2^5;
  17. sbit LCD_EN  = P2^6;
  18.  
  19. unsigned char UIDA[5];
  20. unsigned long UID;
  21. unsigned char LCD_RAM[16];
  22. /* 本文件使用的函数声明 -------------------------------------------------------*/
  23. void BUZZOn(void);
  24. void Delay(unsigned long ms50);
  25. void Delay72us(void);
  26. void LCDWriteCmd(unsigned char val);
  27. void LCDWriteData(unsigned char val);
  28. void LCDInit(void);
  29. void LCDDrawString(unsigned char addr, unsigned char *str);
  30. /* 本文件函数体 ---------------------------------------------------------------*/
  31.  
  32. unsigned char GetUID(void)
  33. {
  34.         unsigned char i, j;
  35.        
  36.         if(RI != 0)
  37.         {
  38.                 for(i = 0; i < 5; i ++)
  39.                 {
  40.                         j = 250;
  41.                         while(RI == 0 && --j);
  42.                         if(j == 0)
  43.                         {
  44.                                 break;
  45.                         }
  46.                         UIDA[i] = SBUF;
  47.                         RI = 0;
  48.                 }
  49.                 if(i == 5)
  50.                 {
  51.                         if((UIDA[0] ^ UIDA[1] ^ UIDA[2] ^ UIDA[3] ^ UIDA[4]) == 0)
  52.                         {
  53.                                 UID = UIDA[0];
  54.                                 UID <<= 8;
  55.                                 UID |= UIDA[1];
  56.                                 UID <<= 8;
  57.                                 UID |= UIDA[2];
  58.                                 UID <<= 8;
  59.                                 UID |= UIDA[3];
  60.                                 return 1;
  61.                         }
  62.                 }
  63.         }
  64.         return 0;
  65. }
  66. /*******************************************************************************
  67. * 函数名         : main
  68. * 描述           : 主函数
  69. * 输入           : 无
  70. * 输出           : 无
  71. * 返回           : 无
  72. *******************************************************************************/
  73. void main(void)
  74. {
  75.         /* 串口配置 */
  76.         SCON= 0x50;
  77.         //选用【定时器1】作为串口波特率发生器
  78.         //清除【定时器1】控制位
  79.         TMOD &= 0X0F;
  80.         //设置【定时器1】工作方式为8位自动重装
  81.         TMOD |= 0X20;
  82.         //设置串口波特率为9600、晶振选用11.0592M
  83.         TH1 = TL1 = 0xFD;
  84.         TR1 = 1;
  85.  
  86.         /* 【定时器0】配置 */
  87.         TMOD &= 0xF0;
  88.         // 【定时器0】工作方式为16位定时器
  89.         TMOD |= 0X01;
  90.         //定时【50ms】即是【50000us】设置方法
  91.         //系统周期 T = 12/(11.0592M)  <开发板通过跳线换成【12M】晶振就很好算了>
  92.         //寄存器值 TH0:TL0 = 65536 - (50000 / T)
  93.         //晶振 11.0592M 时 TH0:TL0 = 19453 转为16进制为 0x4BFD 即是TH0 = 0x4B、TL0 = 0xFD
  94.         //晶振    12M   时 TH0:TL0 = 15536 转为16进制为 0x3CB0 即是TH0 = 0x3C、TL0 = 0xB0
  95.         TH0 = 0x4B;
  96.         TL0 = 0xFD;
  97.         //开启【定时器0】中断
  98.         ET0 = 1;
  99.         //开【定时器0】
  100.         TR0 = 1;
  101.        
  102.         //开启全局中断
  103.         EA  = 1;
  104.         LCDInit();
  105.         LCDDrawString(0x80, "   Welcome!!!");
  106.         LCDDrawString(0xC0, "  Hello World!");
  107.         while(1)
  108.         {
  109.                 if(GetUID() != 0)
  110.                 {
  111.                         LCD_RAM[0] = ' ';
  112.                         LCD_RAM[1] = ' ';
  113.                         LCD_RAM[2] = ' ';
  114.                         LCD_RAM[3] = ' ';
  115.                         LCD_RAM[4] = UID / 1000000000 + '0';
  116.                         LCD_RAM[5] = UID % 1000000000 / 100000000 + '0';
  117.                         LCD_RAM[6] = UID % 100000000 / 10000000 + '0';
  118.                         LCD_RAM[7] = UID % 10000000 / 1000000 + '0';
  119.                         LCD_RAM[8] = UID % 1000000 / 100000 + '0';
  120.                         LCD_RAM[9] = UID % 100000 / 10000 + '0';
  121.                         LCD_RAM[10] = UID % 10000 / 1000 + '0';
  122.                         LCD_RAM[11] = UID % 1000 / 100 + '0';
  123.                         LCD_RAM[12] = UID % 100 / 10 + '0';
  124.                         LCD_RAM[13] = UID % 10 + '0';
  125.                         LCD_RAM[14] = 0;
  126.                         LCDDrawString(0x80, LCD_RAM);
  127.                        
  128.                         LCD_RAM[0] = ' ';
  129.                         LCD_RAM[1] = ' ';
  130.                         LCD_RAM[2] = ' ';
  131.                         LCD_RAM[3] = ' ';
  132.                         LCD_RAM[4] = (UID >> 16) % 100000 / 10000 + '0';
  133.                         LCD_RAM[5] = (UID >> 16) % 10000 / 1000 + '0';
  134.                         LCD_RAM[6] = (UID >> 16) % 1000 / 100 + '0';
  135.                         LCD_RAM[7] = (UID >> 16) % 100 / 10 + '0';
  136.                         LCD_RAM[8] = (UID >> 16) % 10 + '0';
  137.                         LCD_RAM[9] = ',';
  138.                         LCD_RAM[10] = (UID&0XFFFF) % 100000 / 10000 + '0';
  139.                         LCD_RAM[11] = (UID&0XFFFF) % 10000 / 1000 + '0';
  140.                         LCD_RAM[12] = (UID&0XFFFF) % 1000 / 100 + '0';
  141.                         LCD_RAM[13] = (UID&0XFFFF) % 100 / 10 + '0';
  142.                         LCD_RAM[14] = (UID&0XFFFF) % 10 + '0';
  143.                         LCD_RAM[15] = 0;
  144.                         LCDDrawString(0xC0, LCD_RAM);
  145.                 }
  146.         }
  147. }
  148.  
  149. /*******************************************************************************
  150. * 函数名         : Delay
  151. * 描述           : 以50ms为单位延时
  152. * 输入           : ms50: 50ms计数, 为 1 时延时不准确
  153. * 输出           : 无
  154. * 返回           : 无
  155. *******************************************************************************/
  156. void Delay(unsigned long ms50)
  157. {
  158.         DelayTiming = ms50;
  159.         while(DelayTiming != 0);
  160. }
  161.  
  162. /*******************************************************************************
  163. * 函数名         : BUZZOn
  164. * 描述           : 打开蜂鸣器
  165. * 输入           : 无
  166. * 输出           : 无
  167. * 返回           : 无
  168. *******************************************************************************/
  169. void BUZZOn(void)
  170. {
  171.         BUZZTiming = 40;
  172.         BUZZ = 0;
  173. }
  174. /*******************************************************************************
  175. * 函数名         : Delay72us
  176. * 描述           : 延时72us
  177. * 输入           : 无
  178. * 输出           : 无
  179. * 返回           : 无
  180. *******************************************************************************/
  181. void Delay72us(void)
  182. {
  183.         unsigned int i;
  184.         for(i = 0; i < 5; i ++);
  185. }
  186. /*******************************************************************************
  187. * 函数名         : LCDWriteCmd
  188. * 描述           : 向 LCD写命令
  189. * 输入           : -val:将要写的命令
  190. * 输出           : 无
  191. * 返回           : 无
  192. *******************************************************************************/
  193. void LCDWriteCmd(unsigned char val)
  194. {
  195.         LCD_DATA = val;
  196.         LCD_RW = 0;
  197.         LCD_RS = 0;
  198.         LCD_EN = 0;
  199.         LCD_EN = 1;
  200.         Delay72us();
  201. }
  202. /*******************************************************************************
  203. * 函数名         : LCDWriteData
  204. * 描述           : 向 LCD写数据
  205. * 输入           : -val:将要写的数据
  206. * 输出           : 无
  207. * 返回           : 无
  208. *******************************************************************************/
  209. void LCDWriteData(unsigned char val)
  210. {
  211.         LCD_DATA = val;
  212.         LCD_RW = 0;
  213.         LCD_RS = 1;
  214.         LCD_EN = 0;
  215.         LCD_EN = 1;
  216.         Delay72us();
  217. }
  218. /*******************************************************************************
  219. * 函数名         : LCDInit
  220. * 描述           : 初始化LCD
  221. * 输入           : 无
  222. * 输出           : 无
  223. * 返回           : 无
  224. *******************************************************************************/
  225. void LCDInit(void)
  226. {
  227.         LCDWriteCmd(0x38);
  228.         LCDWriteCmd(0x0c);
  229.         LCDWriteCmd(0x06);
  230.         LCDWriteCmd(0x01);
  231.         Delay(5);
  232. }
  233.  
  234. /*******************************************************************************
  235. * 函数名         : LCDDrawString
  236. * 描述           : 在LCD上写字符串
  237. * 输入           : -addr:地址 -1602可以为0x80/0xC0
  238.                                                                                                                         -12864可以为0x80/0x90/0x88/0x98
  239.                                                                          -str: 字符串地址
  240. * 输出           : 无
  241. * 返回           : 无
  242. *******************************************************************************/
  243. void LCDDrawString(unsigned char addr, unsigned char *str)
  244. {
  245.         unsigned char i;
  246.        
  247.         LCDWriteCmd(addr);
  248.        
  249.         for(i = 0; i < 16; i ++)
  250.         {
  251.                 if(*(str+i) == 0)
  252.                 {
  253.                         break;
  254.                 }
  255.                 else
  256.                 {
  257.                         LCDWriteData(*(str+i));
  258.                 }
  259.         }
  260.        
  261.         for( ; i < 16; i ++)
  262.         {
  263.                 LCDWriteData(' ');
  264.         }
  265. }
  266.  
  267. /*******************************************************************************
  268. * 函数名         : timer0
  269. * 描述           : 定时器0中断
  270. * 输入           : 无
  271. * 输出           : 无
  272. * 返回           : 无
  273. *******************************************************************************/
  274. void timer0() interrupt 1
  275. {
  276.         //重新装寄存器值,仍然定时50ms
  277.         TH0 = 0x4B;
  278.         TL0 = 0xFD;
  279.         if(LEDTiming > 0){LEDTiming --;}
  280.         if(BUZZTiming > 0){BUZZTiming --;}
  281.         if(DelayTiming>0){DelayTiming--;}
  282. }

la función que captura el UID es unsigned char GetUID(void)

EDIT

segun esto:
https://github.com/Seeed-Studio/RFID_Library
el dato si empieza por 00
your card number: 0009531147
that your data  : 00 91 6f 0b f5
Raro ese ejemplo, porque según lo que capturo son tag de "00-99-96-4e" 4 espacios.
« Última modificación: 30 de Enero de 2017, 14:00:39 por cvargcal »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:captura de datos con int_RDA sin caracter de control
« Respuesta #3 en: 30 de Enero de 2017, 13:58:34 »
Segun el codigo toma 5 valores. Te lo dejo comentado:

Código: C
  1. unsigned char GetUID(void)
  2. {
  3.         unsigned char i, j;
  4.        
  5.         if(RI != 0)                             //Bit de flag de interrupcion
  6.         {
  7.                 for(i = 0; i < 5; i ++)                         //Tomar hasta 5 caracteres
  8.                 {
  9.                         j = 250;
  10.                         while(RI == 0 && --j);          //Esto es una especie de Timeout, o se recibe continuamente o sale
  11.                         if(j == 0)
  12.                         {
  13.                                 break;
  14.                         }
  15.                         UIDA[i] = SBUF;
  16.                         RI = 0;
  17.                 }
  18.                 if(i == 5)                              // Si se recibio todo procede a hacer el checksum
  19.                 {
  20.                         if((UIDA[0] ^ UIDA[1] ^ UIDA[2] ^ UIDA[3] ^ UIDA[4]) == 0)
  21.                         {
  22.                                 UID = UIDA[0];          // Lo pone todo en una sola variable
  23.                                 UID <<= 8;
  24.                                 UID |= UIDA[1];
  25.                                 UID <<= 8;
  26.                                 UID |= UIDA[2];
  27.                                 UID <<= 8;
  28.                                 UID |= UIDA[3];
  29.                                 return 1;
  30.                         }
  31.                 }
  32.         }
  33.         return 0;
  34. }

Comienza preguntando si esta activo el flag de interrupcion, porque esto es llamado desde el main. Si esta activo lo primero que hace es entrar al for, el primer dato ( 0 ) lo toma directamente, ahora pasa al segundo ( 1 ) y ahi comienza a funcionar lo de la variable j, es como un "timeout", si mientras eso se ejecuta llega otro caracter entonces lo guarda y comienza de nuevo el timeout, si por algun motivo no llego nada, porque se corto la conexion o lo que sea, sale del for y deja de guardar.
Despues tenes la parte del if, que simplemente hace un checksum si es que todas las partes llegaron, y que si esta correcto, procede a guardar los valores en una sola variable.

El modo serial esta configurado como UART 8-bit de baud rate 172.800 (sacado de los comentarios que dice esa frecuencia y que al reset viene configurado como Fosc/64 el baud rate)

Nada mas puedo sacar del codigo como para darte una ayuda.

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re:captura de datos con int_RDA sin caracter de control
« Respuesta #4 en: 30 de Enero de 2017, 17:04:16 »
Segun el codigo toma 5 valores. Te lo dejo comentado:
....

Si, mi error era no fijarme que si son 5 espacios, es curioso por que el ultimo valor no lo imprime cuando "leo y escribo"
Este código funciona bien:
Código: C
  1. #DEFINE SIZE_UID   6                  // Serial Buffer Size
  2. char UID[SIZE_UID];                    // ID 125 K
  3. char c=0x00;  
  4. int isCard=0x00;
  5. int k=0;
  6. int i=0;
  7.  
  8. #int_RDA                                     // Interrupción por recepción de datos UART1
  9. void RDA_isr1(void) {                        // Interrupción recepción serie USART
  10.    c=0x00;                                   // Inicializo caracter recibido                    
  11.    if(kbhit(RFID)){                          // Si hay algo pendiente de recibir ...
  12.       c=getc(RFID);                          //
  13.          UID[i++]=c;
  14.           if(i==5) {                         // 00 00 00 00 00
  15.             disable_interrupts(INT_RDA);     // Deshabilito Interrupcion, miestras proceso la trama
  16.              i=0x00;                         // Reincio contador
  17.              isCard=1;                       // Tarjeta presente
  18.               }
  19.           }
  20.    }        
  21.  
  22. /************************  FUNCIÓN PRINCIPAL  *********************************/
  23. void main () {
  24.    enable_interrupts(global);                     // Habilita interrupciones
  25.    enable_interrupts(int_rda);                    // Habilita Interrupción RDA UART1
  26.    memset(UID,NULL,sizeof(UID));                  // Set all elements to NULL
  27.  
  28.    while(1){
  29.          if (isCard){                                            // Comprobar si hay alguna tarjeta
  30.               for (k=0;k<5;k++) fprintf(debug,"%X",UID[k]);      // IUD
  31.               fprintf(debug,"\r\n");                        
  32.                memset(UID,NULL,sizeof(UID));
  33.                isCard=0;                                          
  34.                i=0x00;                      
  35.                enable_interrupts(INT_RDA);                  // Habilitación interrupción por recepción UART1
  36.      }
  37.    }
  38. }
pero obtengo:
002602D6F2  >>  00-26-02-D6-F2
00B45253B5  >> B4-52-53 >> 0011817555 (Esto es lo que busco)
008498D7CB
00B2930322


Según la teoría:
Numero tarjeta: 0009531147    Este es el numero que veo impreso en los tag
Dato          : 00 91 6f 0b f5        El dato que capturo
check bit, f5 = 00^91^6f^0b    Checksum

916f0b =9531147, ¿como hago para obtener siempre esto "0009531147"?

Intente hacerlo como lo muestra el código:

// Checksum,  aquí lo hacen con = 0, pero debe ser f5 = 00^91^6f^0b, no sé si es lo mismo.
Código: C
  1. if(i == 5){
  2.                         if((UIDA[0] ^ UIDA[1] ^ UIDA[2] ^ UIDA[3] ^ UIDA[4]) == 0)
  3.                         {
  4.                                 UID = UIDA[0];
  5.                                 UID <<= 8;
  6.                                 UID |= UIDA[1];
  7.                                 UID <<= 8;
  8.                                 UID |= UIDA[2];
  9.                                 UID <<= 8;
  10.                                 UID |= UIDA[3];
  11.                                 CardOk=1;
  12.                           }
bueno, yo sé que eso es solo para comprobar si llego bien.
pero quiero imprimir en formato decimal como muestra el ejemplo, y como lo hace esto:
Código: C
  1. LCD_RAM[0] = ' ';
  2.                         LCD_RAM[1] = ' ';
  3.                         LCD_RAM[2] = ' ';
  4.                         LCD_RAM[3] = ' ';
  5.                         LCD_RAM[4] = UID / 1000000000 + '0';
  6.                         LCD_RAM[5] = UID % 1000000000 / 100000000 + '0';
  7.                         LCD_RAM[6] = UID % 100000000 / 10000000 + '0';
  8.                         LCD_RAM[7] = UID % 10000000 / 1000000 + '0';
  9.                         LCD_RAM[8] = UID % 1000000 / 100000 + '0';
  10.                         LCD_RAM[9] = UID % 100000 / 10000 + '0';
  11.                         LCD_RAM[10] = UID % 10000 / 1000 + '0';
  12.                         LCD_RAM[11] = UID % 1000 / 100 + '0';
  13.                         LCD_RAM[12] = UID % 100 / 10 + '0';
  14.                         LCD_RAM[13] = UID % 10 + '0';
  15.                         LCD_RAM[14] = 0;
  16.                         LCDDrawString(0x80, LCD_RAM);
  17.                        
  18.                         LCD_RAM[0] = ' ';
  19.                         LCD_RAM[1] = ' ';
  20.                         LCD_RAM[2] = ' ';
  21.                         LCD_RAM[3] = ' ';
  22.                         LCD_RAM[4] = (UID >> 16) % 100000 / 10000 + '0';
  23.                         LCD_RAM[5] = (UID >> 16) % 10000 / 1000 + '0';
  24.                         LCD_RAM[6] = (UID >> 16) % 1000 / 100 + '0';
  25.                         LCD_RAM[7] = (UID >> 16) % 100 / 10 + '0';
  26.                         LCD_RAM[8] = (UID >> 16) % 10 + '0';
  27.                         LCD_RAM[9] = ',';
  28.                         LCD_RAM[10] = (UID&0XFFFF) % 100000 / 10000 + '0';
  29.                         LCD_RAM[11] = (UID&0XFFFF) % 10000 / 1000 + '0';
  30.                         LCD_RAM[12] = (UID&0XFFFF) % 1000 / 100 + '0';
  31.                         LCD_RAM[13] = (UID&0XFFFF) % 100 / 10 + '0';
  32.                         LCD_RAM[14] = (UID&0XFFFF) % 10 + '0';
  33.                         LCD_RAM[15] = 0;

por ejemplo eso imprime algo así como esto (que es lo que esta impreso en la tarjeta):
0011817555
180,21075

« Última modificación: 30 de Enero de 2017, 17:41:32 por cvargcal »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:captura de datos con int_RDA sin caracter de control
« Respuesta #5 en: 30 de Enero de 2017, 19:37:53 »
Citar
// Checksum,  aquí lo hacen con = 0, pero debe ser f5 = 00^91^6f^0b, no sé si es lo mismo.

Es que te queda en 0. Tomando los numeros que me diste, el checksum es el ultimo dato:

008498D7CB ->  0x00 ^ 0x84 ^ 0x98 ^ 0xD7 = 0xCB , si haces 0xCB ^ 0xCB = 0

00B2930322  ->  0x00 ^ 0xB2 ^ 0x93 ^ 0x03 = 0x22 , si haces 0x22 ^ 0x22 = 0 ,

por eso en el if esta con "==" a 0.

Citar
pero quiero imprimir en formato decimal como muestra el ejemplo, y como lo hace esto:

En si no es nada complejo. Vos lo fuiste guardando de byte en byte en UID.

Por ser un micro pequeño te conviene mas usar una union, y despues le dejamos el trabajo al fprintf

Código: C
  1. //Definicion de union
  2. union IDcard {
  3.         int8 Enbytes[4];
  4.         int16 EnHWord[2];
  5.         int32 EnWord;
  6. }
  7.  
  8. // Esto global
  9. union IDcard IDcard;
  10.  
  11.  
  12. // Esto en ves de desactivar las interrupciones
  13. IDcard.Enbytes[0] = UID[0];
  14. IDcard.Enbytes[1] = UID[1];
  15. IDcard.Enbytes[2] = UID[2];
  16. IDcard.Enbytes[3] = UID[3];
  17.  
  18.  
  19. //Imprimo valores:
  20.  
  21. fprintf(debug,"%d\r\n",IDcard.EnWord);
  22. fprintf(debug,"%d,%d\r\n",IDcard.EnHWord[0],IDcard.EnHWord[1]);

Basicamente en el codigo digo que un una variable de 32bits, puede estar formado por 2 de 16bits, o 4 de 8 bits.
Cargo byte a byte al comienzo. El codigo que tenes lo hace con shift (forma una variable de 32 bits ) en cambio este codigo asume que los 4 valores es uno de 32bits completo.
Como es un numero y basicamente el codigo de muestra es pasar ese numero de hexa a decimal (recorda que el ultimo valor luego del checksum se descarta):

0x00B45253 = 11817555

Al usar el primer printf le digo que lo pase a "decimal" y listo. Ahora con la segunda parte. La segunda parte divide el numero a la mitad

0x00B45253 o mejor dicho: 0x00B4 0x5253
Pasado esto a decimal te queda: 180 y 21075

Si observas esa variable de 32bits son como 2 de 16 juntas en memoria, por eso en la union puse como si hubiera 2 variables de 16 tambien. NUevamente la conversion de hexa a decimal o string se lo dejo al fprintf.

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re:captura de datos con int_RDA sin caracter de control
« Respuesta #6 en: 31 de Enero de 2017, 00:54:17 »
Citar
// Checksum,  aquí lo hacen con = 0, pero debe ser f5 = 00^91^6f^0b, no sé si es lo mismo.
....

Genial eso de "union" no sabia sobre eso, lo encuentro muy útil.
Cuando intento compilar en CCS, tengo problemas en la linea del fprint,
*** Error 114 "testmini.c" Line 94(46,52): Printf format type is invalid  ::

si uso "lu,X,x.." no hay problema, pero con %d.

si lo imprimo de esta forma si funciona:
fprintf(debug,"%d\r\n",idcard.Enbytes[0]);
claro, porque me refiero al espacio especifico...
« Última modificación: 31 de Enero de 2017, 01:23:57 por cvargcal »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:captura de datos con int_RDA sin caracter de control
« Respuesta #7 en: 31 de Enero de 2017, 03:23:02 »
Si mi mala, CCS no permite el uso de algunas cosas.. En un printf comun, %u es unsigned y se puede usar para todos. En cambio en CCS no. (Yo me confundi en poner %d que es para enteros con signo)

Tenes que usar %Lu para las de 16 y 32bits.

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re:captura de datos con int_RDA sin caracter de control
« Respuesta #8 en: 01 de Febrero de 2017, 11:52:00 »
...

Muchas gracias por tus respuestas,
cuando leo el tag 008498D7CB, este es el resultado:
3617096704
33792,55192

Lo que lee esta bien, porque estoy haciendo el control con el checksum CB para imprimir.
pero debería imprimir :
0008689879= 008498D7
132,39127

Que es lo que esta impreso en la tarjeta.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:captura de datos con int_RDA sin caracter de control
« Respuesta #9 en: 01 de Febrero de 2017, 12:23:53 »
Citar
Muchas gracias por tus respuestas,
cuando leo el tag 008498D7CB, este es el resultado:
3617096704
33792,55192

Estan al reves xD, es por eso...

3617096704 = 008498D7

Me refiero a cargarlos al reves aca:

Código: C
  1. IDcard.Enbytes[0] = UID[3];
  2. IDcard.Enbytes[1] = UID[2];
  3. IDcard.Enbytes[2] = UID[1];
  4. IDcard.Enbytes[3] = UID[0];

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re:captura de datos con int_RDA sin caracter de control
« Respuesta #10 en: 01 de Febrero de 2017, 12:57:01 »
Citar
...

Genial, eres un maestro.
Y también se debe imprimir
fprintf(debug,"%Lu,%Lu\r\n",IDcard.EnHWord[1],IDcard.EnHWord[0]);

Muchas gracias, una ultima cosa.
0008689879= 008498D7  >> este numero lo entiendo,sé que sólo es la conversión a decimal
132,39127                   >> ¿Este numero que es?
Esos dos datos los veo impreso en los tags.

No es necesario pero, me gustaría saber como hago para poner el formato del numero en "0000000000", para que se imprima en 10 cifras, es decir, que siempre complete con ceros.


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:captura de datos con int_RDA sin caracter de control
« Respuesta #11 en: 01 de Febrero de 2017, 18:41:20 »
con %010lu

El 0 para el padding con ceros, el 10 para la cantidad de digitos, y lu el tipo

Desconectado cvargcal

  • PIC16
  • ***
  • Mensajes: 166
Re:captura de datos con int_RDA sin caracter de control
« Respuesta #12 en: 01 de Febrero de 2017, 22:45:32 »
con %010lu

El 0 para el padding con ceros, el 10 para la cantidad de digitos, y lu el tipo

Excelente, gracias!!