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
voidUART_ISR1(void)interrupt16
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??
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
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
voidTimer0Overflow(void)interrupt1
2
voidTimer1Overflow(void)interrupt3
3
voidUART_ISR0(void)interrupt4
4
voidUART_ISR1(void)interrupt16
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
voidUART_ISR1(void)interrupt12
oder etwa nicht?
Der gaze Code ist übrigens für den Keil-C geschrieben worden.
Hegy wrote:
> Daher müßte es doch eigentlich heißen>
1
voidUART_ISR1(void)interrupt12
> 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
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
voidISR5(void)interrupt5
2
{}
3
voidISR8(void)interrupt8
4
{}
5
voidISR9(void)interrupt9
6
{}
7
usw.
oder ähnliche Funktionskonstrukte? Oder gibt es eine Funktion, in die
alle ungenutzten Interrupts quasi vereint, wie es beim avr-gcc geht?