Timer, Interrupt

OP #2981705
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?
#2981739
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.
#2981770
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 !
#2981792
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?
OP #2982640
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..
#2983039
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.
OP #2983103
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..

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