Ok, Prinzipell läufts immer gleich ab:
Erst initialisieren, dann nutzen.
Das PWM-Modul hat einige SpecialFunctionRegisters, mit denen es benutzt wird. Ich zeig das mal am PIC16F876a.
Da wäre einmal der Timer2, er stellt den Takt für die PWM-Erzeugung bereit.
CCP1CON ist das Controll Register. Es besteht aus den Wahlschaltern für die Modulfunktion (kann ja auch zb Pulse vermessen), und den zwei kleinsten Bit, da wir hier ein 10Bit PWM haben.
Am besten schreibst du für PWM 0x0F in CCP1CON, also die untersten 4 Bit =1. Du müsstest nur Bit 2 und 3 auf 1 setzen, da Bit 0 und 1 ja X, also unwichtig sind, um PWM zu erreichen.
Ausserdem schreibst du in das PR2 Register. Hier wird die Periodendauer des Signals angegeben, dh, wieviel Zeit vergeht, bis das PWM-Signal wieder von neuem beginnt. Im Datenblatt steht dazu eine Formel.
Die Periodendauer hängt ab von: Dem Wert in PR2, dem Prescaler (Vorteiler) von Timer2 und dem Oszillatortakt an Timer2, meist die Frequenz des externen Quarz.
Ich benutze immer eine kleine Excel Datei um alle Werte einzutragen. Dann kann man solange probieren, bis man genau hat, was man will. Natürlich kannst du auch zu Fuß rechnen.
Danach kommt das Einschaltverhältnis, oder Duty-Cycle dran. Im Register CCPR1L kannst du einen Wert von 0-255 reinschreiben. Damit hast du 256 Stufen, du kannst noch die Bits 4 und 5 von CPP1CON nutzen, um auf 1024 Stufen Auflösung zu kommen. Meist habe ich es nicht gebraucht.
Noch was zur Auflösung: Die ändert sich mit dem Prescaler von Timer2, du kannst also nicht unbedingt alle 10bit nutzen. Ich verweise nur auf die Formel im Datenblatt.
Wichtig: Der CCP1 oder CCP2 Pin, ist nur mit dem Modul verbunden, wenn er über das TRIS Register auf Ausgang geschaltet ist, sonst bekommst du kein PWM Signal, sondern nur High oder Low Pegel, je nach Beschaltung.
Ok, der Ablauf ist folgendermaßen:
Zuerst PR2 wie gewollt einstellen,
Dann das Einschaltverhältnis in CCPR1L schreiben,
Den CCP Pin mit TRIS auf Ausgang stellen,
Den Timer2 Vorteiler einstellen und Timer2 anschalten,
Zum Schluss den 0x0F in das CCP1CON Register schreiben.
Hier ein Beispielcode von mir, er soll ein Signal mit 38kHz liefern, das ungefähr 25% Einschaltdauer hat und am Pin wahlweise ausgegeben wird.
Code:
;PWM INIT
BANKSEL PR2 ;PWM auf 38kHz, DutyCycle 0,25
MOVLW D'78'
MOVWF PR2
BANKSEL CCPR1L
MOVLW D'20'
MOVWF CCPR1L
BANKSEL T2CON
MOVLW D'4'
MOVWF T2CON
BANKSEL TMR2
CLRF TMR2
BANKSEL CCP1CON
MOVLW 0x0F
MOVWF CCP1CON
;In der Anwendung Signal einschalten:
BANKSEL TRISC
BCF TRISC,2
;Ausschalten
BANKSEL TRISC
BSF TRISC,2
Lesezeichen