Forum: Mikrocontroller und Digitale Elektronik Pwm periode Timer1 einstellen.


von Patrick (Gast)


Lesenswert?

Hallo,

Ich Sitz gerade an meinen Uni Klamotten und häng gerade an einer 
Aufgabe, vielleicht könnt ihr mir helfen.

Und zwar gegeben ist ein UC Atmega 16-16 mit einen 8MHz cystal. Nun soll 
über eine PWM 2 Ausgänge bedient werden, mit den Timer1 die PWM soll 
eine Länge haben von 100kHz Periode und der Ausgang 1 oc1a soll mit 50% 
laufen der oc1b mit 25% ein zeit.

Bisher habe ich ein Prescaller von 1:8 um auf 1 MHz ich hab auf 8 bit 
Phasen korrekte PWM gestellt hab die oc1a und oc1b als Ausgang gesetzt 
hab die Werte für die Ausgänge auf oc1a mit 127 und oc1b auf 63 
gestellt, damit lässt sich schonmal das Verhältnis mit 50% und 25% 
realisieren ctc ist auch an, und jetzt kommt das Problem durch den 
Vorteiler komme ich auf eine Periode mit 1Mhz, mit welchen Register kann 
ich diese 1 MHz auf 100khz setzten bzw gibt es eine Möglichkeit Zusagen 
das der Timer nicht bis 255 läuft sonder nur bis 26 dann hätte ich ja 
die 100khz und brauch dann nur die Werte für oc1a und oc1b anpassen wäre 
ja 13 und 6.

von spess53 (Gast)


Lesenswert?

Hi

>mit welchen Register kann
>ich diese 1 MHz auf 100khz setzten bzw gibt es eine Möglichkeit Zusagen
>das der Timer nicht bis 255 läuft sonder nur bis 26 dann hätte ich ja
>die 100khz und brauch dann nur die Werte für oc1a und oc1b anpassen wäre
>ja 13 und 6.

Timer-Mode 14 (WGM-Bits in TCCR1A/TCCR1B).

MfG Spess

von Patrick (Gast)


Lesenswert?

Sind diese Bits nicht nur zum einstellen des Modus gedacht also in mein 
Fall Phasen korrekte PWM mit 8Bit.

Dafür muss ich ja das WGM10 setzten.

Und das WGM12 für CTC

Nur wie bekomm ich jetzt damit eine untersetztung hin.

von spess53 (Gast)


Lesenswert?

Hi

>Sind diese Bits nicht nur zum einstellen des Modus gedacht also in mein
>Fall Phasen korrekte PWM mit 8Bit.

Ich war bei 'TimerMode14' von von Fast PWM ausgegangen. Bei Phase 
Correct PWM wäre es Timermode10.

Die Frequenz der PWM wird über den Wert in ICR1 (Top) eingestellt.

MfG Spess

von Patrick (Gast)


Lesenswert?

Also ich Versuch mal zu schreiben was ich jetzt hab
1
TCCR1A = (1<<WGM10) ;/*8bit PWM */
2
TCCR1A = (1<<COM1A1) | (1<<COM1B1); 
3
TCCR1B = (1<<CS10) | (1<<CS12); /* Prescaller 1024 Frequenz der Periode (8Mhz /1024)* 256 Schritte = Frequenz PWM 2MHz*/
4
5
orc1a = 6; /*50% ein*/
6
orc1b = 3; /*25% ein*/

Jetzt muss ich den Timer nur noch dazu bringen bis 13 laufen zu lassen 
und dann wieder mit 0 beginnen lassen.

Also Timer für orc1a zB high für 0-6 und Low für7-13. dann von vorne.

von Patrick (Gast)


Lesenswert?

Ah also damit ich das jetzt richtig verstehe steht im tcnt1 (h/l) jetzt 
die Zahl 255 als Obergrenze wenn ich dieses jetzt auf 13 änder dann 
läuft der Zähler nur bis 13?

von Patrick (Gast)


Lesenswert?

Ups lese Fehler xD iCR1 h und L meinte ich

