Guten Tag,
ich habe ein STK600 Board und einen ATMega2560 MicroController und will
davon aus ein VGA Signal zu einem normalen Monitor aufbauen.
Ich bekomme bereits das vertikale und horizontale Signal hin und auch
einzelne Farbsignale gehen schon, sodass der ganze Monitor blau,rot oder
grün sein kann. Jedoch immer nur eine Farbe auf einmal.
Für das vertikale und horizontale Signale benutze ich separate Timer
(Timer 0 (8bit) und Timer 1(16bit)) mit jeweils 16MHz. Und ebendiese
Signale erzeuge ich mit FastPWM.
Das Farbsignal bekommen wir hin, wenn wir eines des RGB Kabel mit an an
das horizontale Signal klemmen. Vermutlich könnte man einfach einen 3.
Timer mit einbauen und darüber die Farbsignale laufen lassen.
Damit wir lediglich mal einzelne Pixel mit Farbe befeuern können, will
ich vom horizontalen und vertikalen Signal auch noch auf die ISR
Funktionen zugreifen. Doch die Anweisungen in der ISR Funktion führt er
nicht aus.
Erst wenn ich sei() in den Quellcode mit einfüge, funktionieren die
ISR-Funktionen, aber die PWM-Signale werden dadurch nicht mehr
ausgegeben.
Ich wollte nun fragen, ob es möglich ist, *dass man einen Fast-PWM
und einen Timer-Overflow-Interrupt* (und dann mit der entsprechenden
ISR-Funktion arbeiten) auf dem gleichen Timer konfigurieren kann.
Nur zur Verdeutlichung, damit ihr wisst, wohin das Ganze führen
soll:
Das Endziel sollte irgendwann sein, dass ich farbige einfach Grafiken
darstellen kann. Wie z.B. eine Sonne oder die Uhrzeit oder Ähnliches.
Wenn die Grafiken dann nur 120x60 Pixel haben wäre das auch in Ordnung.
Ich habe mich bisher stark an diese Vorgehensweise hier gehalten:
https://www.gammon.com.au/forum/?id=11608
Hier noch mein aktueller Quellcode:
Ano N. schrieb:> Ich wollte nun fragen, ob es möglich ist, dass man einen Fast-PWM> und einen Timer-Overflow-Interrupt (und dann mit der entsprechenden> ISR-Funktion arbeiten) auf dem gleichen Timer konfigurieren kann.
Warum zweifelst du daran?
Steht doch so im DB Figure 17-2 für Mode 14+15:
-TOVn Flag Set on: TOP -> Timer-Overflow-Interrupt
TOP ist wahlweise ICRn (14) oder OCRnA (15)
Für mehr graphisch veranlagte Menschen auch als Timing Diagram: Figure
17-7
void schrieb:> Ano N. schrieb:>> Ich wollte nun fragen, ob es möglich ist, dass man einen Fast-PWM>> und einen Timer-Overflow-Interrupt (und dann mit der entsprechenden>> ISR-Funktion arbeiten) auf dem gleichen Timer konfigurieren kann.>> Warum zweifelst du daran?> Steht doch so im DB Figure 17-2 für Mode 14+15:> -TOVn Flag Set on: TOP -> Timer-Overflow-Interrupt> TOP ist wahlweise ICRn (14) oder OCRnA (15)
Ok TOVn haben wir bereits für beide Timer gesetzt. Ebenso OCRnA, da wir
den Timer 1 mit dem Mode 15 benutzen. Müsste jetzt unsere ISR Funktion
dann nicht anspringen?
> Für mehr graphisch veranlagte Menschen auch als Timing Diagram: Figure> 17-7>>
1
>ISR(TIMER1_OVF_vect){
2
>PORTL=0xFF;
3
>}
4
>
>> Die Port pins toggeln so aber nicht, oder?
Da hatte ich noch einen kleinen Fehler vom Rumspielen im Code drinnen.
Soll natürlich PORTL ^= 0xFF; heissen.
Hi
>Müsste jetzt unsere ISR Funktion dann nicht anspringen?
Nrin. Bei Fast PWM gibt es nur den Overflow Interrupt, nämlich wenn
OCR1A bzw. ICR den Topwert erreicht hat.
>Da hatte ich noch einen kleinen Fehler vom Rumspielen im Code drinnen.>Soll natürlich PORTL ^= 0xFF; heissen.
PIN-Toggle geht beim ATMega2560 einfacher:
PINL = 0xFF;
MfG Spess
> Nrin. Bei Fast PWM gibt es nur den Overflow Interrupt, nämlich wenn> OCR1A bzw. ICR den Topwert erreicht hat.
Und die ISR Funktion greift diesen Overflow Interrupt nicht ab? Also der
Code der ISR Funktion wird nicht bei diesem Interrupt ausgeführt?
1
ISR(TIMER1_OVF_vect)
Wenn Nein, hast du dann eine Idee wie wir unser Vorhaben erreichen
können? Also Fast PWM auf nem Timer UND zusätzlich noch eine ISR
Funktion benutzen, die unseren eigenen Code ausführt.
HI
>Und die ISR Funktion greift diesen Overflow Interrupt nicht ab? Also der>Code der ISR Funktion wird nicht bei diesem Interrupt ausgeführt?
Wieso nicht. Sieh dir mal im Datenblatt die Kapitel
Modes of Operation -> Fast PWM Mode in den Timerkapiteln an.
MfG Spess
> Wieso nicht. Sieh dir mal im Datenblatt die Kapitel
Als ich dich fragte ob die ISR Funktion jetzt nicht anspringen müsste
hast du verneint. Klang für mich so als wäre das dann gar nicht möglich.
Jetzt sagst du mir, dass es möglich ist. Das Handbuch habe ich schon oft
zu Rate gezogen, aber es steht für mich noch sehr viel kryptisches
drinnen.
Kannst du mir konkrete Hinweise geben, warum in meinem Code die ISR
Funktion nicht ausgeführt wird?
Ich bin noch sehr neu auf dem Gebiet der Elektrotechnik und ich hoffe
ihr könnt mir meine tölpelhafte Ausdrucksweise verzeihen. Und auch, dass
ich nicht alles auf Anhieb verstehe oder es gar missverstehe.
Matthias S. schrieb:> Ano N. schrieb:>> TIMSK2 = (1 << TOIE2);>> Mir fällt auf, das dieser Interrupt nicht behandelt wird. Du brauchst> noch eine ISR (TIMER2_OVF_vect).
Ich habe jetzt den ISR für den Timer 2 noch eingerichtet. Leider ändert
sich dadurch nichts.
Um den ISR zu testen, versuche ich die LED's in den beiden ISR
Funktionen wieder anzuschalten.
Dafür initialisiere ich den PORTD mit:
1
DDRD=0xFF;
2
PORTD=0xFF;// 0xFF = LED's aus
Und schalte in den ISR-Funktionen den Port auf 0x00;
1
ISR(TIMER1_OVF_vect){
2
PORTD=0x00;
3
}
4
5
ISR(TIMER2_OVF_vect){
6
PORTD=0x00;
7
}
Dadurch sollten sich eigentlich die LED's anschalten, diese bleiben aber
leider dunkel.
Ich bin mir ziemlich sicher, dass die ISR-Funktionen einfach nicht
getriggert werden.
Fehlt vielleicht noch etwas in der Konfiguration?
Ano N. schrieb:> Ich bin mir ziemlich sicher, dass die ISR-Funktionen einfach nicht> getriggert werden.
Nicht weiter verwunderlich bei auskommentiertem sei().
Stefan E. schrieb:> Ano N. schrieb:>> Ich bin mir ziemlich sicher, dass die ISR-Funktionen einfach nicht>> getriggert werden.>> Nicht weiter verwunderlich bei auskommentiertem sei().
Das habe ich bereits oben im ersten Beitrag beschrieben.
Sobald sei() aktiviert ist, werden die PWM-Signale nicht mehr
ausgegeben.
Ano N. schrieb:> Sobald sei() aktiviert ist, werden die PWM-Signale nicht mehr> ausgegeben.
Na das ist doch schonmal ein gutes Zeichen.
Es werden also Interrupts aufgerufen, für die Du keinen Handler
hinterlegt hast und dadurch startet Dein Programm ständig neu.
Früher hat man mal paar Breakpoints gesetzt, und das ganze vernünftig
debugged....
Geht das heutzutage denn nicht mehr?
ist doch eigentlich viel einfacher und spassiger, als sich hier
krampfhaft im Forum abzumühen...
Peter D. schrieb:> Na das ist doch schonmal ein gutes Zeichen.> Es werden also Interrupts aufgerufen, für die Du keinen Handler> hinterlegt hast und dadurch startet Dein Programm ständig neu.
Danke für die Info.
Nach meinem Wissen setzte ich nur die Interrupts für Timer1 & Timer2.
Diese fange ich aber mit den beiden Funktionen ab:
1
ISR(TIMER1_OVF_vect){
2
PORTD=0x00;
3
}
4
5
ISR(TIMER2_OVF_vect){
6
PORTD=0x00;
7
}
Hast du vielleicht irgendwelche Tipps, wie ich die überflüssigen
Interrupt-Befehle herausfinden und abdecken kann?
Peter D. schrieb:> Scheint o.k. zu sein. Schau mal ins .lss-File da müßte sowas drin> stehen:
Nochmals vielen Dank. Klappt jetzt alles prima.
Ich habe jetzt einfach zusätzlich den vector_default verwendet, um das
Problem zu lösen:
1
ISR(__vector_default)
Wäre das so sauber gelöst, oder gibt es noch eine bessere Variante?
Ich habe mir auch mal das .lss-File noch ein wenig genauer angesehen.
Kann ich davon ausgehen das 0xf8 eine Addresse ist?
Ano N. schrieb:> Wäre das so sauber gelöst, oder gibt es noch eine bessere Variante?
Einen Fehler zu verstecken, ist niemals eine Lösung.
Du kannst ja nichtmal feststellen, ob beide Handler überhaupt aufgerufen
werden.
Laß das Programm dochmal im Simulator laufen.
Peter D. schrieb:> Einen Fehler zu verstecken, ist niemals eine Lösung.
Geb ich dir vollkommen Recht.
Peter D. schrieb:> Du kannst ja nichtmal feststellen, ob beide Handler überhaupt aufgerufen> werden.
Warum nicht? Man kann z.B. die Pins auch einzeln ansteuern.
1
ISR(TIMER1_OVF_vect){
2
3
PORTD^=1<<PB1;
4
}
5
6
ISR(TIMER2_OVF_vect){
7
8
PORTD^=1<<PB0;
9
}
Peter D. schrieb:> Laß das Programm dochmal im Simulator laufen.
Da passiert bei mir reichlich wenig. Der Simulator ruft nie die
ISR-Funktionen auf. (Ja, ich habe auch oft genug gedrückt).Ich denke es
wird eine Option im Debugger geben, aber da werde ich morgen mal drüber
schauen.
Ano N. schrieb:> Hast du vielleicht irgendwelche Tipps, wie ich die überflüssigen> Interrupt-Befehle herausfinden und abdecken kann?
Zu diesem Zweck kann man Dummy ISR in GCC basteln:
1
EMPTY_INTERRUPT(TIMER0_OVF_vect);
2
// ISR stub for unused irqs. The AVRs sometimes need to fire an interupt and
Ich bin da anscheinend auch mal drüber gestolpert, das die OC Register
nicht das gemacht haben, was ich wollte. Aus einem Quelltext für ein
BLDC Projekt.