fbpx

Expresate

Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:

Avisos
Vaciar todo

Problema en UART de dspic30f leyendo 0x7F

16 Respuestas
4 Usuarios
0 Reactions
20.1 K Visitas
fusion
Respuestas: 391
Topic starter
(@fusion)
Ardero
Registrado: hace 17 años

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 =========
}

Responder
15 respuestas
dragonet80
Respuestas: 1328
(@dragonet80)
Ardero
Registrado: hace 17 años

dsPIC30F hay unos cuantos, ¿cual usas tú en concreto?

Si quieres saber si es un "bug" reconocido, mirate el errata-datasheet del micro en concreto.

Ahora no puedo estudiar el código, pero si cambias el 0x7F en el "if" por cualquier otra cosa, ¿sigue fallando al recibir 0x7F o falla al recibir lo que hayas puesto? ¿Lo puedes probar a ver?

Y, exactamente, ¿cual es el fallo que se produce?

Responder
fusion
Respuestas: 391
Topic starter
(@fusion)
Ardero
Registrado: hace 17 años

Es un dspic30f3013, pero el modelo me parece que da lo mismo pues todos tienen la misma uart. Podría probar con un 33f que tiene el mismo número de patas, a ver si coinciden (aunque me dá que fallará también).

El fallo que produce es que le mando continuamente 0x7F 0x7F .... y recibo 0x7F 0xBF 0xFF etc. Solo el 50% de las veces recibo 0x7F. Sin embargo el lector USB-RS232 que he puesto en paralelo lee bien desde labview.
El led que enciendo y apago sirve para ver si es un fallo en recepción o en trasmisión, y lo veo encendido el 50% de las veces, o sea que es de recepción.
Voy a intentar ahora a emplear la UART-1, que como es la que usa el pic para programarse espero no tenga ese problema.
Para no interferir con los pines de programación usaré los pines ATX y ARX alternativos haciendo U1MODEbits.ALTIO = 1;

Responder
fusion
Respuestas: 391
Topic starter
(@fusion)
Ardero
Registrado: hace 17 años

Gracias dragonet por los esfuerzos,
Buscando un poco más me he dado cuenta de que hay que poner en emisor dos bits de stop y en RS232 que tengo conectado en paralelo hay que poner 1.5 bits de stop. El caso es que el pic solo permite 1 o 2. He intentado poner un delay de medio bit antes de trasmitir en el pic y no sirve.
Me parece que debe haber algún problema de reloj. Quisiera emplear un PLL de 4 u 8 con un oscilador externo, ¿es este el comando adecuado?:

_FOSC(CSW_FSCM_OFF & XT_PLL8 ); // Fosc=8x7.3728MHz, Fcy=2x7.3728MHz

Responder
heli
Respuestas: 748
 Heli
(@heli)
Ardero
Registrado: hace 19 años

Veo que ya tienes casi acorralado el problema...
Seguro que es un problema de sincronización de las tramas. Si lo programas a 2 bits de stop debes hacer lo mismo con los demas dispositivos... si tienes que poner 1,5 bits de stop es que la frecuencia de reloj del PIC que emite es incorrecta y no puede generar un baudrate exacto.
Lo primero puede ser por fallos o deriva en el cristal.
Lo segundo puede ser un problema de diseño... una mala elección de la frecuencia del cristal hace que algunos baudrates tengan demasiada deriva respecto de la velocidad nominal, pero creo que con tu cristal salen todas exactas.

Luego hay UARTs que sincronizan mejor que otras... puede que con DSpic no recibas y con Atmel si...

U2BRG = Fcy/BAUDRATE/16-1; // 38400 baud ¿Como debe calcularse?
(Fcy/BAUDRATE/16)-1 o Fcy/BAUDRATE/(16-1);

Responder
Página 1 / 4
Compartir: