UART löst keinen Interrupt aus?

Gast #2851544
Lesenswert?

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
Gast #2851563
Lesenswert?

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.
Gast #2851597
Lesenswert?

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
}
Gast #2851626
Lesenswert?

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.
#2851635
Lesenswert?

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.
Gast #2851636
Lesenswert?

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?
Gast #2851639
Lesenswert?

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.
Gast #2851644
Lesenswert?

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.
Gast #2851679
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren