Forum: Mikrocontroller und Digitale Elektronik falsches Timing


von Denglmann (Gast)


Lesenswert?

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

von Nn N. (jaytharevo)


Lesenswert?

Taktest du mit dem internen Takt?
Und um welchen Kontroller handelt es sich?

von Denglmann (Gast)


Lesenswert?

Ne isn extern 16MHz Quarz
Arbeite mit nem ATmega 32, sorry vergessen anzugeben.

Aber ich bin schon weiter gekommen:
Es könnte sein das der Controller Probleme damit hat, dass ich bei nem 
Match mit OCR1A sowohl eine Aktion auslöse (Pin togglen), als auch den 
Timer auf 0 setze.
Theorie zwei:
Das Forcen des Matches (TCCR1A |= (1<<FOC1A);/*force output compare 
A*/), klappt eventuell nicht so gut.

Ich hab jetzt einfach mal zwei Interrupts eingefügt: einen bei nem Match 
von OCR1A und einen bei OCR1B. Bei einem Interrupt schalt ich den Pin 
ein, beim andren aus. Zusätzlich wird beim Interrupt mit OCR1A der Timer 
per Hand gelöscht.
Find ich zwar nicht so schön, aber so klappts....

von spess53 (Gast)


Lesenswert?

Hi

>Ein Rechtecksignal mit einstellbarer Frequenz und einstellbarer
>Impulsweite (quasi Duty-Cycle)

Und warum benutzt du dann nicht einen PWM-Mode mit variablen Top-Wert 
(14 oder 15)?

MfG Spess

von Denglmann (Gast)


Lesenswert?

Ich hab mir vor einiger Zeit mal drüber Gedanken gemacht und bin zu dem 
Schluss gekommen, dass es damit nicht geht.
Jetzt wenn ichs mir aber nochmal anschau, sollte es doch gehn.

Allerdings blick ich noch nicht ganz durch:
Mode 15, Fast PWM: OCR1A bestimmt den Top Wert und welches Register 
bestimmt mir die Zeit der andren Flanke? Oder muss ich das OCR1A ständig 
umladen??
Im Datenblatt Seite 100 wird eine Toggle ausgelöst, ohne dass der Timer 
resetet wird, aber wo steht dieser Wert?

von spess53 (Gast)


Lesenswert?

Hi

Mode14: OCR1A Top-Wert -> bestimmt Frequenz
        OCR1B OC-Wert  -> bestimmt Pulsdauer (Signal an OC1B-Pin)

Mode14: ICR1  Top-Wert -> bestimmt Frequenz
        OCR1A OC-Wert  -> bestimmt Pulsdauer (Signal an OC1A-Pin)
        OCR1B OC-Wert  -> bestimmt Pulsdauer (Signal an OC1B-Pin)

MfG Spess

von Denglmann (Gast)


Lesenswert?

Vielen Dank! Muss ich in Ruhe noch mal durchdenken!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.