Forum: Mikrocontroller und Digitale Elektronik ATMEGA16 - Realisierung einer Digitaluhr


von Frank K (Gast)


Lesenswert?

Hallo Leute,

ich bräuchte mal eure Hilfe denn ich komme leider überhaupt nicht weiter 
mit meinem Code. WinAVR bringt keine Fehler aber leider passiert halt 
überhaupt nichts wenn ich das Programm "brenne". Zur Beschreibung: Ich 
versuche eine Digitaluhr zu realisieren die im natürlich im Sekundentakt 
blinkt.

Hier mein C-Quellcode:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/signal.h>
4
5
6
int second;
7
int minute;
8
int hour;
9
10
ISR( TIMER1_OVF_vect ) { 
11
    TCNT1 = 49911;                            
12
    add_second();
13
}
14
15
void add_second(void){
16
    
17
    second++;
18
    
19
    if (second == 60) {
20
        second = 0;
21
        minute++;
22
        if (minute == 60) {
23
            minute = 0;
24
            hour++;
25
            if (hour == 24) { hour = 0; }
26
        }
27
    }
28
}
29
30
31
32
void timerinit(void){
33
    TIMSK|=(1<<TOIE1);            //Aktivierung des Überlaufinterrupts
34
    TCCR1B|=(1 << CS12) | (1 << CS10);    //Prescaler auf 1024
35
    TCNT1=49911;                //Ladewert für Timer1 für 1s Verzögerung
36
}
37
38
39
40
int main( void ){
41
    DDRA  = 0xFF;                //PortA als Ausgang definieren
42
    DDRC  = 0xFF;
43
    DDRD  = 0xFF;
44
    
45
46
    timerinit();                //Timer initialisieren
47
    sei();                        //Interrupts global zulassen
48
    
49
50
    while( 1 ) {                // Endlosschleife
51
        PORTA = hour;
52
        PORTD = second;
53
        PORTC = minute;
54
    }
55
    
56
    return 0;
57
58
}

Für eure Bemühungen im voraus vielen Dank.

MfG

Frank

von MaWin (Gast)


Lesenswert?

> int second;
> int minute;
> int hour;

nicht volatile?
(und das ist nur das erste was auffällt,
ich wüsste jetzt auch nicht von welcher
Frequenz der WinAVR ausgeht und hab mir
den Rest gar nicht angeguckt).

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Außerdem ist nichts initialisiert.
Ich bin mir jetzt aber nicht sicher, ob die Variablen beim Start 
vielleicht doch 0x00 sind. Normal ist das aber nicht. Sie könnten jeden 
beliebigen Wert haben.

von spess53 (Gast)


Lesenswert?

Hi

>    TCNT1=49911;                //Ladewert für Timer1 für 1s Verzögerung

Schon mal etwas von CTC gehört?  Außerdem fängt der Timer nach dem 
ersten Überlauf wieder von Null an.

MfG Spess

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

spess53 schrieb:
> Schon mal etwas von CTC gehört?

Zustimmung  =)

>  Außerdem fängt der Timer nach dem ersten Überlauf wieder von Null an.
>
> MfG Spess

Deswegen lädt er ja auch im OVF Interrupt den Zähler wieder mit dem
"Init-Wert".

Gruß,
Magnetus

von spess53 (Gast)


Lesenswert?

Hi

>Deswegen lädt er ja auch im OVF Interrupt den Zähler wieder mit dem
>"Init-Wert".

Stimmt. Da habe ich irgendwie sein 'add_second' für die ISR gehalten.

MfG Spess

von Frank K (Gast)


Lesenswert?

DANKE. Lag am volatile. Jetzt funktionierts. Weiss zwar noch nicht genau 
für was das steht aber zumindest läufts. SUPI :))))

von Falk B. (falk)


Lesenswert?

@  Frank K (Gast)

>DANKE. Lag am volatile. Jetzt funktionierts. Weiss zwar noch nicht genau
>für was das steht aber zumindest läufts. SUPI :))))

siehe Interrupt

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Alle Variablen, die in einer Interrupt-Routine verändert werden, müssen 
volatile sein. Ansonsten merkt der Compiler nicht, dass sich die 
Variable verändert und optimiert sie weg.

von Falk B. (falk)


Lesenswert?

@  Christian H. (netzwanze) Benutzerseite

>Alle Variablen, die in einer Interrupt-Routine verändert werden, müssen
>volatile sein.

Nicht ganz.

> Ansonsten merkt der Compiler nicht, dass sich die
>Variable verändert und optimiert sie weg.

Kaum. Er optimiert aber ggf. den ZUGRIFF. Siehe Artikel Interrupt.

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Falk Brunner schrieb:
> @  Christian H. (netzwanze) Benutzerseite
>
>>Alle Variablen, die in einer Interrupt-Routine verändert werden, müssen
>>volatile sein.
>
> Nicht ganz.

Ok, nicht alle, sondern nur die, welche im Interrupt und in der 
Hauptschleife verwendet werden.

>> Ansonsten merkt der Compiler nicht, dass sich die
>>Variable verändert und optimiert sie weg.
>
> Kaum. Er optimiert aber ggf. den ZUGRIFF.

Stimmt, mal wieder zu voreilig geschrieben. Ich meinte auch den Zugriff.

Hier ein Beispiel, was ich meinte (hoffe mal, dass es so besser ist):

main:
1
variable = 1;
2
while (1) {
3
  if (variable == 2) {
4
    mach_licht_aus();
5
  }
6
}

wird optimiert zu:
1
variable = 1;

da sich innerhalb der Schleife ja scheinbar nichts mehr verändert. Der 
IF-Vergleich wird also nie zutreffen (so jedenfalls die Meinung des 
Compilers).

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.