Estoy tratando de recibir 32 bytes a traves de la UART con un PIC24FJ256GB110 provenientes de un chip de RFID (TMS3705). Estuve viendo el thread de otro usuario que lo uso al IC, pero no resolvio mi duda.
En el osciloscopio lo que veo es:
La señal en rojo la estoy generando yo, esta en UNO 48mS y en BAJO 52mS. La señal en amarillo son los 32 bytes que devuelve el TMS3705, en este caso esta leyendo un tag.
Haciendo un zoom a la señal:
Ahi se puede ver que el paquete de datos tiene una duracion de 16,38mS, siendo 64uS por bits, ahi estan los 256 bits = 32 bytes.
Haciendo aun mas zoom:
Pudiendo comprobarse que con todos los tags, el primero byte que se lee '11000000' o 0xCO, entonces mi idea es usar la uart por medio de interrupcion para que interrumpa cada vez que se recibio un byte, de manera que por cada paquete de datos se interrumpa 32 veces, y de esta manera pasar cada byte de la UART a un array....
En el main tengo:
TRISA=0x0000;
TRISB=0x0000;
TRISC=0x0000;
TRISD=0x0000;
TRISE=0x0000;
LATA=0x0000;
LATB=0x0000;
LATC=0x0000;
LATD=0x0000;
LATE=0x0000;
AD1PCFGL = 0xFFFF; //Todos los PCFGx como digitales.
TRISFbits.TRISF3 = 1;
// Assign U1RX To Pin RP16 (PIN51, F3)
RPINR18bits.U1RXR = 16;
TRISDbits.TRISD8 = 0;
// Assign U1TX To Pin RP2 (PIN68, D8)
RPOR1bits.RP2R = 3;
UART1Init(19); //Initiate UART1 to 15625 at 10MHz OSCI
Este es mi loop:
IEC0bits.U1RXIE = 1;
LATEbits.LATE0 = 1;
vTaskDelay(48/portTICK_RATE_MS);
LATEbits.LATE0 = 0;
if(bufferfull == 1)
{
bufferfull = 0;
//HEX -> ASCII
}
vTaskDelay(52/portTICK_RATE_MS);
Siendo UART1Init:
void UART1Init(int BAUDRATEREG1)
{
//Set up registers
U1BRG = BAUDRATEREG1; //set baud speed
U1MODE = 0x8000; //turn on module
U1STAbits.UTXISEL1 = 1; //Interrupt when a character is transferred
//to the Transmit Shift Register (TSR) and as a result,
//the transmit buffer becomes empty
U1STAbits.UTXISEL0 = 0;
U1STAbits.UTXINV = 0;
U1STAbits.UTXBRK = 0;
U1STAbits.UTXEN = 1;
U1STAbits.URXISEL1 = 0; //Interrupt is set when any character is received and
//transferred from the RSR to the receive buffer.
//Receive buffer has one or more characters.
U1STAbits.URXISEL0 = 0;
U1STAbits.ADDEN = 0;
U1STAbits.RIDLE = 0;
//reset RX interrupt flag
IFS0bits.U1RXIF = 0;
//Maxima Prioridad.
IPC2bits.U1RXIP2=1;
IPC2bits.U1RXIP1=0;
IPC2bits.U1RXIP0=1;
IEC0bits.U1RXIE = 1;
}
Y la interrupcion:
void __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt(void)
{
unsigned char temp, dataok=0;
IFS0bits.U1RXIF = 0;
while(U1STAbits.URXDA)
{
temp = U1RXREG;
if(temp == 0xC0 && indice == 0)
{
LATEbits.LATE3 = 1;
rx[indice] = temp;
dataok = 1;
indice++;
}
if(dataok==1 && indice !=0)
{
rx[indice] = temp;
indice ++;
if(indice==32)
{
LATEbits.LATE3 = 0;
indice = 0;
bufferfull=1;
dataok=0;
IEC0bits.U1RXIE = 0;
}
}
}
LATEbits.LATE3 = 0;
}
En la interrupcion, la idea es comprobar que cuando se de la misma, ver si es el primer byte esperado (0xC0) y comrpobarlo tambien mediante indice=0, si es asi, me aseguro que si es el primer byte y lo estoy recibiendo de manera correcta.....
En las proximas 31 interrupciones, deberian ser los 31 bytes restantes, de manera de ir guardandolos en rx. Cuando hayan llegado los 32 bytes, deshabilito la interrupcion por cualquier cosa que pueda llegar cuando no deberia......Y es activada nuevamente cuando pongo RE0 en UNO.
Agregue el PIN RE3 para que este en alto desde que detecte el 0xC0 hasta que lleguen los 32 bytes y luego vuelva a cero.....que viendolo con el osciloscopio,,,no llega nunca el 0xC0.
Que es lo que esta mal en la logica???
Gracias!!
EDIT: Estaba equivocado en el concepto.....todo el paquete de datos cuenta, por cada byte con su bit de arranque y bit de stop mas los 8 bits de datos.....y son 17 paquetes en total.....ademas estaba leyendo los datos invertidos, por eso no leia....cambiado de logica, y considerando los bits de start y stop,,,,ya esta solucionado.....ya puedo leer los diferentes tags.
Moderadores: cerrar o eliminar si hace falta.