von Patrick (Gast)


Lesenswert?

Mal so eine Frage am Rande was macht man eigentlich wenn der Prescaller 
nicht mehr ausreicht zB wenn ich eine Taktfrequenz von 8 MHZ habe und 
mit Prescaller 1024 dran gehe hab ich ja immer noch pro Takt eine 
Frequenz von etwas mehr als 7kHz wenn ich aber 50Hz Schritte haben 
möchte, was muss ich den dann tun?

von spess53 (Gast)


Lesenswert?

Hi

>TCCR1A = (1<<WGM10) ;/*8bit PWM */

Du willst aber keine 8-Bit-PWM sondern eine mit einstellbaren Top-Wert

>TCCR1A = (1<<COM1A1) | (1<<COM1B1);

Damit überschreist du die vorherige Einstellung gnadenlos.

>TCCR1B = (1<<CS10) | (1<<CS12);

Damit läuft der Timer mit 7,8125 kHz. Wie willst du dann eine PWM mit 
100kHz hinbekommen? Benutze den Vorteiler 1.

Dann bekommst du mit ICR=40 und orc1a = 20 50% und orc1b = 10 deine 25%;

MfG Spess

von Patrick (Gast)


Lesenswert?

Also die beiden TCCR1A sind beidenzusammen geschrieben damit sich nix 
überschreibt, hatte es zur Übersicht nur getrennt.

Nur beim Rest versteh ich gerade nur Bahnhof

von Shaggy (Gast)


Lesenswert?

Mal anders gefragt wie würde den eine init Code aussehen wenn ich aus 
den 8Mhz Grund Frequenz eine 50Hz machen müsste. Natürlich wieder eine 
pwm
Oc1a und oc1b als Ausgang.

Mit ocr1a und b kann man ja wieder ein zeit einstellen.

von Patrick (Gast)


Lesenswert?

Ach zu deiner 7khz Periode wird die Periode nicht so berechnet:

Periode Frequenz = (f_cpu/prescaller)*schritte bis top

Also als Bsp bei 8bit Zähler

Pfreq = (8Mhz / 1024)*256schritte = 2Mhz

von Patrick (Gast)


Lesenswert?

Bzw wenn man die Dauer sieht wären das bei 2Mhz ja 5*10^-7 Sekunden pro 
Periode.

von spess53 (Gast)


Lesenswert?

Hi

>Nur beim Rest versteh ich gerade nur Bahnhof

Im Datenblatt aus S.106 findest du eine Formel. Wenn du dort für

fOCnxPCPWM   100kHz
fclk_I/O     8MHz
N            1

einsetzt bekommst du für TOP den Wert 40. Das ist der Wert bis zu dem 
der Timer für eine PWM-Periode aufwärts und wieder auf Null zählen muss. 
Und dieser Wert steht beim Mode10 in ICR1.

MfG Spess

von Patrick (Gast)


Lesenswert?

Ok, das macht Sinn aber damit kann man doch nur eine 50% Regelung machen 
oder seh ich das wieder falsch?

von Patrick (Gast)


Lesenswert?

|----|
|.   |
|.   |______
0  Ocr1a.  Max
Wenn das meine Periode ist, gibt ja ocr1a den Wert an wo der Pegel 
Wechsel statt findet.

Von Max soll er ja auf 0 springen und am Ausgang wieder auf High 
schalten.

Mit den ocr1a wert kann ich doch jetzt die Einzeit Variable verstellen 
von 0 bis Max.

Nur wo lege ich den Wert Max fest?

von spess53 (Gast)


Lesenswert?

Hi

>Ok, das macht Sinn aber damit kann man doch nur eine 50% Regelung machen
>oder seh ich das wieder falsch?

Ja, siehst du falsch. Bei einem Topwert von 40 kannst du Werte in 
Abstufungen von 2,5% einstellen.

MfG Spess

von Patrick (Gast)


Lesenswert?

|----|
|    |
|    |-----
0  ORC1A  ICR1

also sieht das ganze so aus?

