PIC-Lernbeispiel: Spannung steuert PWM

nur für PIC16F87x

zurück , Lernbeispiele , PIC-Prozessoren , Elektronik , Homepage

mit einer analogen Eingangsspannung von 0V ... 5V wird das Tastverhältnis einer Rechteckschwingung (0% ... 100%) gesteuert.
Die größeren PICs (PIC16F87x) besitzen einen Analog-DigitalConverter (ADC) zur Messung von Spannungnen im bereich von ca. 0V bis 5V.

Ebendso verfügen sie über zwei CCP-Module (Capture/Compare/PWM) von denen jeweils eines zur Erzeugung einer Rechteckschwingung mit einem bestimmten Pulsverhältnis eingesetzt werden kann.

Unter Nutzung des ADC und des CCP-Moduls lässt sich auf einfache Art ein Rechteckgenerator mit spannungsgesteuertem Tastverhältnis aufbauen.


Schaltung
Die Schaltung besteht lediglich aus einem PIC16F876 (oder anderer 16F87x) und einer 20-MHz Taktquelle für den PIC (z.B. Quarzgenerator). Die analoge Spannung wird an RA0 ind den PIC gespeist. Den Rechteck erzeugt der PIC an RC2.

Zur Kontrolle wird der gemessene ADC-Wert 8-bittig an PortB ausgegeben (kann mit LEDs binär angezeigt werden).

++ACHTUNG++
um den PIC nicht zu beschädigen, darf die Eingangsspannung am Pin RA0 nicht kleiner als Vss-0,3V und nicht größer als Vdd+0,3V sein!! Wer das nicht garantieren kann, sollte den Eingang mit einem Vorwiderstand und zwei Shottky-Schutzdioden (nach Vss und Vdd) schützen.


Programmablauf

Spannung messen:


PWM erzeugen:


Programmlisting

Das Programm erzeugt eine Ausgangsrechteckschwingung von 1,22 kHz.
Das Testprogramm misst in einer Endlosschleife die Eingangsspannung am Pin RA0, und stellt am Pin RC2 das Tastverhältnis der Rechteckschwingung proportional der Eingangsspannung ein.
Eine Eingangsspannung von Vss (0V) ergibt ein Tastverhältnis von 0% (Dauer-Low) eine Spannung von Vdd (+5V) dagegen 100% (Dauer-High). Alle Spannungen dazwischen ergeben eine entsprechendes Tastverhältnis.

Obwohl eine Auflösung von 10 Bit prinzipiell möglich wäre, verwende ich der Einfachheit halber nur die oberen 8 Bit des ADC-Ergebnisses.

;**************************************************************
;*
;* Pinbelegung
;* ---------------------------------- 
;* PORTA: 0 analoger Eingang
;*        1 
;*        2 
;*        3 
;*        4 
;* PORTB: 0 LED 
;*        1 LED 
;*        2 LED 
;*        3 LED 
;*        4 LED 
;*        5 LED 
;*        6 LED 
;*        7 LED 
;* PORTC: 0 
;*        1 
;*        2 PWM-Ausgang 
;*        3 
;*        4 
;*        5 
;*        6 
;*        7 
;*
;**************************************************************
;
; sprut (zero) Bredendiek 04/2002
;
; ADC-Lernbeispiel:
;
; 16F876 wandelt die an RA0 anliegende Spannung in einen
; 10-Bit-Wert um
; die oberen 8 Bit des Wertes werden an PortB angezeigt
;
; 16F876 erzeugt an RC2 ein 2,5 kHz-Signal mit Tastverhältnis
; entsprechend der gemessenen Spannung (8-Bit Auflösung)
;
; Prozessortakt:  20 MHz
; Eingangsspannung: 0V ... 5V (Vss ... Vdd)
;
;**************************************************************
; Includedatei für den 16F876 einbinden

        list p=16f876
        #include <P16f876.INC>

    ERRORLEVEL      -302        ;SUPPRESS BANK SELECTION MESSAGES

;**************************************************************
; Configuration festlegen:
; Power on Timer, kein Watchdog, HS-Oscillator, kein Brown out, kein LV-programming
    __CONFIG    _PWRTE_ON & _WDT_OFF & _HS_OSC & _BODEN_OFF & _LVP_OFF

;**********************************************************

; Variablen

wait    EQU     0x20

; Anfangsinitialisierung

init
; PWM vorbereiten
; Vorteiler 16:1 und Timer2 einschalten
        BSF     T2CON,T2CKPS1  ; Vorteiler 16:1
        BSF     T2CON,TMR2ON   ; Timer2 ein

; Frequenz auf 1,22 kHz einstellen
        BSF     STATUS,RP0     ; Bank1
        MOVLW   D'255'
        MOVWF   PR2            ; 1.22 kHz
        BCF     STATUS,RP0     ; Bank1

; Tastverhältnis auf 50% einstellen
        MOVLW   D'127' 
        MOVWF   CCPR1L         ; 50% 

