Hallo ihr! Bin gerade dabei, mir mittels einigen Testprogrammen den µC ein wenig kennenzulernen. Gerade eben möchte ich einfach nur eine LED zum blinken bringen, um die Timer-Funktion auszuprobieren. Beim 8051er macht man das wie folgt: #include <AT89X52.H> sbit LED = P1^0; void InitTimer0 (void) { IE = IE | 0x82; TMOD = TMOD | 0x01; //Timer0 einschalten (16Bit) TL0 = 0x3C; TH0 = 0xB0; TR0 = 1; } void ISR_Timer0(void) interrupt 1 { int ueberlauf; ueberlauf++; if(ueberlauf == 10) { LED = ~LED; //LED != LED; --> Osterer //P1_0 = ~P1_0; ueberlauf = 0; } //Startwert des Timers setzen TL0 = 0x3C; TH0 = 0xB0; } void main (void) { InitTimer0(); while(1) {} } Wie werden aber die Register bei einem ATmega8 gesetzt? Folgendes hab ich ausprobiert: #include <avr/io.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> #include <inttypes.h> #include <stdlib.h> #include <string.h> #include <stdio.h> void InitTimer0 (void) { SREG = SREG |0x80; TCCR0 = TCCR0 | 0x01; // TIMSK = TIMSK | 0x01; } void ISR_Timer0(void) interrupt 10 { // noch nix da } void main (void) { InitTimer0(); while(1); } Mit der Bitte um Hilfe LG Birgit
> void ISR_Timer0(void) interrupt 10
Wenn Du mit dem WINAVR-Compiler arbeitest (was ich anhand der #includes
mal vermute), dann geht das so nicht. Eine ISR wird in WINAVR-C mit
1 | ISR(VEKTORNAME_vect) |
2 | {
|
3 | //Hier Code einfügen
|
4 | }
|
geschrieben. BTW: Für "SREG = SREG |0x80;" gibt es die Pseudo-Funktion "sei()", die man der Übersicht halber auch verwenden sollte. Generell kann man Sachen wie
1 | TCCR0 = TCCR0 | 0x01; |
kürzer als
1 | TCCR0 |= 0x01; |
schreiben.
Ach ja, und Sachen wie
1 | TCCR0 |= 0x01; |
sind nicht sehr aussagekräftig. Verwende dabei bitte die Schreibweise mit den Bitnamen, also z.B.
1 | TCCR0 |= 1 << CS00; |
Sonst kann das Programm hinterher kein Schwein lesen.
ISR(TIMER0_OVF_vect) { }; int main (void) //Timer0 Einstellungen TCCR0 |= (1<<CS00) | (1<<CS01); //Timer Prescaler auf /64 TIMSK |= (1<<TOIE0); //Timer0_Overflow Interrupt aktivieren TCNT0 = 0; //Timerstartwert sei(); //Interrupts global aktivieren while(1) {...
Hallo zusammen! Ich hänge mich mal hier ran, da ich auch ein Problem mit den Atmega8 Timer0 habe (naja, wahrscheinlich eher der Timer mit mir ;) Und zwar habe ich ein kleines Programm geschrieben das erstmal nur eine LED zum blinken bringen sollte, leider bisher ohne Erfolg. Daher habe ich die ISR erstmal dadurch ersetzt, dass die LED überhaupt einmal leuchten soll, um zu überprüfen ob die ISR angesprungen wird. Leider auch hier tote Hose. Schreibe ich die Anweisung die LED zu aktivieren vor oder in die while Schleife, leuchtet die LED, das Programm läuft also bis dahin. Ich denke ich mache irgendwas bei der Timer Initialisierung falsch oder bei der Interruptabarbeitung. Jedenfalls brachte es mich auch nicht weiter, als ich das Overflowflag des Timers0 manuell mal auf 1 gesetzt habe. Ich hoffe ihr habt eine Idee! Liebe Grüße, Jan
1 | ISR (TIMER0_OVF_vect){ //timer0 overflow vector |
2 | PORTC |= (1<<PC1); |
3 | }
|
4 | |
5 | int main(void){ |
6 | DDRC |= (1 << DDC1); //Set direction register for pc1 |
7 | PORTC = 0x00; //set outputs initially to zero |
8 | |
9 | //Timer initialization
|
10 | TIMSK = (1<<TOIE0); //Timer overflow Interrupt enable |
11 | TCCR0 |= (1<<CS00) | (1<<CS02); //prescaler set to 1024 |
12 | TCNT0 = 0; //startvalue for timer |
13 | |
14 | sei(); //activate interrupts |
15 | |
16 | while(1){ |
17 | }
|
18 | return 0; |
19 | }
|
@Berge: Zeig mal das vollständige Programm. Interrupt-Flags kann man übrigens nicht "manuell" setzen. Abgesehen davon: Sicher, dass die LED gegen Masse angeschlossen ist? Ansonsten schaltest Du sie mit "PORTC |= (1<<PC1);" nämlich aus und nicht ein. Hast Du alle erforderlichen Header eingebunden? Und nächstes Mal machste bitte nen neuen Thread auf, anstatt einen Uralt-Thread wieder rauszukramen. Sonst kommen wieder reihenweise Leute auf die Idee, ihren Senf zum Ursprungs-Posting dazuzugeben, weil sie nicht aufs Datum schauen.
Lieben Dank für die Antwort, ich werde nächstes Mal einen neuen Thread öffnen. Die LED ist definitiv gegen Masse verschaltet, wie gesagt, wenn ich sie sonst mit PORTC |= (1<<PC1) befeuere, leuchtet sie. Ich hatte den Quellcode ein wenig beschnitten (unnötige Kommentare etc entfernt) aber jetzt verwende ich genau den hier:
1 | #include <avr/io.h> //used for register/io access |
2 | #include <avr/interrupt.h> |
3 | |
4 | ISR (TIMER0_OVF_vect){ //timer0 overflow vector |
5 | PORTC |= (1<<PC1); |
6 | }
|
7 | |
8 | int main(void){ |
9 | DDRC |= (1 << DDC1); //Set direction register for pc1 |
10 | PORTC = 0x00; //set outputs initially to zero |
11 | |
12 | //Timer initialization
|
13 | TIMSK = (1<<TOIE0); //Timer overflow Interrupt enable |
14 | TCCR0 |= (1<<CS00) | (1<<CS02); //prescaler set to 1024 |
15 | TCNT0 = 0; //startvalue for timer |
16 | |
17 | sei(); //activate interrupts |
18 | |
19 | //PORTC |= (1<<PC1); LEDtest
|
20 | while(1){ |
21 | }
|
22 | return 0; |
23 | }
|
Die Stelle LEDtest habe ich auskommentiert, damit leuchtet die LED problemlos, leider nicht in der ISR.
Probier mal den Ausgang toggeln zu lassen.
1 | PORTC ^= (1<<PC1); |
Zusätzlich kannst du im der main ja mal den nächsten portpin wackeln lassen. dann weist du schonmal dass überhaupt was läuft.
Das Toggeln habe ich ausprobiert, funktoniert ausserhalb der ISR, innerhalb leider nicht. Einen anderen Pin nutzen kann ich zwar, dafür müßte ich meinen doch recht rudimentären Versuchsaufbau aber erweitern. Ich nutze das AVR Studio und dort habe ich den Atmega8 auch eingestellt, ein Blick auf den avr-gcc Aufruf offenbar mir auch, dass er mit der Option -mmcu=atmega8 aufgerufen wird. Scheint also ok zu sein. Gerade ist mir allerdings etwas elektrisch doch recht seltsames aufgefallen, ich werde da mal nachforschen müssen. Vielleicht machts auch Sinn direkt ein Testboard zu bauen, mal schauen wozu ich heute Abend Zeit finde. Danke schonmal für eure Antworten!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.