Hallo Mein Timer startet nicht in der ISR. Mein Microcontroller ist ein Attiny861 und verwende einen 16 bit Timer. Danke im voraus! /* * Dekodierung_des_Empfangssignales.c * * Created: 05.04.2013 09:31:40 * Author: 09EPAM42 */ #include <avr/io.h> #include <avr/interrupt.h> int16_t Code = 0x0000; int Einlesen; int Auslesen; ISR(PCINT_vect) { GIMSK = 0x00; //PCINT sperren if ((PINB & 0x10) == 0x00) { Code = Code | 0x8000; } Code = Code >> 1; GPIOR0 = Code; if ((Code & 0B0000000000001100) == 0B0000000000001100) //0B11010100000001 --> 100000 00101 T 11 { PORTA = 0x04; Code = 0x00; } TCNT0H = 0xFA; TCNT0L = 0x88; TCCR0B = 0x02; // Timer starten } ISR(TIMER0_OVF_vect) { PORTA = 0xFF; TCCR0B = 0x00; // Timer stoppen GIMSK = 0x01; // INT freigeben GIFR = 0x00; // Flag löschen } int main(void) { for (int i=0; i<30000;i++); DDRA = 0xFF; DDRB = 0x00; PORTB = 0xFF; //PORTB = 0x10; // Konfiguration für den Sensor TCCR0A = 0x80; // 16 Bit Modus PORTA = 0x00; // Konfiguration für die LED TCNT0H = 0xFC; TCNT0L = 0x18; GIMSK = 0B00100000; // GIMSK setzen PCMSK1 = 0B00010000;// Interrupt Maskierung SREG = 0x80; // Global Enable Bit setzen //TIMSK = 0x00; // while (1) {} }
> for (int i=0; i<30000;i++); warum nicht _delay_us ? > SREG = 0x80; // Global Enable Bit setzen sei() und cli() benutzen am SREG brauchst du nicht rumfummeln > GIMSK = 0B00100000; // GIMSK setzen > PCMSK1 = 0B00010000;// Interrupt Maskierung Warum nicht leserlicher schreiben?
1 | GIMSK = (1<<PCIE1); |
2 | PCMSK1 = (1<<PCINT12) |
DANKEEE für eure schnellen antworten! Habe alle fehler korrigiert doch der Timer will nicht starten. PS: Meine unsaubere Programmierung habe ich in der Schule gelernt! Werde in Zukunft darauf achten ! #include <avr/io.h> #include <avr/interrupt.h> int16_t Code = 0x0000; int Einlesen; int Auslesen; ISR(PCINT_vect) { GIMSK = 0x00; //PCINT sperren if ((PINB & 0x10) == 0x00) { Code = Code | 0x8000; } Code = Code >> 1; GPIOR0 = Code; if ((Code & 0B0000000000001100) == 0B0000000000001100) //0B11010100000001 --> 100000 00101 T 11 { PORTA = 0x04; Code = 0x00; } TCNT0H = 0xFA; TCNT0L = 0x88; TCCR0B = 0x01; // Timer starten } ISR(TIMER0_OVF_vect) { PORTA = 0xFF; TCCR0B = 0x00; // Timer stoppen GIMSK = 0x01; // INT freigeben GIFR = 0x00; // Flag löschen } int main(void) { for (int i=0; i<30000;i++); DDRA = 0xFF; DDRB = 0x00; PORTB = 0xFF; //PORTB = 0x10; // Konfiguration für den Sensor TCCR0A = 0x80; // 16 Bit Modus PORTA = 0x00; // Konfiguration für die LED TCNT0H = 0xFC; TCNT0L = 0x18; GIMSK = (1<<PCIE1); // GIMSK setzen PCMSK1 = (1<<PCINT12); // Interrupt Maskierung //SREG = 0x80; // Global Enable Bit setzen TIMSK|=(1<<TOIE0); sei(); cli(); while (1) {} }
Michael Patak schrieb: > for (int i=0; i<30000;i++); Wofür ist diese Zeile am Beginn von main gut? Vielleicht kannst du auch mal beschreiben was das Programm tun soll.
Michael Patak schrieb: > sei(); > cli(); Das ist natürlich Quatsch. Du gibst die Interupts frei und sperrst sie sofort wieder.
Michael Patak schrieb: > sei(); > cli(); Interrupt an und gleich wieder aus. Das ist eine tolle Idee. Das "cli" habe ich nur erwähnt damit du weißt wie du die Intterupts wieder ausmachst
Michael Patak schrieb: > GIFR = 0x00; // Flag löschen Nö, da wird nichts gelöscht. Eine 0 ins Register zu schreiben, bringt - nix. Ich empfehle die Lektüre des Datenblattes.
Damit zuerst der IR Sender das Signal stabilisiert und nicht zuvor einen ungewollten Interrupt auslöst. Aber danke es funktioniert schon! Lg
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.