Forum: Mikrocontroller und Digitale Elektronik Timer Interrupt


von Elos (Gast)


Lesenswert?

Hallo Zusammen.

Ich Programmiere in C auf dem uC Infineon SAB-517 mit internem Takt 
(2GHz).

Ich versuche nun mit Timer und Interrupt den LED Port (P5) blinken zu 
lassen, leider klappt das nicht so wie es soll.

Hier mal der Code den ich bis jetzt verfasst habe:

1
#include <reg517.h>
2
3
4
void ISR (void)       // Interrupt Service Routine
5
{
6
int cnt;
7
8
TR1=0;                               // Timer stoppen
9
EAL=0;        // Alle Interrupts werden gesperrt
10
IEN0=0;        // Interrupt löschen
11
TH0=0x3C;        // Timer High-Bit laden  
12
TL0=0xAF;        // Timer Low-Bit laden
13
cnt++;        // Counter erhöhen
14
if (cnt==40)
15
  {
16
  P5=~P5;             // LED Port invertieren
17
  cnt=0;      // Counter zurücksetzen
18
  }
19
ET0=1;        // Interrupt zulsassen
20
EAL=1;        // Alle Interrupts freigeben
21
TR1=1;                               // Timer Starten
22
}
23
24
void IntVec (void) interrupt 0  // UP Interrupt
25
{
26
TF1=0;        // Timer overflow Flag löschen
27
ISR();        // Aufruf Interrupt Service Routine
28
}
29
30
void main (void)             // Hauptprogramm
31
{
32
int cnt=0;
33
TR1=0;        // Timer gestoppt
34
TMOD=TMOD&0xFD;      // Timer auf 16-Bit modus einstellen
35
TH0=0x3C;        // Timer High-Bit laden  
36
TL0=0xAF;        // Timer Low-Bit laden
37
TF1=0;        // Timer overflow Flag löschen
38
IEN0=0;        // Interrupt löschen
39
P5=0x00;        // LED Port loeschen
40
cnt=0;        // counter löschen
41
ET0=1;        // Interrupt freigeben
42
EAL=1;        // Alle Interrupts freigeben
43
TR1=1;        // Timer starten
44
while(1)        // Endlosschleife
45
{}
46
}


Ich hoffe ihr könnt mir den/die Fehler aufzeigen die ich gemacht habe!

Danke im voraus

Marco

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Elos schrieb:
> Ich Programmiere in C auf dem uC Infineon SAB-517 mit internem Takt
> (2GHz).
   ^^^^

Ich hoffe du nimmst es mir nicht übel, wenn ich den Wahrheitsgehalt 
dieser Angabe anzweifle  =)

Gruß,
Magnetus

von Elos (Gast)


Lesenswert?

Sorry sollte heissen MHz nicht GHz

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Mach cnt in der ISR mal static, damit zwischen zwei ISR() Aufrufen der 
Wert nicht verloren geht bzw. stets neu undefiniert ist. Das cnt in 
der main() ist witzlos/überflüssig.
1
static int cnt = 0;

von Elos (Gast)


Lesenswert?

Hab ich ausprobiert, die LED's bleiben aber nach wie vor dunkel^^

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Aber grundsätzlich gelingt es dir ein Programm zu schreiben, um die LEDs 
leuchten zu lassen?

Du hast einen Mix aus Timer 0 und Timer 1:

> TR1=0;          // Timer 1 gestoppt
> TMOD=TMOD&0xFD; // Timer auf 16-Bit modus einstellen
> TH0=0x3C;       // Timer 0 High-Bit laden
> TL0=0xAF;       // Timer 0 Low-Bit laden

Ich bezweifle auch, dass Timer0 den Interruptvektor #0 hat.

> void IntVec (void) interrupt 0  // UP Interrupt

Das ist eher der External Interrupt 0 an Adresse 0003H. Der Timer 0 
Overflow Vektor müsste Nummer 1 auf Adresse 000BH sein. der Timer 1 
Overflow liegt nochmal woanders.

Dem Rest bin ich nach den beiden Problemstellen nicht mehr nachgegangen.

von Elos (Gast)


Lesenswert?

So habs jetzt hingekriegt! Das habe ich verändert:

- cnt global initialisiert
- alles auf timer 0 angepasst
- inerruptvektor 0 auf 1 geändert
- Die interrupt service routine dirkekt mit dem overflow-flag gestartet
- anstatt das ganze INTR-enable-register zu löschen nur noch direkt das
  interrupt flag 1 gelöscht:
1
 ET1=0;
- und für die leserlichkeit die initialisierung in ein UP gepackt

hier der neue code:
1
#include <reg517.h>
2
3
int cnt;  // definition cnt als globale variable
4
5
void init (void)
6
{
7
cnt=0;    // Counter auf 0 setzen
8
TR0=0;    // Timer gestoppt
9
TMOD=TMOD&0xFD;    // Timer auf 16-Bit modus einstellen
10
TH0=0x3C;    // Timer High-Bit laden  
11
TL0=0xAF;    // Timer Low-Bit laden
12
TF0=0;      // Timer overflow Flag loeschen
13
ET1=0;      // Interrupt löschen
14
P5=0x00;    // LED Port loeschen
15
ET0=1;    // Interrupt freigeben
16
EAL=1;    // Alle Interrupts freigeben
17
TR0=1;    // Timer starten
18
}
19
20
void ISR (void) interrupt 1  // Interrupt Service Routine
21
{
22
TF0=0;
23
TR0=0;    // Timer stoppen
24
EAL=0;    // Alle Interrupts werden gesperrt
25
ET1=0;    // Interrupt loeschen
26
TH0=0x3C;  // Timer High-Bit laden  für 25ms
27
TL0=0xAF;  // Timer Low-Bit laden  für 25ms
28
cnt++;    // Counter erhöhen
29
if (cnt>=39)
30
  {
31
  P5=~P5;    // LED Port invertieren
32
  cnt=0;    // Counter zurücksetzen
33
  }
34
ET0=1;    // Interrupt zulsassen
35
EAL=1;    // Alle Interrupts freigeben
36
TR0=1;    // Timer starten
37
}
38
39
40
41
void main (void)  // Hauptprogramm
42
{
43
init();
44
while(1)  // Endlosschleife
45
{}
46
}

ein grosses dankeschön an stefan für die tolle hilfe =D

Gruss Marco

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Sehr schön!

Wenn du später cnt außerhalb der ISR benutzen willst, schreib die 
Kennzeichnung volatile bei der Definition hinzu und achte auf 
atomaren Zugriff. Mehr dazu im Artikel Interrupt.

von Elos (Gast)


Lesenswert?

jop werd ich mir merken, dankeschön

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.