Forum: Mikrocontroller und Digitale Elektronik Umstieg PIC16F873 -> PIC16F1938 : Probleme mit serieller Kommunikation


von Stefan (netfriend)


Lesenswert?

Hallo,

ich bin dabei, vom PIC16F873 auf den PIC16F1938 umzusteigen. Nun habe 
ich ein bereits lauffähiges Programm vom 16F873 auf den 16F1938 
übertragen. Vorher habe die Initalisierung der Register entsprechend 
angepasst.
Ich verwende MPLAB 8.80 und den CC5X-Compiler.

Kommunizieren möchte ich mit 9600 Baud. Hardwareseitig ist ein 4 
MHz-Quarz verbaut.

Mein Problem ist folgendes:

Von einem PC empfange ich ein 8 Byte großes Telegramm. Wenn dieses 
Telegramm dem PIC bekannt ist, sendet er ein 0x06 zurück. Bei 
unbekannten Telegrammen ein 0x15.
Je nach Telegramm schaltet er Ausgänge, fragt Eingänge ab oder sendet 
Messwerte zurück an den PC. Dies tut aber im Moment noch nichts zur 
Sache, denn soweit komme ich gar nicht. Es scheitert schon an dem 
zurücksenden von 0x06 bzw. 0x15.
Auf der alten Hardware mit dem 16F873 klappt das einwandfrei.

Beim 16F1938 erhalte ich am PC anstatt 0x06 ein 0x3F. Nach wenigen 
Kommunikationsversuchen erhalte ich gar keine Antwort mehr.

Ich befürchte dass ich bei der Initialisierung der Register irgendetwas 
übersehen oder fehlinterpretiert habe - finde jedoch nichts.

Meine EUSART-Initialisierung sieht wie folgt aus:
16F873:
//USART
TX9=0;  //8-Bit
TXEN=0;  //Transmit enabled (1) / disabled (0)
SYNC=0;  //Asynchronous-Mode
BRGH=1;  //High Baud Rate Select Bit
TX9D=0;  //9th Bit auf Transmit Datat

SPEN=1;  //Serial Port Enable Bit
RX9=0;  //9-Bit Receive Enable Bit (1=9 Bit / 0=8 Bit)
CREN=1;  //Continous Receive Enable Bit (1=enable / 0=disable)

//Baudrate lt. Tabelle einstellen
SPBRG = 25; // 25:  9600 (9615) Baud @ 4 MHz

und für den 16F1938:
//USART
TX9=0;  // 8-Bit
TXEN=0;  // Transmit enabled (1) / disabled (0)
SYNC=0;  // Asynchronous-Mode
BRGH=1;  // High Baud Rate Select Bit
TX9D=0;  // 9th Bit auf Transmit Datat

SPEN=1;  // Serial Port Enable Bit
RX9=0;  // 9-Bit Receive Enable Bit (1=9 Bit / 0=8 Bit)
CREN=1;  // Continous Receive Enable Bit (1=enable / 0=disable)

//BAUDCON - Baudrate lt. Tabelle einstellen  (S.300)
BRG16=0;  // BaudRate-Generator (1=16-bit / 0=8-bit - Baude Rate 
Generator)
WUE=0;  // Wake-up Enable bit (1= Receiver is waitung for a falling 
edge, .... / 0=Operation normally)
SPBRGH = 0;
SPBRGL = 25;// 25: 9600 (9615) Baud @ 4 MHz


Hat jemand eine Idee, woran das liegen könnte. Oder einen 
Gedankenanstoss für mich....

Danke,
Stefan

von FfF (Gast)


Lesenswert?

frag mal bei fernando-heitor.de, da sitzen die PIC-Cracks

von Jörg S. (joerg-s)


Lesenswert?

Ich würde erst mal mit was leichten anfangen. Also erst mal ganz 
bestimmte Bytes bzw. ein String zum PC senden. Kommt dann wenn du z.B. 
ein 'A' sendest schon kein 'A' an, ist abzusehen das was mit der Baurate 
nicht stimmt. Wenn du ein Oszi hast, sollte man sich das gesendete dann 
auch mal ansehen.

