Hallo Profis,
ich verzweifle gerade ein bisschen an meinem Bastel-Projekt.
Ich habe hier einen ATMega2560 (ja, auf einem Arduino) den ich mit
AVR-GCC und dem Atmel Stuido 7 programmiere.
Um eine Lüfterdrehzahl zu überwachen habe ich mir mit Timer4 und INT4
eine Impulsmessung gebastelt. Der Zähler läuft einfach im Standard-Mode
immer komplett durch und durch INT4 wird er immer auf 0 gesetzt, so das
er nie sein TOP erreicht, solange ein Drehzahlsignal da ist.
Das Funktioniert auch, und die errechnete Drehzahl stimmt auch alles.
Halte ich den Lüfter mit dem Finger an bzw ziehe das Drehzahlsignal ab,
dann wird allerdings der TIMER4-OVF_vect nicht aufgerufen ! Überprüft
habe ich das, indem ich einen Pin beim aufruf toggle und mit dem
Osziloskop visualisiere.
Das Toggeln an sich funktioniert, wenn ich es irgendwo anders aufrufe,
also liegts nicht am Ausgabepin. Der Timer läuft auch über, was ich mir
durch die serielle Ausgabe von TCNT4 angesehen habe.
Aber der verdammte Interrupt wird nicht ausgelösst !
in der main() habe ich natürlich sei() aufgerufen und wird auch nirgends
in der ganzen Software wieder deaktiviert...
Jemand eine Idee oder hab ich was vergessen ? Oder fehlen noch Infos ?
Hier mal meine Init und die ISR's:
1
voidio_init(){
2
3
DDRB|=(1<<PB7);// PB7 - Sys_LED (arduino 13)
4
DDRC|=(1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5);// PB0 bis PB5 Stepper-Interface (arduino 32 bis 37)
5
PORTC|=(1<<PC0)|(1<<PC1);// Disable Stepper
6
7
DDRE&=~(1<<PE4);// Tacho-Input for Motor-Fan
8
PORTE|=(1<<PE4);// Enable Pullup
9
EICRB|=(1<<ISC40);// Any edge of INTn generates asynchronously an interrupt request
10
EIMSK|=(1<<INT4);// Enable INT4 Interrupt
11
12
DDRF|=(1<<PF0);// Debug Output-Pin
13
14
15
}
1
voidtimer4_init(){
2
TCCR4B|=(1<<CS42)|(1<<CS40);// Timer 4 mit Prescaler 1024 starten
Marcel P. schrieb:> ISR (TIMER4_OVF_vect) { // Timeout, also kein puls> registriert. Lüfter steht / Signal unterbrochen.> debugPIN_tgl;> ui8_fan_measure_running = 0;> ui16_rpm_fan = 0;> }
Was ist "debugPIN_tgl;"?
Ein Makro?
Eine gängige Konvention ist eigentlich, Makros mit Grossbuchstaben zu
versehen und zusätzlich wäre es ja hilfreich zu wissen, was sich
dahinter verbirgt.
Die Deklaration der Variablen fehlt noch.
Sind die "volatile"?
Mitlesa schrieb:> Aus dem Datenblatt:>> "The corresponding Interrupt Vector (see “Interrupts” on page 101)> is executed when the TOVn Flag, located in TIFRn, is set."
Danke... das weiss ich... TOV4 in TIFR4 wird auch gesetzt wenn der
Zaehler überläuft. Aber es wird der Interrupt nicht ausgelöst, durch
welchen TOV4 automatisch wieder zurück gesetzt wird !
Datasheet Page 163: TOVn is automatically cleared when the
Timer/Countern Overflow Interrupt Vector is executed.
Der Interrupt ist ja hier auch in timer4_init() aktiviert:
und in der main wird durch sei() auch erlaubt.
Alle anderen Timer im CTC-Mode laufen und die Interrupts werden ja auch
ausgeführt. Nur der dämliche Timer4 nicht...
Rudolph R. schrieb:> Okay, hat mit dem Problem nichts zu tun, aber ich würde ja> PINF = (1<<PF0)>> benutzen.
Wieso ?
Ich schreibe da ja auf einen Ausgang und nicht auf einen Eingang, also
PORTx und nicht PINx !?
dir dauernd das Timer4 Register nullsetzt und du damit nie
in den Überlauf kommst.
Hab jetzt nicht nachgeschaut, aber kann es sein dass dieser
Interrupt explizit gelöscht werden muss? (sonst würde er
beim Verlassen der ISR sofor wieder zuschlagen)
Marcel P. schrieb:>> Okay, hat mit dem Problem nichts zu tun, aber ich würde ja>> PINF = (1<<PF0)>>>> benutzen.>> Wieso ?> Ich schreibe da ja auf einen Ausgang und nicht auf einen Eingang, also> PORTx und nicht PINx !?
Kapitel 13.2.2 vom Datenblatt: "Toggling the Pin".
"Writing a logic one to PINxn toggles the value of PORTxn, independent
on the value of DDRxn. Note that the SBI
instruction can be used to toggle one single bit in a port."
@Arduinoquäler
genau, da setze ich zurück...
Solange da ein Lüftersignal ankommt, wird der auch immer schön
ausgeführt bei jedem Flankenwechsel.
Gelöscht werden muss da nichts.
Es funktioniert alles, ausser der Tatsache das der OVF-Interrupt nicht
gestartet wird....
@rudolph
Ach, faszinierend, das war mir gänzlich unbekannt. Ich kannte das eben
nur so wie ich gemacht habe. Da es so immer funktioniert hat, habe ich
mir nie Gedanken über Alternativen gemacht oder danach gesucht. Danke
dafür !
Hatten wir nicht neulich sowas schon mal? Es stellte sich raus, das die
Kiste so mit Interrupts höherer Priorität beschäftigt war, das es nie
dazu kam, das der fragliche ausgeführt wurde. Check doch mal, wie es
damit bei dir aussieht.
o.O
ich hab mal die anderen Timer deaktiviert (die machen ganz anderen Kram)
und siehe da... ZACK.. es geht !
Verdammt.. dann ist mein µC zu beschaeftigt mit Interrupts. Da muss ich
da das ganze wohl mal überarbeiten.
Vielen Dank @mschoeldgen
Marcel P. schrieb:> dann ist mein µC zu beschaeftigt mit Interrupts.
Man kommt da gar nicht so einfach drauf, weil die AVRs die
Hauptschleife, wenn auch schnarchlangsam, abarbeiten, es wird mindestens
ein Befehl im Hauptprogramm ausgeführt, bevor der nächste anstehende IRQ
ausgeführt wird.
Aber ist ja schön, das es gefunden wurde. Im anderen Thread haben eine
ganze Menge Leute eine ganze Menge gerätselt, weil alles bestens aussah
im geposteten Code - genau wie bei dir.
Ja, aber genau das ist es was dann fehlt.. Erfahrung...
Ich glaube ich wäre da so nie drauf gekommen.
Jetzt muss ich mal sehen, wie ich das zufriedenstellend lösen kann...