Hola gente. Estoy empezando con esto de los pic y quisiera un poco de ayuda.
Paso a comentar lo que quiero implementar.
Tengo un modulo RFID GP8F-R2 y simplemente pretendo leer los datos de su ID que emite, que corresponden a una tarjeta tag de rfid.
El problema que tengo, es que al leer la primera tarjeta, funciona bien, cuando quiero leer de nuevo, me produce error.
Estoy seguro que el problema es el pic y no el rfid, ya que si desconecto la alimentacion del pic, y pruebo leer la tarjeta lo hace en forma correcta, pero intento por segunda vez y ya no se puede.
Intente de varias formas, con interrupcion y sin interrupcion del puerto y ambas me dan el mismo error, solo lee correctamente una vez la tarjeta tag.
Estaba pensando que quizas sea un problema de algun buffer del pic que no lo borre, pero no estoy seguro, quizas alguna configuracion que se me esta escapando.
Aqui esta el codigo:
#include <18F4550.h>
#device adc=8
//Estos fuses los obtuve con el widzar
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES MCLR //Master Clear pin enabled
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL12 //Divide By 12(48MHz oscillator input)
#FUSES CPUDIV4 //System Clock by 4
#FUSES USBDIV //USB clock source comes from PLL divide by 2
#FUSES VREGEN //USB voltage regulator enabled
#FUSES ICPRT //ICPRT enabled
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include <string.h>
///////////////////////////////////////
// Constantes
///////////////////////////////////////
int const lenbuff=20; // Longitud máxima del buffer
///////////////////////////////////////
// RAM
///////////////////////////////////////
int xbuff=0x00; // Índice: siguiente char en cbuff
char cbuff[lenbuff]; // Buffer de recepción
int1 flagcommand=0; // Flag para comando disponible
///////////////////////////////////////
// Funciones de Buffer
///////////////////////////////////////
// Inicia a \0 cbuff -------------------
void init_cbuff(void){
int i;
for(i=0;i<lenbuff;i++){// Bucle que pone a 0 todos los
cbuff=0x00; // caracteres en el buffer
}
xbuff=0x00; // Inicializo el indice de siguiente caracter
}
// Añade a cbuff -----------------------
void add_2_cbuff(char c){ //En esta parte distingue si se ingresa un enter, un back space y un space, los dos ultimos no los utilizo ya que solo importa el enter.
switch(c){
case 0x0D: // Enter -> Habilita Flag para procesar comando
flagcommand=1;
break;
case 0x08: // Del -> Borra último caracter del Buffer
if(xbuff>0) cbuff[--xbuff]=0x00;
break;
case 0x01B: // Esc -> Borra el Buffer completamente
init_cbuff();
break;
default: // Añade caracter recibido al Buffer
cbuff[xbuff++]=c;
}
}
///////////////////////////////////////
// Procesador de Comandos
///////////////////////////////////////
void commad_process(void){
char cmd[lenbuff]; // Comando
flagcommand=0; // Desactivo flag de comando pendiente.
strcpy(cmd,cbuff); // Lo copio para procesarlo
init_cbuff(); // Borro buffer.
if(cmd[0]==0x02){
output_high (pin_b0);
delay_ms(1000);
output_low(pin_b0);
}
}
///////////////////////////////////////
// INTERRUPCIONES : RDA Recepción USART
///////////////////////////////////////
#int_RDA
void RDA_isr(void)
{
char rcvchar=0x00; // último caracter recibido
if(kbhit()){ // Si hay algo pendiente de recibir ...
rcvchar=getc(); // lo descargo y ...
add_2_cbuff(rcvchar); // lo añado al buffer y ...
}
}
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
setup_oscillator(OSC_4MHZ|OSC_INTRC|OSC_PLL_OFF);
// TODO: USER CODE!!
output_high (pin_b0); // enciendo y apago un led de prueba, solo para corroborar que funciona bien
delay_ms(1000);
output_low(pin_b0);
do {
if(flagcommand) commad_process(); // Hay algo pendiente de procesar y lo procesa.
} while (TRUE);
}
Este codigo lo modifique de uno que publico RedPic sobre como trabajar con el puerto RS232
El modulo RFID proporciona una cadena con
<STX> <DATA (10 bytes)> <CR> <LF> <ETX>
y trabaja a 9600 con 8 bits serie asincronico, sin paridad, a nivel logico
El RFID funciona correcto, puesto que lo he probado con un max 232 y se comunica de forma perfecta con la PC. De ahi puede anotar los numeros ID de cada tarjeta.
El Codigo de arriba solo pretende leer el STX (tengo tres tag) solo para corroborar que funciona bien, me pareció la prueba mas trivial.
Obviamente este es un paso previo al programa completo, pero lo unico que pretendo es leer ese bit STX, que me indica que se leyo una targeta correctamente y mostrar un led encendido en pin b0 confirmando la lectura.
El problema es que la segunda vez que paso una tarjeta en el modulo rfid, y este envia la cadena de caracteres, nunca mas se prende el led, es decir nunca mas el cmd[0], que es la cadena donde recibo el dato, obtiene el valor 0x02.
Repito, si desconecto la alimentacion del pic, funciona bien correctamente, eh probado con otro programa leer el dato completo y compararlos con los valores del ID de la targeta y si funciona, pero solo la primera vez!
Espero que puedan ayudarme, desde ya muchas gracias