Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Veo que la UART me vá bien para retrasmitir variadas cadenas de caracteres sin error, pero le sienta FATAL que le mande siempre 0x7F. He probado ha hacer de todo: cambiar bits de stop, cambiar un poco el baudrate, quitar/poner bit de paridad y nada.
Debe ser algún bug oculto en el micro. He probado incluso a cambiar de compilador del C30 al X16 y nada.
He sacado en paralelo dos cables conectando a RX y terra un módulo USB-RS232 del cual leo usando labview y lee perfectamente 0x7F 0x7F ....
Pregunta: ¿qué micro me recomendáis con un RS232 que sea ROBUSTO?
Pongo aquí el software:
Programación del reloj:
_FOSC(CSW_FSCM_OFF & XT_PLL8 ); // Fosc=8x7.3728MHz, Fcy=7.3728MHz CRISTAL EXTERNO!!!
unsigned long int Fcy=8*7372800/4;//Si pones PLL4 multiplicar por 4, si PLL8 multiplicar por 8
_FWDT(WDT_OFF); // Watchdog timer off
_FBORPOR(PBOR_ON & BORV27 & PWRT_64 & MCLR_DIS);//Brown out voltage=2.7V delay power on=64ms
De la UART y timers:
//Configurar Uart-2
U2MODEbits.UARTEN = 0; // Disable UART-2
U2BRG = Fcy/BAUDRATE/16-1; // 38400 baud
U2MODEbits.PDSEL = 0;//0b10; //odd parity!!. Sin paridad=00, 01=even, 0b10=odd, 11=trasmite 9 bits (?)
U2STAbits.UTXISEL = 0; // enable/disable interrupt when TX buffer is empty ??
// U2MODEbits.BRGH=0; //16 clock/bit (0=low speed)
U2MODEbits.LPBACK = 0; //Disable loopback
U2MODEbits.STSEL = 1; //0=1 stop bit, 1=2 stops bits
U2MODEbits.ABAUD = 0; // Autobaud desactivado
U2MODEbits.UARTEN = 1; // Enable UART-2
U2STAbits.UTXEN = 1; // Enable TX-2
// Configure Timer 1
PR1 = 65535; // Set the Timer 1 period (max 65535)
TMR1 = 0; // Reset Timer 1 counter
IEC0bits.T1IE = 0; // Disable Timer 1 interrupt
T1CONbits.TCKPS = 3; // Prescaler (0=1:1, 1=1:8, 2=1:64, 3=1:256) Frecuencia=Fcy/256
T1CONbits.TON = 1; // Turn on Timer 1
// Configure Timer 2
PR2 = 65535; // Set the Timer 2 period (max 65535)
TMR2 = 0; // Reset Timer 2 counter
IEC0bits.T2IE = 0; // Disable Timer 2 interrupt
T2CONbits.TCKPS = 3; // Prescaler (0=1:1, 1=1:8, 2=1:64, 3=1:256) Frecuencia=Fcy/256
T2CONbits.TON = 1; // Turn on Timer 2
El software es muy sencillo:
while(1)
{
if (U2STAbits.URXDA) //hay byte en RX1 **
{
r=(byte) U2RXREG;
U2TXREG=r;
//envia(r);
if (r==0x7F) LED_W=0; else LED_W=1;
}
//========== FIN loopback de pruebas =========
}
Con un cristal de 8MHz te iría a 38461,5 bps (BRG=12)
Con el de 7,372 debería ir a 38295 bps (BRG=11)
Si no te salen esos valores algo debe fallar en el clock del micro o no lo configuras bien.
¿Has conseguido solucionarlo?
BRG=7.32728e6/16/38400-1=11 BRG=11 -> 38400 baudios (con los ppm aprox del reloj)
BRG=10 -> 7.32728e6/(10+1)/16=41632 baudios
Con el arm habría podido poner una frecuencia más parecida, pero me parece una chapuza cambiar de micro porque el trasmisor no vaya (sería una chapuza para arreglar otra), así que me estoy buscando un transceiver a 2.4Ghz :(, al menos a esa frecuencia las antenas son más baratas, pequeñas y de más ganancia
¿que tal irá a 2.4ghz en un tunel?
Bueno, el radiocsafts 2500hp vá bien a 2.4ghz y 19200 bps, aunque tengo un problema: al trasmitir siempre el mismo dato sin parar, a veces se hace un lio:
En vez de 0x7F lee 0xFD,
En vez de 0x71 sale 0xC5
Se vé que se salta 2 bits.
Mejora algo si cada 10 bytes no trasmito uno para que resintonice al principio
¿cual será la mejor manera de solucionarlo?
1. Poner bit de paridad
2. Poner 2 bits de stop
3.
Si el problema es la sincronización puedes poner paridad impar, peor las tramas seguirán siendo iguales.
Lo que ganas es qe con 0h no manda todo ceros...
Manda un número de série de trama para que siempre haya un dato distinto.
Haz un mini protocolo al estilo STX LONGITUD NUMEROSERIE DATOS CRC EOT y asi siempre serán distintas y con garantía de recepción. Y si es bidireccional puedes contestar con ACK o NAK si esta mal el CRC, si no solo descartas las tramas con CRC incorrecto.
MAs sofisticado es usar códigos ECC (con corrección de errores http://en.wikipedia.org/wiki/Error_detection_and_correction " onclick="window.open(this.href);return false;) como el BCH o similar, pero necesitas mas potencia de cálculo y las tramas crecen..