Wie ist die Hardware zum PC aufgebaut, gibt's noch einen RS232 Wandler?

von W.S. (Gast)


Lesenswert?

Net Friend schrieb:
> Hat jemand eine Idee,

Naja, erstmal ein paar Fragen:
Wie betreibst du die serielle Schnittstelle? Also ob du schlichtweg ohne 
Interrupts arbeitest oder mit Interrupts und Ringbuffer für In und Out.
Mir sieht das nämlich danach aus, daß du den Sender schlichtweg 
überfährst, weil du irgendein Flag übersiehst oder ignorierst.

Mach doch erstmal folgendes:
Sende hintereinander einen länglichen Text (sagen wir mal 10 Zeilen mit 
was Leserlichem), den du kennst und warte dann ne angemessene Zeit, 
sagen wir mal 2 Sekunden per Trampelschleife. Anschließend dasselbe ad 
ultimo. Dann guck dir per Hyperterminal an, was dabei herauskommt. Wenn 
Murks, dann ne Trampelschleife nach jedem Zeichen, bis es klar 
rüberkommt und dann natürlich die Fehlersuche in den 
Zeichen-Ausgaberoutinen.

W.S.

von Hermann U. (Firma: www.pcb-devboards.de) (gera82)


Lesenswert?

Net Friend schrieb:
> Hat jemand eine Idee, woran das liegen könnte. Oder einen
> Gedankenanstoss für mich....

Oszi muss her, ohne wird es ganz schwierig.. Einzelne Bits vergleichen, 
stimmt die Transferrate etc..

Gruß
Hermann

von Stefan (netfriend)


Lesenswert?

Da das ganze Programm auf dem 16F873 schon einwandfrei funktioniert, war 
ich der Meinung man könne das relativ einfach auf den 16F1938 
übertragen.
Das Programm sollte 1:1 laufen, wenn der PIC genauso konfiguriert ist. 
Deshalb denke ich das hier mein Problem liegt.

Es ist ein RS232-Wandler dazwischen, der ganze Weg funktioniert.
Beim Empfang arbeite ich mit Interrupts, die byteweise abgespeichert 
werden. Das Telegramm ist max. 8 Byte groß, deshalb recht übersichtlich. 
Nachdem ich dieses mit einem Terminalprogramm sende, kommt auch nur das 
eine Telegramm an und keine weiteren. Das Ganze funktioniert eine 
gewisse Zeit, dann komme ich anstatt 8mal nur noch 5mal in den Interrupt 
wenn ich ein Telegramm empfange (mit Pin wackeln und Oszi überprüft). 
Das Telegramm liegt aber vollständig am RX-Pin des PIC an. Irgendwas 
scheint zu passieren, so dass der PIC nicht mehr in den Interrupt kommt 
(es fehlen zwischendrin 3 Einsprünge in den Interrupt). Nach einem 
Neustart geht alles wieder - für eine gewisse Zeit.

Beim Senden arbeite ich ohne Interrupt, da ich eh nur ein Byte sende:

  TXEN=1;
  TXREG=0x06;
  while(!TRMT);
  TXEN=0;

Der PC empfängt aber immer 0x3F - jedenfalls zeigt das das 
Terminalprogamm an.

Gruß,
Stefan

von Scotty (Gast)


Lesenswert?

OSCCON und CONFIG1 überprüfen. Vermutlich läuft er mit einem anderen 
internen Takt anstatt der gewünschten 4 MHz.
Man könnte CLKOUTEN = 0 machen und an dem entsprechend Pin mit dem Oszi 
nachsehen.
Ich verwende bei meinen Basteleien schon lange keinen externen Quarz 
mehr. Die internen Taktgeber sind völlig ausreichend, auch für UART.

von Stefan (netfriend)


Angehängte Dateien:

Lesenswert?

Hallo,

habe jetzt mein Programm stark vereinfacht.
Es wird nur 1 Byte vom PC gesendet - dieses wird auch am PIC empfangen. 
Sprich der Interrupt wird durchlaufen, das Byte in einer Variablen 
gespeichert und in der main-loop auf das Display geschrieben.

Wenn ich nun 1 Byte vom PIC sende, erhalte ich am Terminal-Programm 
immer 0x3f - egal was ich sende (lediglich wenn ich 0x00 sende, erhalte 
ich auch 0x00).

Nun habe ich mir das Signal direkt am TX-Pin des PIC angesehen und hier 
scheint mir das Problem zu sein, dass der PIC nicht wie erwartet seinen 
Ruhepegel bei 5V hat. Der Pegel liegt bei 0V und erst wenn gesendet 
werden soll, steigt dieser kurz auf 5V, überträgt das Byte und fällt 
wieder auf 0V ab.

Das selbe habe ich nun mit dem bisherigen PIC16F873 durchgeführt. Hier 
liegt der TX-Ruhepegel wie erwartet auf 5V und nach dem Senden liegt 
dieser auch wieder auf 5V.

Im angehängten Screenshot sieht man das deutlich.
Die UART-Initialisierung habe ich mehrmals geprüft. Ich find den Fehler 
nicht.
Der externe Quarz schwingt sauber mit 4 MHz.

Hat jemand noch ne Idee?

Gruß,
Stefan

von Scotty (Gast)


Lesenswert?

SCKP-Bit in BAUDCON:

SCKP: Synchronous Clock Polarity Select bit
Asynchronous mode:
1 = Transmit inverted data to the TX/CK pin
0 = Transmit non-inverted data to the TX/CK pin

von Stefan (netfriend)


Lesenswert?

Danke, guter Hinweis.
Bisher habe ich dieses Bit gar nicht definiert.
Nun habe ich sowohl SCKP=0 als auch SCKP=1 probiert.
Komischerweise ändert das nichts an dem TX-Pegel.

von Scotty (Gast)


Lesenswert?

Das ist eigenartig.
Lass doch TXEN mal dauerhaft eingeschaltet. Gesendet wird ohnehin nur, 
wenn du etwas ins TXREG schreibst.
Würde das Senden dann so machen:
1
while(!TRMT);      // wait till previous byte is sent
2
TXREG = 0x..;      // send next byte

Weiters könntest noch prüfen, ob das entsprechende ANSEL gelöscht ist.

von Stefan (netfriend)


Lesenswert?

Wenn ich TXEN=1 bei der Initialisierung setze und nie mehr ausschalte, 
dann funktioniert es. Dann ist im Leerlauf der TX-Pegel auf 5V geht beim 
Senden entsprechend auf 0V und bleibt danach auf 5V - so wie man es 
erwartet.

Aber warum geht das Ein-/Ausschalten von TXEN vor-/nach dem Senden beim 
16F1938 nicht, während es beim 16f873 ohne Probleme funktioniert?
Das versteh ich nicht.....


Was hat es mit den ANSEL-Bit auf sich? Lt. Doku defniert man damit, ob 
ein Port analog oder digital arbeitet. Und das gibt es doch nur für 
PORTA und PORTB - die beiden RX- und TX-Ports sind RC6 und RC7.

Gruß,
Stefan

von Erich (Gast)


Lesenswert?

Du solltest bei neuen Bauteilen immer das zugehörige "Errata" gut lesen, 
vielleicht steht dort was drin.
Für deinen Bausteil findest du das mit GOOGLE über
  pic16F1938 errata
Ob konkret für dein Problem was drinsteht, schaust du bitte selbst.
Ich verwende andere Bauteile aus der pic16F1xxx Serie, und dort gibt es 
(andere) Probleme.

von Dieter W. (dds5)


Lesenswert?

Setz doch mal das Bit 6 im LATC Register auf 1, das wäre dann der 
Ruhepegel wenn man den Sender disabled.

Der 16F1938 hat auch schon die neuere I/O Port Struktur mit getrennten 
Registern für lesen (PORTX) und schreiben (LATX), das könnte auch 
Auswirkungen auf den Programmablauf haben.

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.