Noob braucht Hilfe bei Timerinterrupt in C

OP #3134488
Lesenswert?

Auch ich muss euch mit Anfängerfragen belästigen und diese hier ist 
besonders lächerlich :)

Ich bekomme es nämlich einfach nicht hin, in C(GCC) ein Programm zu 
schreiben, dass den Timer0 dazu bringt, Overflow-Interrupts auszulösen. 
Als µC dient mir der ATmega8 (Ja ja, Cliché-Controller und veraltet, ich 
weiß). Meine Überlegungen:
1
#include <avr/interrupts>
der muss doch sicher rein
1
SREG |= 0b10000000
globale Interrupts einschlaten, oder kann ich da direkt
1
sei()
nehmen?
1
TOIE0 |= 0b00000001
Interrupt zulassen, geht das so?
1
TCCR0 = 0b00000101
Timer mit Prescaler 1024 einschalten, richtig?
1
ISR (TIMER0_OVF_vect)
2
{
3
  PORTD0=0b00000001   //Led anschalten
4
}
So die ISR?

Ich danke euch schon mal.

Edgar
OP #3134510
Lesenswert?

Gerne.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/delay.h>
4

5
int main(void)
6
{  
7
  DDRD = 0b11111111;
8
  SREG |= 0b10000000;
9
  TOIE0 |= 0b00000001;
10
  TCCR0 = 0b00000101;
11
  
12
    while(1)
13
    {
14
    _delay_ms(100);      //Trödeln
15
    PORTD = 0b00000000;    //Led ausschalten
16
    }
17
  
18
  ISR (TIMER0_OVF_vect)
19
  {
20
    PORTD=0b00000001;     //Led anschalten
21
  }
22
}
Mir ist auch klar, dass die LED immer nach einer unterschiedlichen Zeit 
wieder aus geht, aber das ist mir derzeit egal.
#3134523
Lesenswert?

> SREG |= 0b10000000;
-Interrupts schaltet mal mit "sei()" an.
-am SREG brauchst du nicht rumfummeln

> TOIE0 |= 0b00000001;
TOIE0 ist ein Bit im Register TIMSK
also:
1
TIMSK |= (1<<TOIE0);
>TCCR0 = 0b00000101;
besser leserlich:
1
TCCR0 = (1<<CS2) | (1<<CS0);
>  ISR (TIMER0_OVF_vect)
>  {
>    PORTD=0b00000001;     //Led anschalten
>  }
Die ISR gehört nicht IN die main-funktion
Gast #3134525
Lesenswert?

Warum nicht einfach so:
1
ISR (TIMER0_OVF_vect)
2
  {
3
  i++;
4
  PORTD=i     
5
  }

Dann passiert das an und aus ganz von selbst, und für die acht Pins am 
Port sogar mit unterschiedlichen Frequenzen.

Im AVR-GCC-Tutorial sind übrigens viele schöne Beispielprogramme. 
Studier mal jenes im Abschnitt "Overflow Interrupt", dann dürfen sich 
einige Fragen von selbst beantworten.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR

PS: Und benutz (auch in Deinem eigenen Interesse) die Bitnamen - dazu 
hat man sie erfunden.
Gast #3134555
Lesenswert?

>Entschuldige die Unhöflichkeit...

Wenn Du bis zum ^-Operator gelesen hättest, dann würde 90% Deines Codes 
vom ersten Posting ganz anders aussehen. Spar Dir also die Sprüche und 
die Entschuldigungen. Das Ganze ist nur noch lächerlich.
OP #3134569
Lesenswert?

>...diese hier ist
>besonders lächerlich

Gebe ich zu...
Ich gebe auch zu das nicht ganz gelesen bzw. verstanden zu haben, doch 
das ich diesen Artikel kenne hätte man sich denken können (von mir aus 
auch mit dem Beispiel SREG |= 0b10000000;), weshalb sein Beitrag das 
alles hier nicht weiterbringt.



Der derzeitige Code sieht so aus:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/delay.h>
4

5
int main(void)
6
{  
7
  DDRD = 0b11111111;
8
  sei();
9
  TIMSK |= 0b00000001;
10
  TCCR0= (1<<CS00)|(1<<CS02);
11
  
12
    while(1)
13
    {
14
    _delay_ms(100);      //Trödeln
15
    }
16
}
17

18
ISR (TIMER0_OVF_vect)
19
{
20
  PORTD ^= (1<<PD0);     //Led togglen
21
}

Edgar
OP #3134628
Lesenswert?

Nachtrag an alle Anfänger, die das gleiche Problem hatten: Statt
1
TIMSK |= 0b00000001;
bitte
1
TIMSK |= 1<<TOIE0;
schreiben, denn das ist, wie Vuvuzelatus schon geschrieben hat, 
übersichtlicher.

>Vuvuzelatus schrieb:
>PS: Und benutz (auch in Deinem eigenen Interesse) die Bitnamen - dazu
>hat man sie erfunden.

Ich spiele jetzt einfach mal Moderator und mache den Thread zu, da alles 
geklärt wurde.

