Problem mit EUSART pic16F18877 im asynchronen Modus

Ich versuche, eine Kommunikation mit dem EUSART des pic16F18877 aufzubauen, aber bisher ohne Erfolg. Nachdem ich einige Kommentare erhalten hatte, nahm ich einige Änderungen an der Funktion RxChar() vor.

Vom Computer sende ich 0xFE05 über eine USB-zu-TTL-Schnittstelle (USB an RS232 TTL PL2303HX) an den Controller. Ein serieller Monitor dazwischen zeigt keine Fehler. Das Sendezeichen geht korrekt aus. Auf der Seite des Mikrocontrollers erhalte ich immer wieder Rahmenfehler.

Ich versuche immer noch, die EUSART zum Laufen zu bringen. Bisher ohne Erfolg. Um herauszufinden, woher das Problem kommt, bin ich zur ursprünglichen Hex-Datei (Code in Basic) zurückgekehrt, um die möglichen Fehlerquellen zu reduzieren. Das Originalprogramm ist für den pic16F887A geschrieben und nach der Programmierung des PIC16F877A funktioniert die serielle Kommunikation korrekt. Die serielle Kommunikation für den PIC16F877A muss in einer Bibliothek sein, da ich sie nicht im Basiscode finden kann. Es werden nur die Port- und Baud-Definitionen angegeben.

Dies lässt mich glauben, dass das Problem irgendwo in den Einstellungen oder im Code meines Projekts mit dem PIC16F18877 liegen muss. Aber bisher habe ich keine Ahnung. Jede Hilfestellung zum weiteren Vorgehen ist willkommen.

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  
    }
}
Ihre erste Codezeile "deaktiviert" den Port nicht, wie Ihr Kommentar sagt, dass es sollte ...
@brhans Kopierfehler. Ergebnis unverändert
Warum setzen Sie die Interrupt-Flags auf 0? Das solltest du nicht tun. Und Sie haben nicht gezeigt, wie das alles verwendet wird
Stellen Sie sicher, dass Sie die Fehler-Flags des UART löschen - insbesondere OERR. Außerdem, wie Eugene bemerkt hat, sollten/müssen Sie die Interrupt-Flags nicht löschen - sie sind ohnehin schreibgeschützt.
Ich schaue es mir an und nehme die Änderungen vor und komme mit einer Antwort. Bisher versuche ich nur einen Char zu empfangen. Im externen seriellen Monitor wird das Zeichen angezeigt. In RCREG nicht.
@EugenSch. Ich habe meine Frage mit weiteren Informationen aktualisiert. Können Sie helfen?
@brhans. Ich habe meine Frage mit weiteren Informationen aktualisiert. Können Sie helfen?
Rahmenfehler weisen auf ein wahrscheinliches Problem mit der Baudrate hin, aber Ihre Baudrateneinstellung sieht in Ordnung aus. Damit bleibt Ihre Uhr. Sind Sie sicher, dass Sie es richtig für 20 MHz konfiguriert haben?
@brhans #pragma config FEXTOSC = HS ; _XTAL_FREQ = 20000000.
- und sind Sie sicher, dass Ihr Quarz wirklich mit 20MHz schwingt? Wenn Sie nicht direkt prüfen können, können Sie einen Timer einrichten, um einen Pin umzuschalten und daraus die Oszillatorfrequenz abzuleiten. Probieren Sie vielleicht einen anderen Quarz und/oder eine andere Frequenz aus (und passen Sie SPBRG entsprechend an). Wenn Sie ein Byte vom PIC übertragen, können Sie es auf dem PC empfangen (und/oder das Bit-Timing auf einem Oszilloskop betrachten)?
XTAL usw. müssen ok sein. Beim PIC16F877A habe ich nur den Mikrocontroller geändert. Das funktioniert
@brhans. Fehler gefunden. Siehe meine Antwort

Antworten (1)

Nach einem sorgfältigen erneuten Lesen des Codes und Neukompilieren entdeckte ich, wo der Fehler gemacht wurde. Ich wurde durch die Informationen in Tabelle 33-4 in die Irre geführt, wo SPBRG = 520 in Kombination mit SYNC = 0; BRGH=1 und BRG16= 1; Dieser Dezimalwert kann in diesem Format nicht verwendet werden.

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

Nach der Neukompilierung und dem Testen stellte ich fest, dass die Informationen korrekt durchkamen; Zeit also, mit dem Rest des Programms fortzufahren.