Hallo zusammen, ich möchte 8 LEDs im Sekunden-Abstand nacheinander an- und wieder ausschalten. Der Plan ist den Timer1 und den Interrupt bei overflow zu nutzen. Ich betreibe den ATM @ 1Mhz und habe den Prescaler auf 64 eingestellt, also 15625 Zähler pro Sekunde. Im Interrupt lade ich die Differenz bis zum Overlow-Wert in den Counter des Timers (65536-15625 = 49911). Im AVR-Studio läuft das auch alles Prima, auf meinen Versuchsaufbau blinkt mal hier ein LED, mal dort ... Hat da jemand eine Idee, woran es liegen könnte? Vielen Dank und Gruß Stefan Hier der Code: #include <avr/io.h> #include <avr/interrupt.h> //LEDs #define LED1 PC4 #define LED2 PC3 #define LED3 PD0 #define LED4 PD1 #define LED5 PD2 #define LED6 PD3 #define LED7 PD4 #define LED8 PD5 #define LED9 PD6 #define LED10 PD7 volatile unsigned int sec; ISR(TIMER1_OVF_vect) { sec++; if (sec==9) {sec = 0;} // ATMEGA8 @ 1MHz; Prescaler 64 => 15625 Takte/sec // Vorzähler auf 65536 - 15625 = 49911 einstellen // ==> Hochzählen alle 1 sec TCNT1 = 49911; } int main(void) { TIMSK |= (1<<TOIE1); //Interrupt bei OVF TCCR1B |= (1<<CS10 | 1<<CS11); //Prescaler 64 TCNT1 = 0xFFFF; //starte sofort mit Interrupt sei(); DDRD = 0xFF; //Initialwerte PORTD = 0x00; sec = 0; while(1) { if (sec==1) {PORTD ^= (1<<LED3);} if (sec==2) {PORTD ^= (1<<LED4);} if (sec==3) {PORTD ^= (1<<LED5);} if (sec==4) {PORTD ^= (1<<LED6);} if (sec==5) {PORTD ^= (1<<LED7);} if (sec==6) {PORTD ^= (1<<LED8);} if (sec==7) {PORTD ^= (1<<LED9);} if (sec==8) {PORTD ^= (1<<LED10);} } return(0); }
Hi Was denkst du denn, wie oft deine While-Schleife in einer Sekunde durchlaufen wird? MfG Spess
Guten Abend, Ich programmiere seit kurzer Zeit auch ein bisschen auf dem Atmega8 und habe eine Frage zu deinem Code. Das Problem liegt, wenn ich das richtig sehe, dadran, dass du ^= schreibst und damit den Ausgang invertierst und die While-Schleife ja einige male mehr in der Sekunde durchläufst. Meine Lösung wäre, die Ausgänge im Interrupt zu invertieren. Und meine Frage dazu: Macht das Sinn, oder was ist die einfachste/beste Lösung an dieser Stelle? Grüße
anfaenger schrieb: > Das Problem liegt, wenn ich das richtig sehe, dadran, dass du ^= > schreibst und damit den Ausgang invertierst und die While-Schleife ja > einige male mehr in der Sekunde durchläufst. > Meine Lösung wäre, die Ausgänge im Interrupt zu invertieren. Wäre möglich und bei der kleinen Aufgabe auch sinnvoll (außer es gibt noch andere wirklich zeitkritische Interrupts / Aufgaben) > Und meine Frage dazu: Macht das Sinn, oder was ist die einfachste/beste > Lösung an dieser Stelle? Das ganze möglichst ohne if machen. Das kostet Zeit. Lieber ein Array mit den ganzen Led-Pins nehmen. z.B. uint8_t *ports[]= {&PORTD, &PORTD, &PORTD, &PORTC}; uint8_t pins[] = {1, 2, 4, 32}; //2^pin //ISR *(ports[sec]) ^= pins[sec++]; sec &= 0x03; //sec == 4 -> sec = 0 Einfacher wäre es wenn die Pins nebeneinander liegen.
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.