; RC2/CCP1 auf Ausgang stellen
        BSF     STATUS,RP0     ; Bank1
        BCF     TRISC, 2       ; RC2: output=0
        BCF     STATUS,RP0     ; Bank 0

; PWM MODE mit CCP1 initialisieren
        CLRF    CCP1CON        ; CCP1-Modus aus
        BSF     CCP1CON,CCP1M3 ; CCP1-Modus PWM-Mode
        BSF     CCP1CON,CCP1M2

; ADC vorbereiten
; PortB vorbereiten
        bsf     STATUS, RP0    ; auf Bank 1 umschalten
        movlw   B'00000000'    ; PortB alle output
        movwf   TRISB
        bcf     STATUS, RP0    ; auf Bank 0 zurückschalten
        clrf    PORTB          ; alle LEDs ausschalten

; ADC einschalten
        BSF     ADCON0, 0      ; ADON=1

; ADC-Eingang AN0 auswählen
        BCF     ADCON0, 5      ; ADCHS2=0
        BCF     ADCON0, 4      ; ADCHS1=0
        BCF     ADCON0, 3      ; ADCHS0=0

; ADC speed für 20 MHz einstellen
        BSF     ADCON0, 7      ; ADCS1=1
        BCF     ADCON0, 6      ; ADCS0=0

; Daten linksbündig
        BSF     STATUS,RP0     ; Bank1
        BCF     ADCON1, 7      ; ADFM=0
        BCF     STATUS,RP0     ; Bank0
 

;**********************************************************
; Hauptprogrammschleife

Main
;Eingangsspannung wandeln
        BSF     ADCON0, 2      ; ADC starten
loop
        BTFSC   ADCON0, 2      ; ist der ADC fertig?
        GOTO    loop           ; nein, weiter warten

; Wert nach PortB schreiben
        movfw   ADRESH         ; obere 8 Bit auslesen
        movwf   PORTB          ; obere 8 Bit nach PortB

; Wert an PWM übergeben
        MOVWF   CCPR1L         ; obere 8 Bit sind PWM

; Warten, damit der ADC sich erholen kann
        clrf    wait
warten
        DECFSZ  wait, f
        goto    warten

        goto    Main

        end

;**********************************************************


mögliche Änderungen

PWM
Wird eine andere Rechteckfrequenz benötigt, so kann man z.B. die PIC-Frequenz verringern. Dass dabei der ADC langsamer wird stört nicht, da mehr als eine ADC-Wandlung pro Rechteckschwingung sowieso nicht genutzt werden kann.
Durch Änderung des Timer2-Vorteilers lassen sich auch 4-fache und 16-fache dieser  Frequenz erzeugen.
 
PIC-Takt
Vorteiler 16:1
Vorteiler 4:1
Vorteiler 1:1
20 MHz
1,22 kHz
4,88 kHz
19,53 kHz
10 MHz
610 Hz
2,44 kHz
9,77 kHz
4 MHz
244 Hz
977 Hz
3,9  kHz
1 MHz
61 Hz
244 Hz
977 Hz
400 kHz
24,4 Hz
98 Hz
390 Hz
100 kHz
6,1 Hz
24,4 Hz
97,7 Hz

Wird der Wert für PR2 etwas verringert, dann erhöht sich die Frequenz etwas. Allerdings wird dadurch die Auflösung der PWM verringert. Das lässt sich kompensieren, wenn man die eigentlich 10-Bit breite Auflösung der PWM wirklich nützt.

Falls die erreichbaren 19,53 kHz nicht ausreichen, lässt sich die Frequenz noch einmal vervierfachen (bei 8-Bit Auflösung), wenn man PR2 auf 63 verringert,  nur die oberen 6 Bit des ADC-Ergebnisses in CCP1L einschreibt (rechtsbündig) und die nächsten 2 Bit in die Bits 5&4 des CCP1CON einträgt.

ADC
In geringem Maße lässt sich der Spannungsbereich des ADC durch die Wahl externer Referenzspannungen ändern. Für größere Änderungen muss man auf  vorgeschaltete Operationsverstärker zurückgreifen.

Auflösung
Sowohl ADC  wie auch PWM erlauben eine 10-bittige Auflösung. Bei Bedarf können die zusätzlichen LSB aus ADRESL (Bit 7&6) ausgelesen und in CCP1CON (Bit 5&4) eingeschrieben werden. Dann wird das Taktverhältnis mit 10-bittiger Genauigkeit von der analogen Eingangsspannung gesteuert. Das macht aber nur Sinn, wenn die Betriebspannung (bzw. die Referenzsspannungen) mit einer Genauigkeit von 0,1% stabilisiert wird.


zurück , Lernbeispiele, PIC-Prozessoren , Elektronik , Homepage
Autor: sprut
erstellt: 15.04.2002
letzte Änderung: 14.04.2010