Forum: Mikrocontroller und Digitale Elektronik UART von einem PIC24F zu einem PIC16F


von Marc O. (marcosfs)


Lesenswert?

Hey zusammen,

ich arbeite zur Zeit an der Programmierung einer seriellen Verbindung 
über UART zwischen einem PIC24FJ64GB004 und einem PIC16F627A. Die 
Übertragung geht ausschließlich vom PIC24F aus zum PIC16F. Ganz 
einfaches 8-Bit-Datenfeld mit einem Stop-Bit, ohne Parity, vom PIC24F 
aus über das U1-Modul, ohne U1RTS oder U1CTS. Baud-Rate ist 9600kb/s.

Ich benutze die Software "Labcenter Proteus" für Simulationen, und die 
Kommunikation funktioniert auf der Simulation super. Auf der Software 
reagiert der PIC16F richtig auf die Befehle, die vom PIC24F aus 
geschickt werden, und der Virtual Terminal, den ich auch noch in der 
Software dazu geschaltet habe, zeigt mir die richtige Chars.

Wir haben nun die Schaltung zusammengelötet, und es funktioniert nicht. 
Elektronisch haben wir alles überprüft, es stimmt alles, nix 
kurzgeschloßen oder so. Mit dem PICKit 3 haben wir auch schon debuggt, 
und an der Sockel vom PIC16F mit dem Oszilloskop die zwei geschickten 
Chars (die man in Form von Bytes abliest) überprüft, ohne dass der 
PIC16F in der Sockel drin war. Der Oszilloskop meldet was ganz falsches! 
Wenn wir den PIC16F in der Sockel haben, empfängt er die "falsche" 
Nachricht und reagiert "richtig" auf sie, wir schließen einen Fehler 
beim Empfang des PIC16 deswegen praktisch aus.

Hier die Register-Einstellungen beim PIC24F:
/* UART-EINSTELLUNGEN: Siehe Seite 192-195 von Datenblatt */
    IEC0bits.U1TXIE = 0;        //Interrupt für Uebertragung disabled
    IEC0bits.U1RXIE = 0;        //Kein Empfang-Interrupt aktiviert
    U1MODEbits.USIDL = 0;       //Weiter betreiben in Idle-Modus
    U1MODEbits.IREN = 1;        //Kein Infra-Rot-Modul fuer UART
    U1MODEbits.RTSMD = 0;       //Hier egal, weil Pin URTS nicht benutzt 
(unten)
    U1MODEbits.UEN = 0b00;      //Nur U1TX und U1RX aktiviert, UCTS/URTS 
intern
    U1MODEbits.WAKE = 0;        //Kein Wake-Up von Sleep-Modus
    U1MODEbits.LPBACK = 0;      //Kein Loopback-Modus
    U1MODEbits.ABAUD = 0;       //Keine Baud-Rate Messung
    U1MODEbits.RXINV = 0;       //Kein Empfang von Reverse-Polarity-Bit
    U1MODEbits.BRGH = 0;        //Kein High Speed Baud-Rate Generator
    U1MODEbits.PDSEL = 0b00;    //Keine Parity-Bits
    U1MODEbits.STSEL = 0;       //1 Stop Bit
    //Flexible Peripherie-Pins siehe 10.4 auf Datenblatt.
    RPOR9bits.RP19R = 3;    //RP19 (RC3) gewaehlt als U1TX-Bein
    U1BRG = 103;                //Formel auf Datenblatt fuer BRGH = 0 
(kein high speed), 9,6kb/s Baud-Rate

    U1STAbits.UTXISEL0 = 1;     //Interrupt: siehe Datenblatt.
    U1STAbits.UTXISEL1 = 0;
    U1STAbits.UTXINV = 0;       //Infra-Rot Polarity Inversion disabled
    U1STAbits.UTXBRK = 0;       //Synchronisierter Break-Bit disabled
    U1STAbits.ADDEN = 0;        //Address-Detect disabled
    U1MODEbits.UARTEN = 1;      //UART AKTIVIERT!
    U1STAbits.UTXEN = 1;        //Transmit enabled
    IFS0bits.U1TXIF = 0;


Beim schicken, machen wir so:


    while(!U1STAbits.TRMT);
    U1TXREG = befehl_1;
    waitXms(1);

    while(!U1STAbits.TRMT);
    U1TXREG = befehl_2;
    waitXms(1);



Diese waitXms(1) Funktion ist woanders definiert und tut schon richtig. 
Befehl_1 und Befehl_2 sind Variabeln die wo anders ihren Wert erhalten. 
Die sind einzelne Chars, z.B. '0' oder '1' (entspr. 48 bzw. 49 in der 
ASCII-Tabelle).

