Hallo, ich hab ein problem. ich verstehe nicht, wie ich bei dem 8 bit zähler ein interrupt programmiere. hab mir das im tutorial mal angesehen: /* uC: AT90S2313 */ #include <avr/io.h> #include <avr/interrupt.h> int main(void) { // Timer 0 konfigurieren TCCR0 = (1<<CS01); // Prescaler 8 // Overflow Interrupt erlauben TIMSK |= (1<<TOIE0); // Global Interrupts aktivieren sei(); while(1) { /* Sonstige Aktionen */ } } /* Der Overflow Interrupt Handler wird aufgerufen, wenn TCNT0 von 255 auf 0 wechselt (256 Schritte), d.h. ca. alle 2 ms */ ISR (TIMER0_OVF0_vect) { /* Interrupt Aktion alle (1000000/8)/256 Hz = 488,28125 Hz bzw. 1/488,28125 s = 2,048 ms */ } ich verstehe nicht ganz, was das "ISR (TIMER0_OVF0_vect)" im code soll? kann es villt sein, dass wenn der interrupt ausgelöst wird, dass program dort weiterläuft? hab auch versucht das programm mal in meinen code einzubinden, aber bei "ISR (TIMER0_OVF0_vect)" meckert er rum. ich bin dabei eine uhr zu programmieren, da is die timerfunktion ganz hilfreich. kann mir jemand villt weiterhelfen? nicht nutze einen atmega16. 4mhz qaurz. mfg
Tobias D. schrieb: > ich verstehe nicht ganz, was das "ISR (TIMER0_OVF0_vect)" im code soll? > kann es villt sein, dass wenn der interrupt ausgelöst wird, dass program > dort weiterläuft? ganz genau. Das ist wie eine normale C-Funktion
1 | void foo() |
2 | {
|
3 | mach irgendwas |
4 | }
|
nur mit dem Unterschied, dass die letzte Funktion du selber aufrufen musst, während eine ISR vom 'System' automatisch aufgerufen wird, wenn das auslösende Ereignis eintritt. > hab auch versucht das programm mal in meinen code > einzubinden, aber bei "ISR (TIMER0_OVF0_vect)" meckert er rum. Dann musst du nachsehen, wie die entsprechende Interrupt routine bei deinem µC konkret heißt. Die Namen unterscheiden sich leicht, je nach Prozessor. Normalerweise heißen die Dinger so, wie sie auch im Datenblatt genannt werden, nur mit einem _vect hinten drann. Wenn das übereinstimmt, dann sieh dir deine Projektkonfiguration an, ob du den richtigen Prozessor eingestellt hast. Aus dem Bauch heraus würde ich nämlich sagen, dass der Interrupt beim Mega16 TIMER0_OVF_vect und nicht TIMER0_OVF0_vect heißt (da ist bei OVF0 eine 0 zuviel). Der Timer hat nur einen Overflow, daher macht es keinen Sinn von OVF0 im Gegensatz zu zb OVF1 zu reden. Mit TIMER0_OVF_vect ist genau festgelegt was gemeint ist: Der Overflow vom Timer 0
ja das habe ich auch schon mal gelesen. aber ich finde es nicht mehr im datenblatt. wenn ich: ISR (TIMER0_OVF_vect) { /* Interrupt Aktion alle (1000000/8)/256 Hz = 488,28125 Hz bzw. 1/488,28125 s = 2,048 ms */ } in meinen code einbinde, dann erscheinen 2 fehlermeldungen: ../ProjektWecker.c:113: error: static declaration of '__vector_9' follows non-static declaration und: ../ProjektWecker.c:113: error: previous declaration of '__vector_9' was here was ist mit dem global enable interrupt flag? hab ich das mit: // Global Interrupts aktivieren sei(); gesetzt?
Tobias D. schrieb: > in meinen code einbinde, dann erscheinen 2 fehlermeldungen: > ../ProjektWecker.c:113: error: static declaration of '__vector_9' > follows non-static declaration > und: > ../ProjektWecker.c:113: error: previous declaration of '__vector_9' was > here zeig nochmal den ganzen Code. da könnte irgendwo eine Klammer fehlen, oder sowas in der Richtung. Schieb auch mal die ISR vor alle anderen Funktionen. Fehlermeldungen im Zusammenhang mit ISR können sehr irritierend sein und nicht immer sitzt der Fehler auch wirklich in der ISR > > was ist mit dem global enable interrupt flag? hab ich das mit: > // Global Interrupts aktivieren > sei(); > gesetzt? ja. Siehe AVR-GCC-Tutorial
der code: #define F_CPU 4000000 //Takt 4Mhz #include <avr/io.h> #include <util/delay.h> //Headerfile für Zeitschleife #include <stdlib.h> #include <stdio.h> //für sprintf #include "define.h" //header #include <avr/interrupt.h> int main () { DDRA = 0x03; DDRB = 0xff; DDRC = 0xff; DDRD = 0xff; // Timer 0 konfigurieren TCCR0 = (1<<CS02); // Prescaler 256 // Overflow Interrupt erlauben TIMSK |= (1<<TOIE0); // Global Interrupts aktivieren sei(); //init LCD RS_0; PORTC = 0b00111000; E(); wait(); PORTC = 0b00001100; E(); wait(); PORTC = 0b00000001; E(); wait(); while (1) { if (TCNT0 == 0xff) { zaehler++; } if (zaehler == 61) { zeitsec++; zaehler = 0; } if (zeitsec == 60) { zeitmin++; zeitsec = 0; } if (zeitmin == 60) { zeitstd++; zeitmin = 0; } if (zeitstd == 24) { zeitstd = 0; } sprintf( bufferstd, "%d: ", zeitstd); ausgabestd(); sprintf( buffermin, "%d: ", zeitmin); ausgabemin(); sprintf( buffersec, "%d ", zeitsec); ausgabesec(); switch (zeitsec) { case 0: PORTB = 0b00000100; PORTD = 0b00000010; break; case 1: PORTB = 0b00000100; PORTD = 0b00000001; break; case 2: PORTB = 0b00000010; PORTD = 0b10000000; break; case 3: PORTB = 0b00000010; PORTD = 0b01000000; break; case 4: PORTB = 0b00000010; PORTD = 0b00100000; break; case 5: PORTB = 0b00000010; PORTD = 0b00010000; break; case 6: PORTB = 0b00000010; PORTD = 0b00001000; break; case 7: PORTB = 0b00000010; PORTD = 0b00000100; break; case 8: PORTB = 0b00000010; PORTD = 0b00000010; break; case 9: PORTB = 0b00000010; PORTD = 0b00000001; break; } //Licht if (PINA&(1<<PINA5)) { DDRA |=(1<< DDA5); PORTA |=(1<<PA5); _delay_ms(3000); PORTA &=~( 1<<PA5); DDRA &=~( 1<<DDA5); } ISR (TIMER0_OVF_vect) { } } return 0; } der code ist aber lang noch nicht fertig. vor welche funktionen soll dich dir ISR schieben. die fehlermeldungen kommen schon wieder -.-'.
Tobias D. schrieb: > vor welche funktionen soll dich dir ISR schieben. Egal. Die darf nur nicht, wie jede andere Funktion auch, innerhalb einer anderen Funktionen stehen. Verschachtelte Funktionen kennt C nicht. Oliver
Tobias D. schrieb: Ach nö! > while (1) > { > > if (TCNT0 == 0xff) > { > zaehler++; > } > > if (zaehler == 61) > { > zeitsec++; > zaehler = 0; > } > > if (zeitsec == 60) > { > zeitmin++; > zeitsec = 0; > } > > if (zeitmin == 60) > { > zeitstd++; > zeitmin = 0; > } > > if (zeitstd == 24) > { > zeitstd = 0; > } > > sprintf( bufferstd, "%d: ", zeitstd); > ausgabestd(); > sprintf( buffermin, "%d: ", zeitmin); > ausgabemin(); > sprintf( buffersec, "%d ", zeitsec); > ausgabesec(); > > switch (zeitsec) > { > case 0: PORTB = 0b00000100; > PORTD = 0b00000010; > break; > case 1: PORTB = 0b00000100; > PORTD = 0b00000001; > break; > case 2: PORTB = 0b00000010; > PORTD = 0b10000000; > break; > case 3: PORTB = 0b00000010; > PORTD = 0b01000000; > break; > case 4: PORTB = 0b00000010; > PORTD = 0b00100000; > break; > case 5: PORTB = 0b00000010; > PORTD = 0b00010000; > break; > case 6: PORTB = 0b00000010; > PORTD = 0b00001000; > break; > case 7: PORTB = 0b00000010; > PORTD = 0b00000100; > break; > case 8: PORTB = 0b00000010; > PORTD = 0b00000010; > break; > case 9: PORTB = 0b00000010; > PORTD = 0b00000001; > break; > } > > //Licht > if (PINA&(1<<PINA5)) > { > DDRA |=(1<< DDA5); > PORTA |=(1<<PA5); > > _delay_ms(3000); > > PORTA &=~( 1<<PA5); > DDRA &=~( 1<<DDA5); > } Ich habe jetzt ehrlich gesagt keine Lust die { und } abzuzählen um zu sehen, wo du eine vergessen hast. Rück deinen Code ein, so wie es jeder andere Programmierer auch tut. Nach einer { erhöht sich die Einrücktiefe um 2 Leerzeichen. Eine } wird wieder um 2 Zeichen nach links ausgerückt und dann in dieser Spalte darunter weitergeschrieben. Dann muss man am Ende der Funktion wieder ganz am linken Rand rauskommen. Wenn nicht - da stimmt doch was nicht. > vor welche funktionen soll dich dir ISR schieben. Ganz nach vorne
1 | ....
|
2 | |
3 | ISR( ... ) |
4 | {
|
5 | ...
|
6 | }
|
7 | |
8 | int main() |
9 | {
|
10 | ....
|
11 | }
|
Hallo Eine Einrückung wurde ungemein helfen. Ich habe das Gefühl, deine ISR-Routine steht innerhalb der main. Gruß Joachim
hab ich doch auch nicht, aber es geht trotzdem nicht -.-' ich brauch nur noch diesen richtigen ISR code für den atmega 16. sonst läuft alles. kann mir den mal jemand sagen?!^^ Tobias
XXX schrieb: > Hallo > > Eine Einrückung wurde ungemein helfen. Ich habe das Gefühl, deine > ISR-Routine steht innerhalb der main. Beim drüberscrollen würde ich sogar sagen: die steht innerhalb der while(1). Wie du (und ich) schon sagten: Er soll mal seinen Code vernünftig einrücken.
Tobias D. schrieb: > hab ich doch auch nicht, aber es geht trotzdem nicht -.-' > ich brauch nur noch diesen richtigen ISR code für den atmega 16. sonst > läuft alles. kann mir den mal jemand sagen?!^^ Rück deinen verdammten Code endlich ein! Deine ISR steht nicht auf der Schachtelungstiefe auf der Funktionen erlaubt sind. verdammt nochmal.
Hallo ISR (TIMER0_OVF_vect) { } } return 0; } Da paßt doch was nicht mit den }. Rück das ganze mal anständig ein! Gruß Joachim
Deine ISR steht in der main(),da muss sie raus. Wenn würde an deiner Stelle den Timer so einstellen, dass er jede Sekunde ein Interrupt auslöst und die Zeit in der ISR hochzählen.
also das mit den interrupts klappt jetzt. sitze jedoch schon die ganze zeit an der zeit. normalerweise müssten die sekunden jede sec um 1 steigen. jedoch brauchen sie fast 2 sec. der code: #define F_CPU 4000000 //Takt 4Mhz #include <avr/io.h> #include <util/delay.h> //Headerfile für Zeitschleife #include <stdlib.h> #include <stdio.h> //für sprintf #include "define.h" //header #include <avr/interrupt.h> int main () { DDRA = 0b10000011; DDRB = 0xff; DDRC = 0xff; DDRD = 0xff; // Timer 0 konfigurieren TCCR0 = 0b00000011; // Prescaler 256 // Overflow Interrupt erlauben TIMSK |= (1<<TOIE0); //Global Interrupts aktivieren sei(); //init LCD RS_0; PORTC = 0b00111000; E(); wait(); PORTC = 0b00001100; E(); wait(); PORTC = 0b00000001; E(); wait(); while (1) { //Licht if (PINA&(1<<PINA5)) { DDRA |=(1<< DDA5); PORTA |=(1<<PA5); _delay_ms(5000); PORTA &=~( 1<<PA5); DDRA &=~( 1<<DDA5); } //Zeiteinstellung /* if (PINA&(1<<PINA2)) { _delay_ms(2000); } if (PINA&(1<<PINA2)) { PORTA |=(1<<PA7); _delay_ms(300); PORTA &=~( 1<<PA7); } while (!(PINA&(1<<PINA4))) { if (PINA&(1<<PINA2)) { zeitstd++; sprintf( bufferstd, "%d: ", zeitstd); ausgabestd(); _delay_ms(300); } }*/ } return 0; } ISR (TIMER0_OVF_vect) { zaehler++; if (zaehler == 61) { zeitsec++; zaehler = 0; } if (zeitsec == 60) { zeitmin++; zeitsec = 0; } if (zeitmin == 60) { zeitstd++; zeitmin = 0; } if (zeitstd == 24) { zeitstd = 0; } sprintf( bufferstd, "%d: ", zeitstd); ausgabestd(); sprintf( buffermin, "%d: ", zeitmin); ausgabemin(); sprintf( buffersec, "%d ", zeitsec); ausgabesec(); led(); }
Tobias D. schrieb: 1) hast du dein Programm immer noch nicht eingerückt 2) > #define F_CPU 4000000 //Takt 4Mhz nachrechnen ergibt: das ist glatt gelogen 3) > // Timer 0 konfigurieren > TCCR0 = 0b00000011; // Prescaler 256 das ist kein Prescaler von 256 4) > ISR (TIMER0_OVF_vect) Die Zeit in der ISR hochzuzählen ist in Ordnung. Aber die Ausgabe muss dort raus. Das dauert viel zu lange für eine ISR.
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.