was pasiert dann, hab das jetzt so verstanden, dass der Anlauf so 
aussieht

0---> ORC1A----->ICR1 ------> ORC1A---->0.

oder läuft er doch:

0---> ORC1A----->ICR1/0---->ORC1A------->ICR1/0.

von spess53 (Gast)


Lesenswert?

Hi

>0---> ORC1A----->ICR1 ------> ORC1A---->0.
>oder läuft er doch:
>0---> ORC1A----->ICR1/0---->ORC1A------->ICR1/0.

Welches Verhalten stellst du denn bei 'Phase Correct PWM' ein?

Lies dir einfach noch mal die entsprechenden Stellen im Datenblatt 
durch.

MfG Spess

von Patrick (Gast)


Lesenswert?

Erstmal schonmal vielen Dank für deine mühe ich versuch mir das mal mit 
mein Board jetzt nach zustellen, wäre schön, wenn du einmal ein blick 
drauf werfen kannst.

HW: Atmega 16 mit 16Mhz Quarz

hab jetzt an den ausgängen 2 LED angeschlossen eine an OC1A die andere 
an OC1B. Ich versuch das ganze mal mit ner fast PWM, da mir die Funktion 
einfacher fällt.
nun der Code
1
/* fpwm = F_CPU/(Prescaller*Obergrenze)*/
2
TCCR1A |= (1<<WGM13)|(1<<WGM12)|(1<<WGM11)|(1<<COM1A1)|(1<<COM1B1); /* Modus 14: Fast PWM mit beliebiger Schrittzahl (festgelegt durch ICR1)*/
3
TCCR1B |= (1<<CS12) | (1<<CS10); // Prescaler 1024 = Enable counter
4
5
ICR1 = 31250;  /* Obergrenze */
6
7
OCR1A = 31250/2; /* Einschaltzeit PD6 50%*/
8
OCR1B = 31250/4; /* Einschaltzeit PD5 25%*/
9
10
DDRD |= (1<<PD5) | (1<<PD6);

nun müsste ich doch eine Frequenz von 0,5Hz haben oder?

also müsste die LED an PD6 doch 1s ein 1s aus sein?

von S. Landolt (Gast)


Lesenswert?

WGM13 und 12 befinden sich in TCCR1B.
OC1A liegt auf PD5, OC1B auf PD4.

(Spess möge entschuldigen, aber es beschleunigt die Sache vielleicht)

von Patrick (Gast)


Lesenswert?

Oh die ports waren richtig bei mir hatte hier nur ein schreib fehler 
drin.

das mit WGM12 und 13 hat geholfen;
1
TCCR1A |= (1<<WGM11)|(1<<COM1A1)|(1<<COM1B1); /* Modus 14: Fast PWM mit beliebiger Schrittzahl (festgelegt durch ICR1)*/
2
TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS12) | (1<<CS10); // Prescaler 1024 = Enable counter
3
4
ICR1 = 31250;  /* Obergrenze */
5
6
OCR1A = 31250/2; /* Einschaltzeit PD5 50%*/
7
OCR1B = 31250/4; /* Einschaltzeit PD4 25%*/

damit wäre dann alles richtig.

von spess53 (Gast)


Lesenswert?

Hi

>damit wäre dann alles richtig.

Nein.

>TCCR1A |= (1<<WGM11)|(1<<COM1A1)|(1<<COM1B1); /* Modus 14: Fast PWM mit 
>beliebiger Schrittzahl (festgelegt durch ICR1)*/
>TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS12) | (1<<CS10); // Prescaler 1024 = 
>Enable counter

1. Welchen PWM-Mode willst du? Das ist jetzt auf einmal Mode 13->Fast 
pwm

2. Was soll Prescaler 1024? Ich dachte du wolltest eine PWM-Frequenz von 
100kHz?

Lies endlich mal das Datenblatt. Deine Werte für ICR1, OCR1A und OCR1B 
sind gemäß deiner Vorgaben jenseits von gut und böse.

MfG Spess

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.