Hallo Leute!
Ich sitze grad an einer eigentlich einfachen Aufgabe, bei der aber
komische Fehler auftreten.
Was will ich:
Ein Rechtecksignal mit einstellbarer Frequenz und einstellbarer
Impulsweite (quasi Duty-Cycle)
Zum Quellcode:
1 | ISR(TIMER1_COMPB_vect)
|
2 | {
|
3 | TCCR1A |= (1<<FOC1A);/*force output compare A*/
|
4 | }
|
5 |
|
6 | void main()
|
7 | {
|
8 | DDRD |= (1<<PD5); /*OC1A as output*/
|
9 | OCR1A=15999;
|
10 | OCR1B=15839;
|
11 |
|
12 | TCCR1B |= (1<<WGM12)|(1<<CS10); /*CTC active (OCR1A), CPU-Clock*/
|
13 | TCCR1A |= (1<<COM1A0); /*toggle OC1A on OCR1A match*/
|
14 | TIMSK |= (1<<OCIE1B); /*interrupt on OCR1B match*/
|
15 | sei();
|
16 | }
|
Erklärung:
Der Timer (CPU-Clock:16MHz) wird ständig bei 15999 resetet, was zu einer
Periodendauer von 15999/16MHz=9.999*exp(-4) führt. Also 1KHz. Zusätzlich
wird bei 15999 der bin OC1A getogglet.
Bei 15839 wird ein Interrupt ausgeführt, der auch OC1A togglet. (Löst
eine Compare-match Erreignis von OCR1A aus).
Soweit so gut. Bei großer Impulsdauer (OCR1B klein) ist das alles auch
exakt genug. Mit 15839 kommt jedoch nicht 10us, sondern eine Impulsdauer
von 8.8us heraus.
Interessant ist auch, dass wenn ich die Optimierung vom AVR-Studio
aussschalte, die Zeit sich plötlich uaf 7.7us ändert.
Hab ich da irgendwo einen Denkfehler?
Viele Dank für eure Hilfe!
Denglmann