Forum: Mikrocontroller und Digitale Elektronik Timer, Interrupt


von Mustafa N. (snippel9)


Lesenswert?

Aufgabe:

Ich will einen Timer Interrupt programmieren, der alle 10 ms aufgerufen 
wird und innerhalt der ISR soll bei jedem 1000. mal mein Wert 
inkrementiert werden. Das will ich mir ausgeben lassen am Terminal..
1
//======================== Einbinden von Frunktionsbibliotheken =============================//
2
3
#include <stdio.h>                    // Standard Ein-/Ausgabefunktionen
4
#include <at89C51cc03.h>             // CC03er-Grundregister
5
#include <at89C51cc03.h>            // 8051er-Grundregister
6
#include <reg51.h>                   
7
#include <irq52.h> 
8
9
//======================== Definition von Konstanten =============================//
10
    const unsigned char bit LED1  @  0x92;    // Port-Pin P1.1 (Adresse 92h) LED1 low-aktiv
11
    const unsigned char bit LED2  @  0x93;    // Port-Pin P1.2 (Adresse 93h) LED2 low-aktiv
12
    const unsigned char bit LED3  @  0x94;    // Port-Pin P1.3 (Adresse 94h) LED3 low-aktiv
13
    const unsigned char bit LED4  @  0x95;    // Port-Pin P1.4 (Adresse 95h) LED4 low-aktiv
14
    
15
    const unsigned char bit Button1  @  0x92;     // Port-Pin P1.1 (Adresse 92h) low-aktiv
16
    const unsigned char bit Button2  @  0x93;     // Port-Pin P1.2 (Adresse 93h) low-aktiv
17
    const unsigned char bit Button3  @  0x94;     // Port-Pin P1.3 (Adresse 94h) low-aktiv
18
    const unsigned char bit Button4  @  0x95;     // Port-Pin P1.4 (Adresse 95h) low-aktiv
19
20
//======================== Deklaration von Funktionen =============================//
21
22
void         initSerial(void);
23
char         receiveCharacter(void);
24
int          checkCharacter(void);
25
void         sendCharacter(char c);
26
void         pause(void);
27
unsigned int Messwertausgabe1;         // Variable zur Messwertausgabe
28
unsigned int Messwertausgabe2;         // Variable zur Messwertausgabe
29
int          i;
30
//======================== Hauptprogramm =============================//
31
32
i=0;
33
34
35
void ISR_Timer0 (void) interrupt
36
37
{
38
39
    TH0 = 0xD8;                   // Startwert
40
    TL0 = 0xF0;            
41
42
    i++;
43
    if (i == 1000)
44
    {
45
        TH0 = 0xD8+1;
46
        TL0 = 0xF0+1;
47
        printf("TH0%d\n", TH0);
48
        printf("TL0%d\n", TL0);
49
        i=0;
50
    }
51
    
52
}
53
54
void main (void)
55
56
{
57
58
    TH0 = 0xD8;                 // Startwert
59
    TL0 = 0xF0;            
60
    TMOD = TMOD | 0x01;         // Mode 1, 16-Bit-Zähler
61
    TR0 = 1;                    // Timer starten
62
63
    ET0 = 1;                    // Timer 0 Interrupt einschalten
64
    EA = 1;                     // Globale Interruptfreigabe
65
    
66
67
    while(1);
68
69
}

Der Controller ist aus der 8051 Reihe.
Der Mikrocontroller wird mit 12 MHz getaktet. Durch den Teiler von 12 
wird TL0 also jede µs inkrementiert.

Mir wird kein Fehler angezeigt, aber ich bekomme die Werte nicht 
ausgegeben.. Wo liegt der Fehler?

von Falk B. (falk)


Lesenswert?

@  Mustafa Nissan (snippel9)

>Ich will einen Timer Interrupt programmieren, der alle 10 ms aufgerufen
>wird

Das ist leicht, oder?

> und innerhalt der ISR soll bei jedem 1000. mal mein Wert
>inkrementiert werden.

Hast du ja schon drin.

> Das will ich mir ausgeben lassen am Terminal..

Dort ist der Fehler. Die Ausgabe gehört nicht in den Interrupt 
sondern in die Hauptschleife. Wie man das macht, steht im Artikel 
Interrupt.

von Mustafa N. (snippel9)


