Forum: Mikrocontroller und Digitale Elektronik ICR1A/B Unklarheiten


von Kev M. (Gast)


Lesenswert?

Hallo,
ich habe hier im Forum ein Programm gefunden und habe dazu ein paar 
fragen.

https://www.mikrocontroller.net/attachment/highlight/551441

In Zeile 57 und 58 werden die register OCR1A und B mit unterschiedlichen 
Werten beschrieben. Ich habe keine Erklärung gefunden warum das so ist 
besonders weil die beiden Register in Zeile 127 und 128 wieder mit 
anderen Werten beschrieben werden.
Da ist mir aber auch noch einiges unklar. Ich verstehe das OCR1A und B 
die Ausgangspins des Arduino sind. Aber ich verstehe nicht genau was da 
passiert. Kann mir da vielleicht jemand weiter helfen oder schreiben wo 
ich nach der Funktion suchen kann?

von Falk B. (falk)


Lesenswert?

Kev M. schrieb:
> Hallo,
> ich habe hier im Forum ein Programm gefunden und habe dazu ein paar
> fragen.
>
> https://www.mikrocontroller.net/attachment/highlight/551441

Hmm, kommt mir bekannt vor ;-)

> In Zeile 57 und 58 werden die register OCR1A und B mit unterschiedlichen
> Werten beschrieben. Ich habe keine Erklärung gefunden warum das so ist

Hää? Leseschwäche? Schon mal den "Text" am Ende der Zeile gelesen?

> besonders weil die beiden Register in Zeile 127 und 128 wieder mit
> anderen Werten beschrieben werden.

Warum wohl? Auch dort steht ein Kommentar, der einen Hinweis liefert.

> Da ist mir aber auch noch einiges unklar. Ich verstehe das OCR1A und B
> die Ausgangspins des Arduino sind. Aber ich verstehe nicht genau was da
> passiert.

Es wird eine PWM ausgegeben. Diese PWM wird moduliert (verändert). 
Der Modulationsparameter Pulsbreite wird über das Register OCR1A/B 
bestimmt.

> Kann mir da vielleicht jemand weiter helfen oder schreiben wo
> ich nach der Funktion suchen kann?

Im Datenblatt, Abschnitt Timer 1

von Kev M. (Gast)


Lesenswert?

Falk B. schrieb:
> Hmm, kommt mir bekannt vor ;-)

Sehr gut :D

Falk B. schrieb:
> Hää? Leseschwäche? Schon mal den "Text" am Ende der Zeile gelesen?

Mit dem statischen testen ist gemeint, dass das im fertigen Programm gar 
nicht gebraucht wird?

Falk B. schrieb:
> Warum wohl? Auch dort steht ein Kommentar, der einen Hinweis liefert.

Ahh ok ich glaube ich habe es ein bisschen verstanden. i wird bei jedem 
Interrupt um 256 hochgezählt.
1
(int8_t)pgm_read_byte(&sinus[i>>8])
Der Wert wird in Binär um 8 Stellen nach rechts verschoben. Dadurch wird 
das sinus array durchlaufen.
Die Amplitude ist dann die Nachkommastelle? Die 128+ am Anfang habe ich 
auch noch nichts so ganz verstanden.

von Falk B. (falk)


Lesenswert?

Kev M. schrieb:
> Falk B. schrieb:
>> Hää? Leseschwäche? Schon mal den "Text" am Ende der Zeile gelesen?
>
> Mit dem statischen testen ist gemeint, dass das im fertigen Programm gar
> nicht gebraucht wird?

BINGO!

> Falk B. schrieb:
>> Warum wohl? Auch dort steht ein Kommentar, der einen Hinweis liefert.
>
> Ahh ok ich glaube ich habe es ein bisschen verstanden. i wird bei jedem
> Interrupt um 256 hochgezählt.(int8_t)pgm_read_byte(&sinus[i>>8])

Nein. I wird um den Wert frequenz hochgezählt.

> Der Wert wird in Binär um 8 Stellen nach rechts verschoben. Dadurch wird
> das sinus array durchlaufen.

Ja.

> Die Amplitude ist dann die Nachkommastelle?

Nein. Die Amplitude ist der Wert aus der Tabelle. Der Index zur Tabelle 
sind die oberen 8 Bit von i.

> Die 128+ am Anfang habe ich
> auch noch nichts so ganz verstanden.

Das ist der Mittelwert der PWM, denn die kann keine negativen Werte des 
Sinus ausgeben. Also legt man die gedachte Nullinie auf die Hälfte des 
Maximums, hier 128. Die PWM arbeitet dann im Bereich von 0-255, anstatt 
von -128 bis 128.

von Kev M. (Gast)


Lesenswert?

Perfekt danke.

Falk B. schrieb:
> Nein. Die Amplitude ist der Wert aus der Tabelle. Der Index zur Tabelle
> sind die oberen 8 Bit von i.

Aber der Wert aus der Tabelle wird dann mit dem Wert der Variable 
amplitude multipliziert um so dann die Amplitude des Ausgangssignals zu 
verändern?

von Falk B. (falk)


Lesenswert?

Kev M. schrieb:
> Aber der Wert aus der Tabelle wird dann mit dem Wert der Variable
> amplitude multipliziert um so dann die Amplitude des Ausgangssignals zu
> verändern?

Ja, stimmt. Aber deine Aussage

"Die Amplitude ist dann die Nachkommastelle"

ist trotzdem falsch und sinnlos.
1
  i += frequenz;
2
  OCR1A = 128+(((int8_t)pgm_read_byte(&sinus[i>>8])*(int16_t)amplitude)>>8);

index i um 8 Bit nach recht schieben
Wert aus sinustabelle auslesen
mit amplitude multiplizieren
das Ergebnis um 8 Bit nach recht schieben
128 addieren

Hier wird zwei mal das Prinzip der Festkommaarithmetik verwendet, 
sowohl for den Tabellenindex als auch die Berechnung des aktuellen 
Sinuswertes. Die Nachkommastellen (hier untere 8 Bit) braucht man zum 
Rechnen, um die Auflösung zu verbessern, nutzt sie aber nicht für die 
Ausgabe.

von Kev M. (Gast)


Lesenswert?

Falk B. schrieb:
> Ja, stimmt. Aber deine Aussage
>
> "Die Amplitude ist dann die Nachkommastelle"
>
> ist trotzdem falsch und sinnlos.

Da gebe ich dir recht. Danke für die Hilfe. Mir ist einiges klarer 
geworden.

von Wolfgang (Gast)


Lesenswert?

Kev M. schrieb:
> Ich verstehe das OCR1A und B die Ausgangspins des Arduino sind.

Sind sie nicht. OCR1A und B sind Register (Output Compare Register), 
deren Wert mit dem Zählerstand des Timers verglichen werden.

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.