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
voidfoo()
2
{
3
machirgendwas
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
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
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.
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.
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.