Hi,
ich habe erst neu mit Microcontroller / Robotik angefangen und arbeite mich nun langsam durch den Stoff und hier durchs Forum.
Nun hatte ich ein Problem, konnte dieses zwar Lösen, verstehe aber nicht warum nicht beides funktioniert.
Funktion:
Es soll LED3 (PB3) blinken. Nach ca. einer Minute soll die LED0 (PB0) leuchten, nach einer weiteren Minute dann LED0 aus und LED1 (PB1) an usw.
Ergebnis Code1:
LED3 blinkt wie gewünscht, aber die andere LEDs blinken von Anfang an auch ganz wild und unvorhersehbar.
Ergebnis Code2:
Nach etwas probieren (Interrupts während den IF-Anweisungen ausschalten usw.) hab ichs dann wie in Code2 geändert und nun tut es.
Nun hoffe ich, dass mir jemand von euch sagen kann warum. Es müsste doch egal sein, ob ich die Sekunden in der Hauptschleife oder dem Interrupt hochzähl, hauptsache ich deklariere die Variable als volatile, damit der Compiler das richtig umsetzt.
Wenn es jemand Testen will, ich arbeite mit einem NiboBee.
(Die stellen, welche sich unterscheiden sind mit " // <<----- Unterschied" markiert)
Code1 (funktioniert nicht):
Code2 (funktioniert):Code:#include <avr/io.h> // allgemeine Headerdatei #include <stdint.h> // für standardisierten Typen z.B. int8_t #include <avr/interrupt.h> // fuer sei() => Aktivieren, cli() => ausschalten und ISR(): // Prototypen void Timer0_init(void); // Globale Variable volatile uint16_t blink_hz = 0; volatile uint8_t blink = 0; // <<----- Unterschied int main(void) { // IO's init Timer0_init(); DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3); // LED's // Variable volatile uint8_t sek = 0; // <<----- Unterschied // Globale Interrupts erlauben sei(); while(1) { if(blink) { PORTB |= (1<<PB3); sek++; // <<----- Unterschied } else PORTB &= ~(1<<PB3); if (sek > 59 && sek < 119) PORTB |= (1<<PB0); else PORTB &= ~(1<<PB0); } return 0; } /************* Funktionen **************/ // Timer 1ms void Timer0_init(void) { TCCR0 = (1<<WGM01); // Timer im CTC-Modus TCCR0 |= (1<<CS00) | (1<<CS01); // Prescaler auf 64 OCR0 = 234; // um ca. 1ms zu erreichen TIMSK |= (1<<OCIE0); // Interrupt "TIMER0_COMP_vect" aktivieren } /************* Interrupts **************/ ISR (TIMER0_COMP_vect) { blink_hz++; switch (blink_hz) { case 499: blink = 1; break; // <<----- Unterschied case 999: blink = 0; blink_hz = 0; break; default: break; } }
greezCode:#include <avr/io.h> #include <stdint.h> #include <avr/interrupt.h> // Prototypen void Timer0_init(void); // Globale Variable volatile uint16_t blink_hz = 0; volatile uint8_t blink = 0; volatile uint8_t sek = 0; // <<----- Unterschied int main(void) { // IO's init Timer0_init(); DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3); // LED's // Globale Interrupts erlauben sei(); while(1) { if(blink) { PORTB |= (1<<PB3); // <<----- Unterschied } else PORTB &= ~(1<<PB3); if (sek > 59 && sek < 119) PORTB |= (1<<PB0); else PORTB &= ~(1<<PB0); } return 0; } /************* Funktionen **************/ // Timer 1ms void Timer0_init(void) { TCCR0 = (1<<WGM01); // Timer im CTC-Modus TCCR0 |= (1<<CS00) | (1<<CS01); // Prescaler auf 64 OCR0 = 234; // um ca. 1ms zu erreichen TIMSK |= (1<<OCIE0); // Interrupt "TIMER0_COMP_vect" aktivieren } /************* Interrupts **************/ ISR (TIMER0_COMP_vect) { blink_hz++; switch (blink_hz) { case 499: blink = 1; sek++; break; // <<----- Unterschied case 999: blink = 0; blink_hz = 0; break; default: break; } }







Zitieren

Lesezeichen