Hi,
@shedepe: Die Schleife sollte ein guter Compiler selbst "einbauen".
@damnit: Manche Compiler nehmen das "static" nicht sehr ernst, hast Du mal versucht,
vTeiler global zu definieren ?
mfg
Achim
Hi,
@shedepe: Die Schleife sollte ein guter Compiler selbst "einbauen".
@damnit: Manche Compiler nehmen das "static" nicht sehr ernst, hast Du mal versucht,
vTeiler global zu definieren ?
mfg
Achim
Das Verlassen von main() ist eine ziemlich deutliche Willensbekundung des Programmierers, dass das Programm enden soll. Und daher macht der exit-Code der AVR-Libc auch genau das. Die Interrupts werden abgeschaltet, gefolgt von einer Endlosschleife, also quasi eine Deaktivierung des Controllers.
- - - Aktualisiert - - -
Sorry, aber was ist das denn für ein Quatsch?
Ein C-Compiler, der das static für eine lokale Variable nicht korrekt implementiert, hätte den Namen "C-Compiler" schlicht nicht verdient. Kannst du auch nur ein konkretes Beispiel für dieses "manche Compiler" nennen?
MfG
Stefan
Hi @ all,
erstmal danke für eure Unterstützung.
@shedepe: thx, hab die while (1) - Schleife noch mit eingebaut und es funzt einwandfrei.
mfg
damnit
Kleiner Hinweis. Ein delay_ms(4000); in einer ISR ist wirklich sehr sehr sehr sehr sehr sehr sehr sehr sehr schlecht und sollte um jeden Preis vermieden werden!!!! Du blockierst damit einfach alles.
mfg
@Wsk8, bin mir dessen bewusst.
Der Inhalt in der ISR dient aktuell nur zu Visualisierung (ob Magnetventil komplett durchschaltet).
Kann leider nur Schritt für Schritt programmieren, da ich eben ein Neueinsteiger in diesem Themengebiet bin.
Hallo,
hab den Rat von Wsk8 beherzigt und habe in die Interrupt-Routine einen weiteren Timer eingebaut (ist das so üblich?).
Prinzipiell läuft das Programm, jedoch findet bei jedem zweiten Aufruf der ISR, schon nach ca. einer Sekunde ein Interrupt statt, wodurch PD6 wieder auf Low gesetzt wird.#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h> //Datei interrupt.h einbinden
#include <util/delay.h>
ISR(TIMER1_COMPA_vect) //Interrupt service routine wenn Vergleichswert erreicht ist
{
static uint16_t swTeiler = 0; //Deklarieren von swTeiler
swTeiler++; //Zählschritt einstellen
if (swTeiler == 30) //Wert bis Interrupt ausgelöst wird
{
swTeiler = 0; //Teiler wieder auf 0 setzen
PORTD |= (1<<PD6); //PortD Strom an
TCCR1B |= (1<<WGM12) | (1<<CS12);
TIMSK |= (1<< OCIE1B);
OCR1B = 3094;
sei();
}
}
ISR (TIMER1_COMPB_vect)
{
static uint8_t vTeiler = 0;
vTeiler++;
if (vTeiler == 4)
{
vTeiler = 0;
PORTD &= ~(1<<PD6);
}
}
int main (void)
{
DDRD |= (1<<PD6); //PD6 als Ausgang deklarieren
//Timer konfigurieren
TCCR1B |= (1<<WGM12) | (1<<CS12); //CTC-Mode und Vorteiler auswählen
//Tabelle
TIMSK |= (1<<OCIE1A); //Timer1 auswählen (Output Compare A Match Interrupt Enable
//Interrupt aufrufen, wenn der Vergleichswert erreicht ist
//Tabelle
OCR1A = 3906; //Vergleichswert zur bestimmung einer Sekunde
//Interrupts aktivieren
sei();
int i = 0; //Schleifenvariable deklariert
while(i<2) //Zwei mal wird die Schleife durchlaufen
{
//Zu beginn des Programmstarts, sollen 2 Schmierungen druchgeführt werden
i++;
PORTD |= (1<<PD6);
_delay_ms(3000); //Schmierzeit
PORTD &= ~(1<<PD6);
_delay_ms(3000); //Untebrechung der Schmierung
}
while(1)
{
}
}
Sprich bei jedem ungeraden Interrupt findet der Overflow nach 4 Zählschritten statt und bei jedem geraden schon nach einem.
Kann es mir nicht wirklich erklären?
mfg
Damnit
Lesezeichen