Problema con EUSART pic16F18877 en modo asíncrono

Estoy intentando establecer una comunicación con el EUSART del pic16F18877 pero hasta ahora no tengo éxito. Después de recibir algunos comentarios, hice algunos cambios en la función RxChar().

Desde la computadora estoy enviando 0xFE05 al controlador por medio de una interfaz usb to ttl (USB To RS232 TTL PL2303HX). Un monitor serial en el medio no muestra errores. El char de envío está saliendo correctamente. En el lado del microcontrolador, sigo recibiendo errores de trama una y otra vez.

Sigo intentando que el EUSART funcione. Sofar sin exito. Para saber de dónde viene el problema, volví al archivo hexadecimal original (código en básico) para reducir las posibles fuentes de error. El programa original está escrito para el pic16F887A y después de programar el PIC16F877A, la comunicación en serie funciona correctamente. La comunicación serial para el PIC16F877A debe estar en una librería ya que no la encuentro en el código básico. Solo se dan las definiciones de puerto y baudios.

Esto de arriba me hace creer que el problema debe estar en algún lugar de la configuración o código de mi proyecto con el PIC16F18877. Pero hasta ahora no tengo ni idea. Cualquier ayuda sobre cómo proceder es bienvenida.

fosc = 20.000000
void UART_Init(void) 
{    

    RC1STAbits.SPEN = 0;     // begin of setup disable serial port.
    // transmitter
    TX1STAbits.TXEN     = 1;    // continues transmit enable bit
    TX1STAbits.TX9      = 0;    // 8 bit transmission
    TX1STAbits.SYNC = 0;        // asynchronous operation
    ANSELCbits.ANSC6    = 0;    // digital
    TRISCbits.TRISC6    = 0;    // output

    // receiver
    RC1STAbits.CREN    = 1;   // continues receive enable bit
    RC1STAbits.RX9     = 0;
    // there is only one sync
    ANSELCbits.ANSC7   = 0;   // digital
    TRISCbits.TRISC7   = 1;   // input

    // baudrate.
    TX1STAbits.BRGH    = 1;
    BAUD1CONbits.BRG16 = 1;
    SPBRG = 520;               // baudrate 9600

    RC1STAbits.SPEN   = 1;     // end of setup enable serial port
}

void UART_TxChar(uchar ch) 
{ 
     while(TXIF==0);    
     TXREG=ch;
}

uchar UART_RxChar()
{  
    uchar Discard;
    while(1){
        while(RCIF==0);       // Wait till the data is received 
        if (RCSTAbits.FERR)
        {    
            Discard = RCREG;   Read the register and wait for the next byte
            break;
        }    
        if (RCSTAbits.OERR)
        {    
            RCSTAbits.CREN = 0;
            break;
        }
        return RCREG;   // Return the received data to calling function  
    }
}
Su primera línea de código no "deshabilita" el puerto como dice su comentario que debería ...
@brhans Copiar error. Resultado sin cambios
¿ Por qué está configurando los indicadores de interrupción en 0? No deberías hacer eso. Y no has mostrado cómo se usa todo esto
Asegúrese de borrar los indicadores de error de UART, particularmente OERR. Además, como ha señalado Eugene, no debe/no necesita borrar los indicadores de interrupción; de todos modos, son de solo lectura.
Voy a investigarlo, hago los cambios y vengo con una respuesta. Hasta ahora solo trato de recibir un char. En el monitor serial externo se muestra el personaje. En RCREG no lo hace.
@EugeneSh. Actualicé mi pregunta con más información. ¿Puedes ayudar?
@brhans. Actualicé mi pregunta con más información. ¿Puedes ayudar?
Los errores de encuadre apuntan a un posible problema de velocidad en baudios, pero su configuración de velocidad en baudios parece estar bien. Eso deja tu reloj. ¿Estás seguro de haberlo configurado correctamente para 20 MHz?
@brhans #pragma config FEXTOSC = HS ; _XTAL_FREQ = 20000000.
- y ¿estás seguro de que tu cristal realmente está oscilando a 20 MHz? Si no puede sondear directamente, puede configurar un temporizador para alternar un pin e inferir la frecuencia de osc a partir de eso. Tal vez intente con un cristal diferente y/o una frecuencia diferente (y ajuste SPBRG apropiadamente). Si transmite un byte desde el PIC, ¿puede recibirlo en la PC (y/o mirar el tiempo de bit en un 'alcance')?
XTAL, etc. debe estar bien. Para el PIC16F877A solo cambié el microcontrolador. Eso funciona
@brhans. Error encontrado. ver mi respuesta

Respuestas (1)

Después de volver a leer cuidadosamente el código y volver a compilarlo, descubrí dónde se cometió el error. Me engañó la información de la tabla 33-4 donde SPBRG = 520 en combinación con SYNC = 0; BRGH=1 y BRG16= 1; Este valor decimal no se puede utilizar en este formato.

//Therefore not: 
 SPRG = 520;
//but:
 SPBRGH = 0x02;
 SPBRGL = 0x08;

Después de recompilar y probar, descubrí que la información llegaba correctamente; Así que es hora de seguir adelante con el resto del programa.