---------------------------Thread zu!---------------------------
#3134662
Lesenswert?

edgar 339 schrieb:
> als "Schiebe eine 1 an TOIE0 und verknüpfe ODER-weise" und nicht als
> "Schiebe eine 1 so oft nach links, wie der Wert von TOIE0 ist"
> interpretiere?
> Das würde so einiges erklären...
So kann man das interpretieren.
Tatsächlich wird natürlich mit dem Wert geschoben, mit dem TOIE0 
definiert ist. Aber nicht auf dem Controller sondern das macht der 
Compiler auf der 3-GHz-Quadcore-Granate unter dem Tisch.

mfg.
#3134725
Lesenswert?

edgar 339 schrieb:
> Gut, danke das das nochmals geklärt wird. Im Artikel Bitmanipulation
> steht nämlich "(1 << n) : Zuerst wird durch die '<<'-Ausdrücke eine "1"
> n-mal nach links geschoben.", es wäre besser wenn es "...auf Bit n
> geschoben." lauten würde.

Das erste ist (allgemein gesehen) richtig.
das zweite ist deine Interpretation, die in diesem Fall (eine 1 wird 
geschoben) auf dasselbe rausläuft.
Gast #3134726
Lesenswert?

Mein Vorschlag für eine erschöpfende, nicht missverstehbare Auskunft 
darüber, was 1<<n ist:

1<<0 = 0b00000001 = 0x01 = 2^0 = 1
1<<1 = 0b00000010 = 0x02 = 2^1 = 2
1<<2 = 0b00000100 = 0x04 = 2^2 = 4
1<<3 = 0b00001000 = 0x08 = 2^3 = 8
1<<4 = 0b00010000 = 0x10 = 2^4 = 16
1<<5 = 0b00100000 = 0x20 = 2^5 = 32
1<<6 = 0b01000000 = 0x40 = 2^6 = 64
1<<7 = 0b10000000 = 0x80 = 2^7 = 128

wobei das ^ die Potenzierung bezeichnet ("hoch").
OP #3135159
Lesenswert?

>Das erste ist (allgemein gesehen) richtig.
Aber auch nur, wenn man keine Bitnamen einsetzt...

>1<<0 = 0b00000001 = 0x01 = 2^0 = 1
>1<<1 = 0b00000010 = 0x02 = 2^1 = 2
>1<<2 = 0b00000100 = 0x04 = 2^2 = 4
>1<<3 = 0b00001000 = 0x08 = 2^3 = 8
>1<<4 = 0b00010000 = 0x10 = 2^4 = 16
>1<<5 = 0b00100000 = 0x20 = 2^5 = 32
>1<<6 = 0b01000000 = 0x40 = 2^6 = 64
>1<<7 = 0b10000000 = 0x80 = 2^7 = 128

Das falsch zu verstehen wird wirklich schwer :D
Wirklich gute Idee!
#3135747
Lesenswert?

edgar 339 schrieb:
>>Das erste ist (allgemein gesehen) richtig.
> Aber auch nur, wenn man keine Bitnamen einsetzt...

Die "Bitnamen" sind auch nichts weiter als Präprozessor-Makros, für die 
eine Zahl eingesetzt wird. TOIE0 ist in der avr-libc für den atmega8 
z.B. so definiert:
1
#define TOIE0   0

Also ist
1
1 << TOIE0;
genau das gleiche wie:
1
1 << 0;

Man könnte auch
1
12 << TOIE0;
schreiben, auch wenn das in dem Fall keinen Sinn ergeben würde. Dann 
würde eben eine 12 um TOIE0 bits nach links geschoben statt einer 1.
OP #3136447
Lesenswert?

>Die "Bitnamen" sind auch nichts weiter als Präprozessor-Makros...

Danke nochmals, das sollte eventuell im Artikel "Bitmanipulation" 
erwähnt werden... Doch das überlasse ich lieber anderen, es ist zu 
wahrscheinlich, das ich irgend etwas Falsches rein schreibe...

>Denk mal darüber nach, warum man sich sehr viel Arbeit gemacht hat, um
>dort einen Einstieg in die C-Programmierung zu geben.

Och komm schon, wenn das dort ausführlich erklärt wäre, würde ich nicht 
fragen... Ich habe durchaus einige Zeit verbracht, um die Antwort 
alleine zu finden, habe es aber nicht geschafft, da die Erklärung dazu 
über drei Artikel verteilt ist(Bitmanipulation, AVR-GCC-Tutorial/Die 
Timer und Zähler des AVR, AVR-GCC-Tutorial). Wenn man schon weiß wie es 
geht, dann versteht man die Erklärung auch, aber für einen, der es 
gerade lernen will, ist das kaum möglich. Ich will nicht sagen, dass die 
Personen, die diese Artikel geschrieben haben, schlechte Arbeit 
geleistet haben(ganz im Gegenteil, sie haben freiwillig und ohne Lohn zu 
verlangen ein riesiges Projekt auf die Beine gestellt, Respekt!), aber 
als Eingeweihter kann man einfach nicht an alles denken, was ein Neuling 
falsch verstehen könnte.

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