Wieso Interrupt? benötigt ein Timer einen Interrupt???
Auf jeden Fall belegen deine 4 PWMs da alle 4 Timer. Du kannst höchstens noch einen Softwaretimer machen, aber frag jemand anders, wie das funzt. C kann ich nicht so gut.
Hallo,
mal eine Verständnisfrage: Ich benutze einen ATMEGA16
zur Erzeugung von 4 PWM für 4 Motoren. Jetzt würde ich
gerne noch einen Timer benutzen, zum Beispiel um noch
eine Status-LED blinken zu lassen. Geht das jetzt überhaupt
noch, oder blockieren meine 4 PWM jetzt alle Timer/Counter
Kanäle, von denen der ATMEGA16 ja nur 4 Stück hat (2x8bit,
1x16bit,1xreal_time_counter[?])???
Sind Interupt-Routinen davon auch betroffen?
Gruß
RICOLA
Wieso Interrupt? benötigt ein Timer einen Interrupt???
Auf jeden Fall belegen deine 4 PWMs da alle 4 Timer. Du kannst höchstens noch einen Softwaretimer machen, aber frag jemand anders, wie das funzt. C kann ich nicht so gut.
o
L_
OL
This is Schäuble. Copy Schäuble into your signature to help him on his way to Überwachungsstaat!
http://de.youtube.com/watch?v=qV1cZ6jUeGE
Wenn einer deiner Timer durchläuft und nicht durch einen PWM Mode automatisch wieder genullt wird, oder rückwärts läuft, kannst du den Timer Overflow Interrupt dieses Timers aktivieren und einen Zähler hochzählen.
Wenn dieser Zähler dann einen bestimmten Wert erreicht hat kannst Du den Zustand eines Ausgangs toggeln den Zählerstand des Softwarezählers (nicht! das TCNT Register) auf 0 setzen und damit eine LED zum blinken bringen.
Die Routine braucht nur ein paar Bytes und dürfte den Ablauf deines Programmes nicht allzusehr stören.
hallo wgrug,
das ist genau was ich brauche! könntest du es noch ein wenig konkretisieren bitte!? In etwa so hier? Geht dann das PWM noch?
// Initialisierung:
TCCR2 = (1<<CS22);
TCNT2 = 183;
TIMSK |= (1<<TOIE2);
SIGNAL(SIG_SIG_OVERFLOW2)
{
countTimer2++;
}
Danke und Gruß
RICOLA
Die Antwort hast Du dir mit diesem Post vermutlich schon selbst gegeben.hallo wgrug,
das ist genau was ich brauche! könntest du es noch ein wenig konkretisieren bitte!? In etwa so hier? Geht dann das PWM noch?
// Initialisierung:
TCCR2 = (1<<CS22);
TCNT2 = 183;
TIMSK |= (1<<TOIE2);
SIGNAL(SIG_SIG_OVERFLOW2)
{
countTimer2++;
}
Mit dem Timer 2 wird das nicht gehen wenn auf dieses Register auch noch anderweitig geschrieben wird und dadurch kein Überlauf zstande kommt?
Es kommt auch auf den gewählten PWM Mode an.
Diese Modes kenne ich:
Bei manchen Modes Zählt das TCNT2 Register bis zum Comparewert hoch und wird dann Hardwaremässig genullt - CTC.
In einem anderen PWM Mode Zählt der Zähler bis zum Comparewert vorwärts und dann wieder rückwärts.
In wieder einem anderen Mode Zählt der Zähler bis 0xFF und dann wieder auf 0x00.
Alle diese Modes erzeugen normalerweise keinen! Timer Overflow Interrupt und sind somit nicht geeignet.
Das TCNT2 Register muss Hochzählen bis der Zählerstand von 0xFF wieder auf 0x00 Überläuft, nur dann wird ein Timer Overflow Interrupt erzeugt (=Fast PWM Mode + Phase Correct PWM Mode).
Hast Du in einem deiner Timer, diesen PWM Mode eingestellt ???
Wenn nicht wird es so nicht funktionieren.
Eine weitere Option wäre es einen Comparematch Interrupt freizugeben und hier den Zähler hochzuzählen.
Das hätte aber den Nachteil, das bei Extremwerten des PWM (0x00 + 0xFF) unter Umständen dieser Interrupt nicht anspricht.
hmmm, ich initialisiere den PWM-Kanal mit
// 8bit Kanal
TCCR0 = (1<<WGM00)|(1<<COM01)|(1<<CS01);
??
Gruß
RICOLA
Mit diesen Einstellungen wird kein Timer Overflow Interrupt generiert, wohl aber ein Comparematch Interupt.// 8bit Kanal
TCCR0 = (1<<WGM00)|(1<<COM01)|(1<<CS01);
Du musst diesen Interrupt nur im TIMSK freigeben die Vektoren in deinem Compiler anlegen und darin die Comparematch Routine (deine blinkende Led) anlegen.
hmmm, ich lese dazu folgendes:
When the OCIE0 bit is written to one, and the I-bit in
the Status Register is set (one), the Timer/Counter0
Compare Match interrupt is enabled.
When the I-bit in SREG, OCIE0 (Timer/Counter0 Compare
Match Interrupt Enable), and OCF0 are set (one), the
Timer/Counter0 Compare Match Interrupt is executed.
also folgender Code?
TIMSK = (1<<OCIE0);
SREG = (1<<I);
TIFR = (1<<OCF0);
das mit den vektoren verstehe ich aber nicht. wo lege
ich die denn im compiler an? und wo ist die funktion, die
jetzt von dem interrupt aufgerufen wird?
ich finde das hier:
No:20 Addr:$026 TIMER0 COMP Timer/Counter0 Compare Match
DANKE!!
Gruß
RICOLA
Mit dem I Flag im SREG gibt es ein eigenes Assembler Kommando
#asm ("SEI");
Wie bei deinem Compiler Interrupts angelegt werden kann ich Dir nicht sagen, sollte aber auf jeden Fall im Compiler Handbuch stehen.
Bei Codevision geht das so:
interrupt [EXT_INT0] void ext_int0_isr(void)
{
dein Code;
}
Ist aber bei jedem Compiler anders.
Hallo,
war eigentlich ganz einfach, musste nur
TIMSK |= (1<<OCIE1A);
sei();
eingeben und hatte dann schon den SIG_OUTPUT_COMPARE1A
Compare Match Timer an. PWM funktionieren noch tadellos. Muss
mir halt nur die Zeitbasis selber mit Inkrementen mitzählen.
Danke also!
PS: Das Anlegen der Vektoren mach avr-gcc ganz von allein!
Gruß
RICOLA
Lesezeichen