cbg
11.05.2009, 00:25
Hallo!
So, für die Uni muss ich auf 4 verschiedene Arten ein PWM Signal (50us high, 25us low) generieren.
Timer1 mit Prescaler von 8 wird verwendet (F_CPU = 16M).
Bei der Timeroverflow Methode weicht leider mein berechneter Wert für High- und Lowtime vom gemessenen ab. Bei dieser Methode sollen wir nur die berechneten Preload Werte einsetzten ohne Fehlerkorrektur also soll der Wert nicht genau stimmen (25us, 50us).
Der Assemblercode der ISR ist im Anhang (mit Debuginfos von C Datei).
Hier die Ergebnisse von 4 Messungen:
+---------+-----------+----------+---------+
| Messung | High Time | Low Time | Periode |
+---------+-----------+----------+---------+
| 1 | 52.04us | 26.46us | 78.50us |
+---------+-----------+----------+---------+
| 2 | 52.00us | 26.49us | 78.50us |
+---------+-----------+----------+---------+
| 3 | 52.05us | 26.45us | 78.50us |
+---------+-----------+----------+---------+
| 4 | 52.09us | 26.40us | 78.50us |
+---------+-----------+----------+---------+
Da ich in der Main ständig in den Idle Sleep Modus gehe, dauert es mMn
4+4+3 Taktzyklen bis ich den ISR Code erreicht habe (4 cycles PC push, 3 cycles JMP @ Vector Adresse, 4 cycles weil Sleep).
Wakeup-Time hab ich beim Idle Sleep nicht gefunden im Datasheet, sondern nur bei Powerdown und noch einem anderen "tiefen" Modus.
Bis der Pin auf HIGH gesetzt wird, vergehen also:
4+4+3
2+1+1 (lds, and, brne=false)
2 (sbi)
--------
17 cycles
Bis der neue Preload eingetragen ist:
17
1+1+2 (ldi, ldi, rjmp)
1+1 (out, out)
-------
23 cycles
Innerhalb dieser 23 cycles hat der Timer floor(23/8) = 2 increments ausgeführt.
Jetzt läuft der Timer wieder normal weiter, bis der Pin auf LOW geht vergehen folgende cycles:
4+4+3
2+1+2 (lds, and, brne=true)
2 (cbi)
--------
18 cycles
Bis der neue Preload eingetragen ist:
18
1+1 (ldi, ldi)
1+1 (out, out)
--------
22 cycles
Hier ebenfalls 2 increments beim Timer.
Da der Wechsel von HIGH auf LOW und umgekehrt ca gleich schnell erfolgt (nach 17 bzw 18 cycles) und der Preloadwert noch vor dem 24ten cycle eingetragen wird, sollte mMn eine Verzögerung von 2 Timeriterationen (16 cycles) bei HIGH und LOW sein.
Ist es aber nicht, wie man den gemessenen Werten entnehmen kann.
Ich bräuchte nun Hilfe, ich bin mit meinem Latein am Ende. Bei der busywait Variante war alles noch so schön leicht :)
So, für die Uni muss ich auf 4 verschiedene Arten ein PWM Signal (50us high, 25us low) generieren.
Timer1 mit Prescaler von 8 wird verwendet (F_CPU = 16M).
Bei der Timeroverflow Methode weicht leider mein berechneter Wert für High- und Lowtime vom gemessenen ab. Bei dieser Methode sollen wir nur die berechneten Preload Werte einsetzten ohne Fehlerkorrektur also soll der Wert nicht genau stimmen (25us, 50us).
Der Assemblercode der ISR ist im Anhang (mit Debuginfos von C Datei).
Hier die Ergebnisse von 4 Messungen:
+---------+-----------+----------+---------+
| Messung | High Time | Low Time | Periode |
+---------+-----------+----------+---------+
| 1 | 52.04us | 26.46us | 78.50us |
+---------+-----------+----------+---------+
| 2 | 52.00us | 26.49us | 78.50us |
+---------+-----------+----------+---------+
| 3 | 52.05us | 26.45us | 78.50us |
+---------+-----------+----------+---------+
| 4 | 52.09us | 26.40us | 78.50us |
+---------+-----------+----------+---------+
Da ich in der Main ständig in den Idle Sleep Modus gehe, dauert es mMn
4+4+3 Taktzyklen bis ich den ISR Code erreicht habe (4 cycles PC push, 3 cycles JMP @ Vector Adresse, 4 cycles weil Sleep).
Wakeup-Time hab ich beim Idle Sleep nicht gefunden im Datasheet, sondern nur bei Powerdown und noch einem anderen "tiefen" Modus.
Bis der Pin auf HIGH gesetzt wird, vergehen also:
4+4+3
2+1+1 (lds, and, brne=false)
2 (sbi)
--------
17 cycles
Bis der neue Preload eingetragen ist:
17
1+1+2 (ldi, ldi, rjmp)
1+1 (out, out)
-------
23 cycles
Innerhalb dieser 23 cycles hat der Timer floor(23/8) = 2 increments ausgeführt.
Jetzt läuft der Timer wieder normal weiter, bis der Pin auf LOW geht vergehen folgende cycles:
4+4+3
2+1+2 (lds, and, brne=true)
2 (cbi)
--------
18 cycles
Bis der neue Preload eingetragen ist:
18
1+1 (ldi, ldi)
1+1 (out, out)
--------
22 cycles
Hier ebenfalls 2 increments beim Timer.
Da der Wechsel von HIGH auf LOW und umgekehrt ca gleich schnell erfolgt (nach 17 bzw 18 cycles) und der Preloadwert noch vor dem 24ten cycle eingetragen wird, sollte mMn eine Verzögerung von 2 Timeriterationen (16 cycles) bei HIGH und LOW sein.
Ist es aber nicht, wie man den gemessenen Werten entnehmen kann.
Ich bräuchte nun Hilfe, ich bin mit meinem Latein am Ende. Bei der busywait Variante war alles noch so schön leicht :)