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.
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
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.
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
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.
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?
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?
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
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
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.
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
Bzw wenn man die Dauer sieht wären das bei 2Mhz ja 5*10^-7 Sekunden pro Periode.
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
Ok, das macht Sinn aber damit kann man doch nur eine 50% Regelung machen oder seh ich das wieder falsch?
|----| |. | |. |______ 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?
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
|----| | | | |----- 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.
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
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?
WGM13 und 12 befinden sich in TCCR1B. OC1A liegt auf PD5, OC1B auf PD4. (Spess möge entschuldigen, aber es beschleunigt die Sache vielleicht)
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.