Hallo Furu,
sorry, wenn es frech rüergekommen ist, aber ich dachte, es ist nicht so viel Arbeit (habe daher ca. 1 oder 2 Minuten geschrieben).
Ich habe mich mit dem Datasheet vorbereitet:
http://www.atmel.com/dyn/resources/prod_documents/doc2545.pdf (Kapitel 15. 8-bit Timer/Counter0 with PWM)
Es geht also um einen ATmega48, 88 oder 168.
Auf Seite 96 des Datenblattes geht es schonmal mit Punkt "15.7.3 Fast PWM mode"
los und auf Seite 97 mit "15.7.4 Phase correct PWM mode" weiter.
Meine Ziele:
Ich möchte meine Lösung in C Programmieren. Die Hardwarelösung ist auch gut für höhere Frequenzen, also nehme ich diese zur Sicherheit. Ich brauche eine Auflösung von 255 (8 Bit).
Meine Vorbereitung/Recherchen:
Ich brauche den 8-Bit Timer TCNT0A . Erreicht das Register TCNT0A den Wert, welcher im Register OCR0A voreingestellt wurde, wird ein Interrupt ausgelöst.
Für Hardware-PWM benötigst du keine Interrupts. Das macht die Hardware komplett
von alleine. Du mußt nur die gewünschte Frequenz und den Modus einstellen. Dann
kannst du durch das Ändern eines Registerwertes dein ausgegebenes PWM-Signal
beeinflussen. Alles sehr einfach.
The counter counts from BOTTOM to TOP then restarts from BOTTOM. TOP is defined as 0xFF when WGM2:0 = 3, and OCR0A when WGM2:0 = 7. In non-inverting Compare Output mode, the Output Compare (OC0x) is cleared on the compare match between TCNT0 and OCR0x, and set at BOTTOM. In inverting Compare Output mode, the output is set on compare match and cleared at BOTTOM.
Der Timer Einstell-Bits:
WGM02=0 WGM01=1 WGM00=1 (Für die 8-Bit Obergrenze Fast PWM Mode)
COM0A1=1 und COM0A0=0 (für den nicht invertierenden PWM-Modus)
in Tabelle 15-8 sind die Bit für die Einstellungen drin. Bei FastPWM bleiben bei dir
Mode 3 oder Mode 7. Du hast Mode 3 eingestellt.
Tabellen 15-3 + 15-6 für COM0xn
COMx1 = 1 , COMx0 = 0
TCCR0A : COM0A1 COM0A0 COM0B1 COM0B0 – – WGM01 WGM00 (Bits7...0)
==> 1 0 1 0 0 0 1 1 =
0xA3h für TCCR0A
note that the Data Direction Register (DDR) bit corresponding to the OC0x pin must be set in order to enable the output driver.
PD6 = OC1A , PD5 = OC1B
DDRD ==> - 1 1 - - - - - ==> also Bits 5+6 für Kanal A und B auf 1
The FOC0A bit is only active when the WGM bits specify a
non-PWM mode. ==> 0
The FOC0B bit is only active when the WGM bits specify a
non-PWM mode. ==> 0
Clock-Source CS02..CS00 => 001 ... 101 möglich
TCCR0B : FOC0A FOC0B – – WGM02 CS02 CS01 CS00 (Bits7...0)
==> 0 0 0 0 1 0 0 1 =
0x09h für TCCR0B
mit CSx = 001 läuft die PWM auf dem vollen Prozessortakt (also am schnellsten)
TCNT0
OCR0A --> generate a waveform output on the OC0A pin ==> Wert für PWM-Kanal A
OCR0B --> generate a waveform output on the OC0B pin ==> Wert für PWM-Kanal B
TIMSK0 : – – – – – OCIE0B OCIE0A TOIE0 (Bits7...0) ==> alles auf 0
TIFR0 : – – – – – OCF0B OCF0A TOV0 (Bits7...0) ==> alles auf 0
Der Befehl in C lautet dann:
TCNT0A = ( 1<<WGM01) |( 1<<WGM00) | (1<<COM0A1);
Jetzt muss ich einen Vorzähler mit einer gewünschten Taktfrequenz bestimmen:
CS12=1 CS11=0 CS10=1 (entspricht dem Verhalten: CK|1024 , wobei ich nicht ganz genau weiß, warum ich das brauche und ob das richtig ist)
Der Befehl in C lautet dann:
TCCR0A = (1<<CS10) | (1<<CS12);
Wie oben schon geschrieben, brauche ich einen Vergleichswert auf OCR0A.
Der Befehl in C lautet dann:
OCR1A = 125;
Schlussendlich will ich das Signal auf dem Port DDRA Ausgeben.
Der Befehl in C lautet dann:
DDRA = 0b00000001; oder
DDRA = 0x01; (Ich will das Signal am Pin 1 ausgeben)
Meine Ausführung:
Code:
void main (void){
[B][COLOR="red"]DDRA = 0x01[/COLOR][/B]; ==>DDRD = 0x40 fuer Kanal A !!
TCNT0A = ( 1<<WGM01) |( 1<<WGM00) | (1<<COM0A1);
TCCR0A = (1<<CS10) | (1<<CS12);
OCR1A = 125;
}
Könnte mir bitte jetzt jemand weiterhelfen? Ich denke nicht, dass es jetzt aufeinmal gehen wird, kann es bis Freitag aber auch nicht einfach so testen.
Ich bin auch dankbar für Tipps, muss ja nicht gleich das fertige Programm sein
Ich hoffe mal das die Ausführungen von mir etwas weiterhelfen. Wobei ich selber noch
nichts mit der Hardware-PWM oder C gemacht habe
Das war jetzt mal etwa ne knappe Stunde Erklärbär. Nix mit 5 Minuten. Weil ich mich erstmal
durch das Datenblatt arbeiten mußte.
EDIT: Gut das Dirk auch schon was geschrieben hat. Ich hoffe mal das ich jetzt alle Fehler bei mir raus habe
Gruß
Dino