Lesenswert?

Habs mir duchgelesen und es ins main gepackt, aber dasselbe Problem 
besteht immernoch..

von Ralph S. (jjflash)


Lesenswert?

... als Ausgabe wirst du dann immer wieder (in deinen Zeitabständen) die 
Zahlenwerte 217 und 241 angezeigt bekommen, oder ?

Wenn Dein Interrupt i auf 1000 hochgezählt hast setzt du den 
(richtigerweise auf 0) zurück. Aber für die Ausgabe zeigst du nur die 
Timerbelegung (was im Interrupt "fürchterlich" ist, denn: die 
Printf-Funktion benötigt viele viele Taktzyklen, während dieser wird 
sich mindestens der Zahlenwert für TL0 geändert haben (wahrscheinlich 
auch für TH0).

Innerhalb deines Interrupts ist somit als allererstes der Nachladewert 
festzulegen ... und dann nicht mehr !!!!

Vielleicht definierst du ein paar (steinigt mich nicht) globale 
Variable, die in deinem Interrupt veränderst und die du dann in deinem 
Main ausliest !

von Mustafa N. (snippel9)


Lesenswert?

http://et-tutorials.de/4628/timer-interrupt-losung-der-aufgabe/

bei dem video hat das auch geklappt, nur wurde da P1 = P1 +1 genommen.. 
Hab das Programm identisch abgetippt und trotzdem zeigt mir das Terminal 
nix an

von Karl H. (kbuchegg)


Lesenswert?

Mustafa Nissan schrieb:

> Mir wird kein Fehler angezeigt

Echt nicht?
Das kann ich mir kaum vorstellen. Denn das hier
1
....
2
unsigned int Messwertausgabe1;         // Variable zur Messwertausgabe
3
unsigned int Messwertausgabe2;         // Variable zur Messwertausgabe
4
int          i;
5
//======================== Hauptprogramm =============================//
6
7
i=0;

ist kein gültiges C. Anweisungen sind in C nur innerhalb von Funktionen 
erlaubt.


PS: Woher weiß eigentlich dein printf, wie und wo es ausgeben soll? 
Sollte da nicht zumindest irgendwo die Aktivierung der UART bzw. die 
Einstellung der Baudrate in deinem Programm auftauchen?

von Ingo (Gast)


Lesenswert?

Mustafa Nissan schrieb:
> TH0 = 0xD8+1;
> TL0 = 0xF0+1;

Was soll das bewirken? Incrementieren bedeutet das alle 1000 x 10ms der 
Wert um 1 erhöht wird. Du hingegen addierst zu einer Konstanten nur eine 
eins hinzu.

> Wo liegt der Fehler?
Deine USART-Ausgabe evtl.?



Ingo

von Mustafa N. (snippel9)


Lesenswert?

Also ich hab versuch es mir leichet zu machen indem ich das mit einer 
LED mache.
1
//======================== Einbinden von Frunktionsbibliotheken =============================//
2
3
#include <stdio.h>                    // Standard Ein-/Ausgabefunktionen
4
#include <at89C51cc03.h>             // CC03er-Grundregister
5
#include <at89C51cc03.h>            // 8051er-Grundregister                 
6
#include <irq52.h> 
7
#include <reg51.h>
8
9
//======================== Definition von Konstanten =============================//
10
    const unsigned char bit LED1  @  0x92;    // Port-Pin P1.1 (Adresse 92h) LED1 low-aktiv
11
    const unsigned char bit LED2  @  0x93;    // Port-Pin P1.2 (Adresse 93h) LED2 low-aktiv
12
    const unsigned char bit LED3  @  0x94;    // Port-Pin P1.3 (Adresse 94h) LED3 low-aktiv
13
    const unsigned char bit LED4  @  0x95;    // Port-Pin P1.4 (Adresse 95h) LED4 low-aktiv
14
    
15
    const unsigned char bit Button1  @  0x92;     // Port-Pin P1.1 (Adresse 92h) low-aktiv
16
    const unsigned char bit Button2  @  0x93;     // Port-Pin P1.2 (Adresse 93h) low-aktiv
17
    const unsigned char bit Button3  @  0x94;     // Port-Pin P1.3 (Adresse 94h) low-aktiv
18
    const unsigned char bit Button4  @  0x95;     // Port-Pin P1.4 (Adresse 95h) low-aktiv
19
20
//======================== Hauptprogramm =============================//
21
22
int i=0;
23
24
void ISR_Timer0 (void) interrupt 
25
26
{
27
    
28
    TH0 = 0xD8;
29
    TL0 = 0xF0;
30
31
    i++;
32
    if(i == 1000)
33
    {
34
    LED1=0;
35
    i=0;
36
    }
37
   
38
}
39
40
41
void main (void)
42
43
{
44
    LED1=1;
45
    TM0D = 0x01;
46
    
47
    TH0 = 0xD8;
48
    TL0 = 0xF0;
49
    
50
    ET0 = 1;
51
    EA = 1;
52
    
53
    TR0 = 1;
54
    
55
    while(1)
56
    
57
    {
58
    }
59
60
}

Ziel: Alle 10 Sekunden soll die LED 1 kurz aufleuchten (Interrupt)

Funktioniert nicht..

von Mustafa N. (snippel9)


Lesenswert?

Jetzt kommt hinzu, dass beim 2. mal immer ein Fehler bei "  TM0D = 
0x01;" abgezeigt wird. Beim 1. mal gehts..

von Falk B. (falk)


Lesenswert?

@  Mustafa Nissan (snippel9)

>Jetzt kommt hinzu, dass beim 2. mal immer ein Fehler bei "  TM0D =
>0x01;" abgezeigt wird. Beim 1. mal gehts..

Tu mal besser die LED umschalten (toggeln), das ist einfacher und besser 
erkennbar. Denn sonst macht die LED nur einmal was und die siehst nicht, 
dass dein Timer dauernd läuft.

von Mustafa N. (snippel9)


Lesenswert?

Laut meinem Blatt ist LED ^=1; Led invertieren (blinken)
1
//======================== Einbinden von Frunktionsbibliotheken =============================//
2
3
#include <stdio.h>                    // Standard Ein-/Ausgabefunktionen
4
#include <at89C51cc03.h>             // CC03er-Grundregister
5
#include <at89C51cc03.h>            // 8051er-Grundregister                 
6
#include <irq52.h> 
7
#include <reg51.h>
8
9
//======================== Definition von Konstanten =============================//
10
    const unsigned char bit LED1  @  0x92;    // Port-Pin P1.1 (Adresse 92h) LED1 low-aktiv
11
    const unsigned char bit LED2  @  0x93;    // Port-Pin P1.2 (Adresse 93h) LED2 low-aktiv
12
    const unsigned char bit LED3  @  0x94;    // Port-Pin P1.3 (Adresse 94h) LED3 low-aktiv
13
    const unsigned char bit LED4  @  0x95;    // Port-Pin P1.4 (Adresse 95h) LED4 low-aktiv
14
    
15
    const unsigned char bit Button1  @  0x92;     // Port-Pin P1.1 (Adresse 92h) low-aktiv
16
    const unsigned char bit Button2  @  0x93;     // Port-Pin P1.2 (Adresse 93h) low-aktiv
17
    const unsigned char bit Button3  @  0x94;     // Port-Pin P1.3 (Adresse 94h) low-aktiv
18
    const unsigned char bit Button4  @  0x95;     // Port-Pin P1.4 (Adresse 95h) low-aktiv
19
20
//======================== Hauptprogramm =============================//
21
22
int i=0;
23
24
25
void ISR_Timer0 (void) interrupt 
26
27
{
28
    
29
    TH0 = 0xD8;
30
    TL0 = 0xF0;
31
32
    i++;
33
    if(i == 1000)
34
    {
35
    LED1 ^=1
36
    i = 0;
37
    }
38
   
39
}
40
41
42
void main (void)
43
44
45
46
{
47
48
49
    LED1=1;
50
    TMOD = 0x01;
51
    
52
    TH0 = 0xD8;
53
    TL0 = 0xF0;
54
    
55
    ET0 = 1;
56
    EA = 1;
57
    
58
    TR0 = 1;
59
    
60
    while(1)
61
    
62
    {
63
    }
64
65
66
}

Wo ist dann der Fehler? Also es funktioniert nur theoretisch, nicht 
praktisch..

von Mustafa N. (snippel9)


Lesenswert?

Sind meine Unterlagen falsch?

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.