Hallo zusammen, ich habe folgendes Problem: Ich arbeite mit dem C8051F120 schon eine lange Zeit und nie gab es Probleme mit der UART0 Schnittstelle. Jetzt habe ich mal ein komplett neues Projekt angefangen und bin der Meinung alles wichtige eingestellt zu haben, aber aus irgend einem Grund wird der Interrupt 4 für die UART0 nicht ausgelöst, wenn ich Daten an den µC sende. Folgendes habe ich alles schon Probiert: - Timer Einstellungen sind OK, für Timer 1 als Baudratengenerator für UART - Interrupt Enable Bits habe ich überprüft: ES0 = 1 und EA = 1 - Ausserdem habe ich Daten vom µC an den PC gesendet, diese kommen auch mit der eingestellten Baudrate (115200) ordentlich am PC an. Nun meine Frage an euch: Woran kann es noch liegen, dass der Interrupt nicht ausgelöst wird? Viele Grüße, Daniel
Daniel schrieb: > Nun meine Frage an euch: Woran kann es noch liegen, dass der Interrupt > nicht ausgelöst wird? An Zeile 42 Deines Programms.
Nico ... schrieb: > Allgemeine Interruptfreigabe vergessen? Eigentlich ist diese über das EA bit mit 1 gesetzt?
@ Nico > Allgemeine Interruptfreigabe vergessen? Daniel schrieb > EA = 1
Ich habe parallel dazu eine zweite Interrupt-Routine für den PCA Überlauf, diese wird in regelmäßigen Abständen auch ausgeführt.
Was ich auch noch getestet habe ist: Ich habe mal das RI0 bit in der Main-Routine auf 1 gesetzt, dann wurde der Interrupt auch ausgelöst, nur beim Empfangen von Daten über die UART wird dieses Bit aus irgend einem Grund nicht gesetzt.
Nico ... schrieb: > Löscht Du das Interrupt-Flag (RI0)? In der Interrupt-Routine ja, falls es gesetzt war - das wird vorher überprüft. Hintergrund: Bei diesem Controller wird die UART Interrupt Routine bei erfolgreichem senden und erfolgreichem empfangen aufgerufen.
Und der Empfänger ist auch wirklich aktiv? Zeig doch mal deinen Code!
Nico ... schrieb im Beitrag #2851578:
> S. 154 Dat
Nein, aber ich werds gleich mal probieren. Bisher war das eigentlich
nicht notwendig.
Den Post habe ich gelöscht, das gilt nur fürs löschen des EA-Bits!
Ok, hier mal ein bischen Code:
1 | void Timer_Init() |
2 | { |
3 | SFRPAGE = TIMER01_PAGE; |
4 | TCON = 0x40; // Timer 1 enabled |
5 | TMOD = 0x20; // Timer 1 = Mode 2: 8-bit counter/timer with auto-reload |
6 | CKCON = 0x10; // Timer 1 uses the system clock |
7 | TH1 = 0xD0; // Reloadwert: -(88473600 / 115200 / 16) |
8 | } |
9 | |
10 | void UART_Init() |
11 | { |
12 | SFRPAGE = UART0_PAGE; |
13 | SCON0 = 0x50; // Mode 1: 8-Bit UART, Variable Baud Rate |
14 | // UART0 reception enabled |
15 | |
16 | SSTA0 = 0x10; // UART0 baud rate divide-by-two disabled |
17 | } |
18 | |
19 | static void ISR_UART (void) interrupt 4 |
20 | { |
21 | if(RI0) |
22 | { |
23 | RI0=0; |
24 | } |
25 | } |
26 | |
27 | void main() |
28 | { |
29 | // Initialisierung |
30 | Init_Device(); // --> Timer_Init() & UART_Init() |
31 | |
32 | SET_SFRPAGE (LEGACY_PAGE); |
33 | ES0 = 1; |
34 | EA = 1; // Alle Interrupts einschalten |
35 | |
36 | // Main-Loop |
37 | while(1) |
38 | { |
39 | |
40 | } |
41 | } |
Was ich noch dazu sagen muss - vielleicht hilft das ja weiter - es ist ein externer CMOS mit 29,4912 MHz angeschlossen und dieser wird mit der PLL x3 multipliziert, so dass ein SYSCLK von 88473600 Hz am Timer ankommt. Hier noch der Code zur Initialisierung der PLL:
1 | void Oscillator_Init() |
2 | { |
3 | int i = 0; |
4 | SFRPAGE = CONFIG_PAGE; |
5 | OSCXCN = 0x20; |
6 | PLL0CN = 0x04; |
7 | CCH0CN &= ~0x20; |
8 | SFRPAGE = LEGACY_PAGE; |
9 | FLSCL = 0xB0; |
10 | SFRPAGE = CONFIG_PAGE; |
11 | CCH0CN |= 0x20; |
12 | PLL0CN |= 0x01; |
13 | PLL0DIV = 0x01; |
14 | PLL0FLT = 0x01; |
15 | PLL0MUL = 0x03; |
16 | for (i = 0; i < 15; i++); // Wait 5us for initialization |
17 | PLL0CN |= 0x02; |
18 | while ((PLL0CN & 0x10) == 0); |
19 | CLKSEL = 0x22; |
20 | OSCICN &= ~0x80; |
21 | } |
Wenn das Senden von Daten funktioniert, dann sind die Timer-Einstellungen ja okay! Woher weiß Du, dass kein Interrupt kommt? Du tust ja nix in der ISR!
Nico ... schrieb: > Wenn das Senden von Daten funktioniert, dann sind die > Timer-Einstellungen ja okay! > Woher weiß Du, dass kein Interrupt kommt? Du tust ja nix in der ISR! Ich hab mit dem Debug-Adapter ein Haltepunkt bei RI0 = 0; gesetzt, es wird aber niemals dort angehalten. Falls das im Debug Modus nicht funktioniert, habe ich ausserdem nach dieser Stelle mal eine LED auf der Platine eingeschaltet, das ist aber auch niemals passiert. Und wie gesagt, ich habe dieses Bit (RI0) mal von Hand auf 1 gesetzt, da hält dann auch der Code im Debug Modus an dieser Stelle an. Ich habe absolut keine Idee, was jetzt gerade schief läuft.
Frag mal Fehlerbits ab (sofern vorhanden). Nicht, dass der UART laufend Frame Error oder Parity Error produziert. Und schau dir den Assemblercode an. Möglich, dass der Compiler entscheidet, dass in der Rx Routine nichts benötigt wird und sie wegoptimiert. Der Keil ist da gnadenlos.
Nico ... schrieb: > Der Port ist auch richtig zugewiesen und verbunden? Ja ich denke schon, ich hab die Crossbar Konfiguration aus meinem alten Projekt übernommen, es ist auch die gleiche Elektronik. Und wenn ich auf diese Elektronik die alte Firmware aufspiele, funktioniert die UART auch. Ich habe schon den kompletten Code an den relevanten Stellen verglichen - er ist absolut Identisch - aber irgendwas will nicht funktionieren. Kann es eventuell sein, dass ich irgend eine Compiler-Einstellung vergessen oder übersehen habe?
Georg G. schrieb: > Frag mal Fehlerbits ab (sofern vorhanden). Nicht, dass der UART laufend > Frame Error oder Parity Error produziert. Und schau dir den > Assemblercode an. Möglich, dass der Compiler entscheidet, dass in der Rx > Routine nichts benötigt wird und sie wegoptimiert. Der Keil ist da > gnadenlos. Hallo Georg, das iss natürlich noch ne gute Idee (mit dem wegoptimieren). Das sehe ich mir gleich mal an, das kann gut möglich sein, obwohl ich im Map-File die Routine als Segment sehen kann.
Daniel schrieb: > Georg G. schrieb: >> Frag mal Fehlerbits ab (sofern vorhanden). Nicht, dass der UART laufend >> Frame Error oder Parity Error produziert. Und schau dir den >> Assemblercode an. Möglich, dass der Compiler entscheidet, dass in der Rx >> Routine nichts benötigt wird und sie wegoptimiert. Der Keil ist da >> gnadenlos. > > Hallo Georg, > > das iss natürlich noch ne gute Idee (mit dem wegoptimieren). > Das sehe ich mir gleich mal an, das kann gut möglich sein, obwohl ich im > Map-File die Routine als Segment sehen kann. also im Debug Modus ist Assembler Code für diese Routine vorhanden und Frame oder Parity Errors sind da auch keine.
Jim Meba schrieb: > Blöde Frage, aber den Watchdog hast Du ausgeschltet? Ja:
1 | void Reset_Sources_Init() |
2 | { |
3 | WDTCN = 0xDE; |
4 | WDTCN = 0xAD; // disable Watchdog |
5 | |
6 | SET_SFRPAGE (LEGACY_PAGE); |
7 | RSTSRC = RSTOPTIONS; // enable reset sources |
8 | } |
Danke an alle, die mir Tips zum suchen gegeben haben. Ich habe den Fehler jetzt gefunden. Der Tip mit dem Reset hat mich auf eine Idee gebracht. Ihr konntet das nicht wissen, aber ich will euch mal das Problem erläutern. Um in bestimmten Situationen Strom zu sparen, ist an meiner Elektronik zwischen Reset-Pin und Rx-Leitung der UART ein Schalter. Damit kann man den Controller komplett runter fahren und ihn dann über die Rx Leitung wieder aufwecken. Mein Fehler war einfach nur, dass ich vergessen habe diese Verbindung beim Initialisieren der Elektronik zu unterbrechen, somit kam nie ein Signal bis zum Controller, da dieser beim Datenemfang gleich wieder resettet wurde. Schönes Wochenende wünsche ich euch und nochmals vielen Dank. Daniel
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.