Was könnte das Problem sein? Wir dachten vielleicht schickt er was 
falsches hin weil wir den PIC24F mit dem PICKit 3 versorgen und 
debuggen, und die serielle Kommunikation zwischen den zwei 
beeinträchtigt die restliche serielle Kommunikation. Tut's vllt richtig 
wenn man vom Akku+Spannungsregler versorgt?

Die Baud-Rates stimmen schon überein, sogar mit der exakt gleichen 
Abweichung, wie man den Datenblättern entnehmen kann. Der PIC24F wird 
von einem externen 32MHz-Quarz, der PIC16F von seinem internen 4MHz 
Oszillator getaktet. Wie gesagt, Simulation tut richtig, Schaltung aber 
nicht =( Wir denken nicht, dass es dran liegt, dass der interne 4MHz 
Oszi vom PIC16f einfach schlecht ist, weil er wie gesagt "richtig" auf 
die falsch geschickten Chars reagiert. Der PIC24F schickt z.B. laut 
Oszilloskop "157", wo der geschickte Char dem Byte "48" entsprechen 
sollte (nach ASCII).

Natürlich, wenn wir da was richtig mega falsches in den Einstellungen 
haben, bitte auch das melden ^^

Jemand Erfahrung mit typischen Problemen des UARTs beim PIC24f?

Cheers

von spontan (Gast)


Lesenswert?

>empfängt er die "falsche" Nachricht und reagiert "richtig" auf sie, ..

Wie ist denn das zu verstehen?
Wieso ist die nachricht "falsch", was lest ihr am Oszi ab? Was wäre 
richtig?
Was heißt "richtig" reagieren?

Wo ist oberhaupt der Fehler, wenn der µC richtig reagiert?

von Marc O. (marcosfs)


Lesenswert?

OK, Deutsch ist nicht meine Muttersprache, sorry wenn etwas nicht so 
eindeutig klingt. Also wir schicken im Programm z.B. ne '0'. Dieses Char 
entspricht laut ASCII-Tabellen die Zahl 48. Wir sollten im Oszilloskop 
also diese 48 als high-low-Muster sehen können. Wir sehen da aber eine 
157, also das Datenfeld ist irgendwie versaut. Ein Stop-Bit und die 
eingebaute 1ms zwischen Befehlen ist jedoch immer drin.

Was ich meine mit "richtig" und "falsch" ist, dass wir den PIC16F zum 
"debuggen" so programmiert haben, dass er eine LED so oft blinken soll, 
wie die Zahl, der das geschickte Char entspricht. D.h. zur empfangenen 
'0' sollte er 48 Mal blinken. Er blinkt aber 157 Mal - genau die Zahl, 
die vom Oszilloskop abzulesen ist. Also: der PIC16F reagiert richtig auf 
ein Char, das er vom PIC24F bekommt. Der PIC24F hätte aber nicht dieses 
Char schicken sollen, also ist es eine richtige Reaktion auf ein im 
PIC24F versautes Datenfeld. Jetzt?

von Bronco (Gast)


Lesenswert?

Taktfrequenz vom PIC24? Config Register richtig gesetzt?
Laß doch mal einen Pin mit einer Sollfrequenz toggeln und miß mit dem 
Oszi nach.
Ansonsten sieht Dein Code gut aus.
Ich erinnere mich noch, daß UTXEN nach UARTEN gesetzt werden muß, aber 
das ist richtig bei Dir.

von Marc O. (marcosfs)


Lesenswert?

Nur noch zur Korrektur, unser IREN ist nicht aktiviert, das war nur ein 
Test, um zu kucken, ob das noch größere Fehler verursachen würde. Normal 
haben wir IREN = 0

von Marc O. (marcosfs)


Lesenswert?

Hallo zusammen,

falls jemand dieses Thread sich wieder anschaut, wir haben das Problem 
entdeckt, und zwar, anscheinend funktioniert die serielle Kommunikation 
NICHT, WENN MAN DEN uC GERADE MIT DEM PICKIT 3 PROGRAMMIERT/DEBUGGT. 
Sobald wir die Versorgung fertig gelötet haben und den PICKit 3 nicht 
mehr als Versorgung benutzt haben, ging das UART wieder. Der PIC16f 
reagiert zwar trotzdem komisch, aber am Oszi sehen wir auf jeden Fall 
schon 48 und 49, was '0' bzw. '1' entspricht und schon mal richtig ist.

Falls jemand noch Fragen/Anregungen hat, wir arbeiten gerade an einem 
Mini-Roboter, und lernen unheimlich viel über die beiden PICs was 
anderen nützlich sein könnte ^^

Cheers

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.