Hallo zusammen,
ich versuche den timer0 beim tiny13 zu verwenden. Der Timer scheint aber
nicht zu laufen, denn der code in der ISR wird nicht ausgeführt.
Ich initialisiere den Timer so:
im Main()
1
TIMSK0=(1<<TOIE0);// enable timer overflow interrupt for both Timer0
2
TCNT0=0x00;// set timer0 counter initial value to 0
3
TCCR0B=(1<<CS02)|(1<<CS00);// start timer0 with /1024 prescaler
4
5
sei();
6
7
for(;;){
8
if(_main_counter==1000){
9
PORTB|=1<<PB4
10
}
11
}
Die ISR
1
ISR(TIM0_OVF_vect){
2
_main_counter++;
3
}
Das Problem ist, dass der code in der IF-Bedingung nie ausgeführt wird.
Der Tiny13 läuft auf 9,6MHz und CKDIV8 ist ausgeschaltet.
Der Code läuft auch im Simulator nicht.
Hat jemand Anregungen für mich?
Peter II schrieb:> ist _main_counter volatile?
Eben. Den entscheidenen Code-Teil wieder mal nicht gezeigt. Ist es so
schwer den ganzen verdammten Code zu zeigen und nicht immer nur genau
den Teil in dem Fehler nicht ist? Das ist so selten dämlich!
gruß cyblord
cyblord ---- schrieb:> Eben. Den entscheidenen Code-Teil wieder mal nicht gezeigt. Ist es so> schwer den ganzen verdammten Code zu zeigen und nicht immer nur genau> den Teil in dem Fehler nicht ist? Das ist so selten dämlich!>> gruß cyblord
1
volatileuint16_t_main_counter;
Sorry, vergessen zu erwähnen. Ja, alle Variablen die ich in den ISRs
benutze sind volatile. Das Semikolon beim PortPin ändern habe ich nur
hier vergessen, im code ist es vorhanden.
Das Problem ist: Ich mache im AVR Studio einen Breakpoint in die ISR und
lasse das Ding im emulator laufen. Leider wird der Breakpoint nie
angesprungen. In der Schaltung auf dem Steckbrett äußert sich das
ebenso, da der Code der damit gesteuert wird nicht läuft.
Um es klar zu stellen: Der Code der ausgeführt werden soll, ist eine
Serielle Übertragung. Ich messe mit dem Multimeter am entsprechenden Pin
aber immer einen LOW Pegel. Die Übertragungsgeschwindigkeit ist langsam
genug um beim Multimeter wenigstens eine Veränderung auslösen zu müssen,
aber auch das ist nicht der Fall.
Florian Trück schrieb:> Sorry, vergessen zu erwähnen. Ja, alle Variablen die ich in den ISRs> benutze sind volatile. Das Semikolon beim PortPin ändern habe ich nur> hier vergessen, im code ist es vorhanden.
Bitte zeig deinen richtigen Code!
Häng einfach dein C-File hier als Attachment an.
Das ist für dich am einfachsten. Das ist für uns am einfachsten. Und wir
haben tatsächlich dann 100% das Programm vor uns, welches auf deinem µC
läuft (vorausgesetzt, dass du das richtige Hex-File gebrannt hast und
das in der Entwicklungsumgebung auch wirklich ein Tiny13 eingestellt
ist)
> Um es klar zu stellen: Der Code der ausgeführt werden soll, ist eine> Serielle Übertragung. Ich messe mit dem Multimeter am entsprechenden Pin> aber immer einen LOW Pegel. Die Übertragungsgeschwindigkeit ist langsam> genug um beim Multimeter wenigstens eine Veränderung auslösen zu müssen,> aber auch das ist nicht der Fall.
Tipp für die Zukunft.
An dieser Stelle ist eine simple LED das bessere Messinstrument. Denn
eine LED siehst du auch dann noch flackern, wenn dein Voltmeter schon
längst nur noch einen konstanten Wert anzeigt.
Unter Atmel Studio 6 läuft das bei mir problemlos (d.h. der Breakpoint
in der ISR wird angesprungen!):
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<inttypes.h>
4
5
volatileuint16_t_main_counter;
6
7
intmain(){
8
TIMSK0=(1<<TOIE0);// enable timer overflow interrupt for both Timer0
9
TCNT0=0x00;// set timer0 counter initial value to 0
10
TCCR0B=(1<<CS02)|(1<<CS00);// start timer0 with /1024 prescaler
11
12
sei();
13
14
for(;;){
15
if(_main_counter==1000){
16
PORTB|=1<<PB4;
17
}
18
}
19
}
20
21
22
ISR(TIM0_OVF_vect){
23
_main_counter++;
24
}
Anmerkungen:
1. Rechne nicht damit, dass sich an PB4 etwas ändert, denn Du setzt das
DDRB nicht.
2. Der Vergleich
1
if(_main_counter==1000)
funktioniert hier zwar wegen des hohen Prescalerwerts, aber eigentlich
müsste der Zugriff atomar sein!
3. Zeige uns Deinen GANZEN Code (wie oben schon mehrfach gesagt!).
Also gut, ok. Hier das C-File. Es war nicht mein Gedanke irgendwas
geheim zu halten. Ich wollte mich nur nicht blamieren oder allzu herbe
Kritik für für den Code einheimsen.
Ich hoffe ihr seht mehr als ich.
Bin mir nicht sicher ob ich F_CPU richtig definiert habe, aber das
sollte für den Code erstmal uninteressant sein, da die ISR vom Timer
davon ja erstmal nicht beeinflusst wird, oder?
Florian Trück schrieb:> Die Übertragungsgeschwindigkeit ist langsam> genug um beim Multimeter wenigstens eine Veränderung auslösen zu müssen,> aber auch das ist nicht der Fall.
Im Gegenteil, die Übertragungsgeschwindigkeit ist rasend schnell.
1
_delay_us(16L/BAUD);
Oder welchen Delay erwartest du bei _delay_us(0) zu bekommen?
Florian Trück schrieb:> Also gut, ok. Hier das C-File. Es war nicht mein Gedanke irgendwas> geheim zu halten. Ich wollte mich nur nicht blamieren oder allzu herbe> Kritik für für den Code einheimsen.>> Ich hoffe ihr seht mehr als ich.> Bin mir nicht sicher ob ich F_CPU richtig definiert habe, aber das> sollte für den Code erstmal uninteressant sein, da die ISR vom Timer> davon ja erstmal nicht beeinflusst wird, oder?
Ich kann eigentlich nichts entdecken.
Daher ein paar Fragen:
Die ist klar, dass deine Overflow ISR in Realzeit nur alle 0.02 Sekunden
ausgeführt wird? Das ist im Simulator eine lange Zeit. Da braucht der
schon eine Weile, bis die Simulationszeit soweit fortgeschritten ist.
Setz zum Testen mal den Prescaler des Timers auf 1 anstelle von 1024.
Siehst du den Timer im Simulator hochzählen? Wird die ISR jetzt
angesprungen? Dann hast du einfach nur nich lange genug gewartet.
Woran machst du es fest, dass die Timer-ISR nie angesprungen wird?
Stellst du das nur mit deinem Multimeter fest?
Programmier dir das mal um dass in der ISR eine LED eingeschaltet wird.
Dann hast du eine eindeutige Kennung, dass sie ausgeführt wird.
Karl Heinz Buchegger schrieb:> Die ist klar, dass deine Overflow ISR in Realzeit nur alle 0.02 Sekunden> ausgeführt wird? Das ist im Simulator eine lange Zeit. Da braucht der> schon eine Weile, bis die Simulationszeit soweit fortgeschritten ist.>> Setz zum Testen mal den Prescaler des Timers auf 1 anstelle von 1024.> Siehst du den Timer im Simulator hochzählen? Wird die ISR jetzt> angesprungen? Dann hast du einfach nur nich lange genug gewartet.
Hah! In der Tat! Der Overflow wird ewig nicht aufgerufen.
Da habe ich wohl offensichtlich nicht darüber nachgedacht. :-)
Wie ist das mit der F_CPU? Habe ich die eigentlich richtig gesetzt, oder
ist die falsch?
Florian Trück schrieb:> Wie ist das mit der F_CPU? Habe ich die eigentlich richtig gesetzt, oder> ist die falsch?
Nö. Passt schon.
Der Optimizer muss eingeschaltet sein, damit das _delay_us korrekte
Zeiten liefert. Und bei der Gelegenheit optimiert der Compiler die
Floating Point Zahl sowieso weg.
WEnn dir unwohl dabei ist, dann schreibs halt als
#define F_CPU 9600000UL
dann kann dir nichts passieren.
Da die Daten ja seriell übertragen werden sollen, stellt sich mir gerade
die Frage ob ich noch einen Pegelwandler brauche, wenn ich den tiny an
einen usb/seriell wandler hänge.
Oder kann ich den tiny direkt dran hängen und am PC daten empfangen?
Florian Trück schrieb:> Das Problem ist, dass der code in der IF-Bedingung nie ausgeführt wird.
Es scheint, dass der Interrupthändler (ISR) nicht angesprungen wird.
Ist d. Vektorname (TIM0_OVF_vect) korrekt?
Der Compiler ist an dieser Stelle sehr tolerant und bemeckert den Fehler
nicht.
Als nächstes würde ich versuchen den zweiten Parameter mitzugeben.
Bei meinem Tiny26 muss ich den Händler so definieren:
1
ISR(TIMER0_OVF0_vect,ISR_BLOCK){
2
tuMaWat();//…
3
}
Sonst wird beim Überlauf wieder zu „main“ gesprungen…
Gruß
AVR-Newbie
AVR-Newbie schrieb im Beitrag #3004198:
> Bei meinem Tiny26 muss ich den Händler so definieren:ISR(TIMER0_OVF0_vect,
ISR_BLOCK){
> tuMaWat();//…> }> Sonst wird beim Überlauf wieder zu „main“ gesprungen…
Danke für den Tipp, aber es scheint zumindest im Emulator nun zu
funktionieren. Ich muss mich jetzt noch darum kümmern, dass der Tiny in
Echt-Beschaltung auch funktioniert.
Karl Heinz Buchegger schrieb:> Tipp für die Zukunft.> An dieser Stelle ist eine simple LED das bessere Messinstrument. Denn> eine LED siehst du auch dann noch flackern, wenn dein Voltmeter schon> längst nur noch einen konstanten Wert anzeigt.
Das werde ich ausprobieren. Vielleicht sehe ich ja was flackern. :-)