Forum: Mikrocontroller und Digitale Elektronik C517: Interruptquelle unbekannt


von Hegy (Gast)


Lesenswert?

Hallo,

vor einiger Zeit habe ich schonmal rumgegrübelt, warum ein C517 (oder 
C515, C509) nicht feststellen kann, was ein Interrupt ausgelöst hat. 
Dazu habe ich in der ISR an 3 Stellen Befehle eingefügt, die jeweils 
LED's einschalten. Aber nix ist passiert, außer daß die "ISR-Entry"-LED 
eingeschaltet wurde. Ich hatte eher den Eindruck, daß ein IRQ 
aufgetreten ist, aber kein entsprechendes Bit im S1CON-Register gesetzt 
wurde. Was läuft nicht richtig? Wichtig in dem Zusammenhang ist wohl 
auch die Tatsache, daß RxD und TxD über einen 2-Draht-1-Draht Konverter 
kommunikationsmäßig zusammenhängen, d.h. was über Tx rausgeht kommt bei 
Rx gleich wieder rein. Aber in diesem Fall kommt nur was über Rx rein, 
weil der C517 nichts ausgegeben hat.
1
#define IsBit(value, mask)  ((value) & (mask))
2
3
// voreingestellt:
4
// LED's an P5 alle aus
5
6
void UART_ISR1(void) interrupt 16
7
{
8
  P5 = 0x01; // wenn ISR, dann LED an -> ok, funxoniert
9
  // Sende-IRQ?
10
  if(IsBit(S1CON, TI1_BIT))
11
  {
12
    P5 = 0x03; // 2 LED's an 
13
    ClrBit(S1CON, TI1_BIT);
14
    // TxConf: Empf. wieder zuschalten
15
    SetBit(S1CON, REN1_BIT);
16
    UART_TxConf1(); // Sendepause für X ms
17
  }
18
19
  // Empfangs-IRQ? Warum läuft das Proggi bei Datenempfang nicht in diese if-Kiste??
20
  if(IsBit(S1CON, RI1_BIT))
21
  {
22
    P5 = 0x05; // 2 LED's an
23
    // Empf. war ein
24
    Uart1Receive(S1BUF);    // Datenbyte wegspeichern
25
    ClrBit(S1CON, RI1_BIT); // RI-Bit resetten
26
  }
27
}
Ratlos
   Hegy

von Peter D. (peda)


Lesenswert?

Warscheinlich hast Du noch nen anderen Interrupt freigegeben, ohne einen 
Handler dafür geschrieben zu haben.

Dann läuft dieser einfach in den nachfolgenden Handler rein und der 
wundert sich dann, wieso er aufgerufen wurde.


Peter

von Hegy (Gast)


Lesenswert?

Gerade bei durchforsten der Doku mit der Freigabe irgendeines anderen 
Interrupts ist mir folgendes aufgefallen (Datenbladl v. C509, S. 216, 
Tabelle 7-3, Interrupt Sources and Vektors), in der Tabelle steht:

Int. Source         Int. Vector Addr.
-----------------+-------------------+-
Ext. Interrupt 0   0003  (= "interrupt 0"?)
Timer 0 Ovfl.      000B  (= "interrupt 1"?)
Ext. Interrupt 1   0013  (= "interrupt 2"?)
Timer 1 Ovfl.      001B  (= "interrupt 3"?)
Serial Channel 0   0023  (= "interrupt 4"?)
usw. (7 Einträge)  ....
Serial Channel 1   0083  (= "interrupt 16"?)

Im Code stehen folgende ISR-Aufrufe:
1
void Timer0Overflow(void) interrupt 1
2
void Timer1Overflow(void) interrupt 3
3
void UART_ISR0(void) interrupt 4
4
void UART_ISR1(void) interrupt 16
Verglichen mit der Tabelle ergibt sich für mich folgender Zusammenhang, 
keine Ahnung ob das korrekt ist:

Timer 0 Overflow ist "interrupt 1", weil dieser an 2. Stelle in der 
Tabelle steht, die nach Vektor-Adressen sortiert ist. Also ist die erste 
Einsprungadresse "interrupt 0" (Ext. Interrupt 0). Zähle ich weiter, ist 
"interrupt 3" dann auch Timer 1 Overflow. Kurzum, meine Annahme deckt 
sich mit der Tabelle. ABER, dann past das nicht mit dem "interrupt 16" 
für Serial Channel 1, da dieser an 13. Stelle in der Tabelle steht. 
Daher müßte es doch eigentlich heißen
1
void UART_ISR1(void) interrupt 12
oder etwa nicht?

Der gaze Code ist übrigens für den Keil-C geschrieben worden.

von Peter D. (peda)


Lesenswert?

Hegy wrote:
> Daher müßte es doch eigentlich heißen
>
1
void UART_ISR1(void) interrupt 12
> oder etwa nicht?

Paßt schon:

0x83 / 8 = 16

Setz mal nen Handler für Interrupt 15 auf, der ne LED setzt und ne 
Endlosschleife macht.
Der sollte dann nie aufgerufen werden, wenn alles stimmt.


Peter

von Hegy (Gast)


Lesenswert?

Warum wird die Adresse durch 8 geteilt?

Wenn so die Werte für die ISR-Funktionen "void ISR(void) interrupt 16" 
berechnet werden, gibt es lt. Datenblatt vom C509 keinen Interrupt 15. 
Der nächste untendrunter ist 13 für external Interrupt 6, und da ist der 
Pin 6 des C509 für zuständig (P1.3, CC3, INT6). Grade mal wieder den 
Code durchgekramt und festgestellt, daß nur am IEN2 Register 
rumgeschraubt wird (ES1 wird auf 1 gestzt). An IEN1 wird nix gemacht, 
also Default-Wert = 0 = externer Int. 6 aus. Bleibt nur noch CC3. Dies 
hängt mit CC0 bis CC3 unter einer Decke und kann mit CCEN abgeschaltet 
werden, bzw. aktiviert werden. Default-Wert auch hier wieder 0, also 
alle CC[0..3] aus.

Da nur die Interrupts 1, 3, 4 und 16 verwendet werden, müßte ich, um die 
Sache einfach mal abzukürzen, für die Interrupts 5 bis 15, eine ISR 
bauen, die dann jeweils eine LED setzt, vorzugsweise in jeder ISR eine 
andere, und dann die Endlosschleife. Das wären dann die Interrupts 5, 8, 
9, 10, 11, 12 und 13, danach kommt schon 16 für UART1.

Wird denn vom Keil-C kein direkter Rücksprung für nicht definierte ISR's 
eingebaut, also so Teile wie
1
void ISR5(void) interrupt 5
2
{}
3
void ISR8(void) interrupt 8
4
{}
5
void ISR9(void) interrupt 9
6
{}
7
usw.
oder ähnliche Funktionskonstrukte? Oder gibt es eine Funktion, in die 
alle ungenutzten Interrupts quasi vereint, wie es beim avr-gcc geht?
1
void unusedISRs(void) interrupt all_unused
2
{
3
  // insert your code here
4
}

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.