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
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?
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.
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
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
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.
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
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
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.
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.
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.