Code:
;==========================================================================
;
; Configuration
;
;==========================================================================
__CONFIG _CP_OFF & _DEBUG_OFF & _LVP_OFF & _WRT_OFF & _PWRTE_ON & _WDT_OFF & _BODEN_OFF & _HS_OSC
;==========================================================================
;
; Variable Definition
;
;==========================================================================
wait EQU 0x20
loops2 EQU 0x22
summe EQU 0x21
; Anfangsinitialisierung
init
; PWM vorbereiten
; Vorteiler 16:1 und Timer2 einschalten
BSF T2CON,T2CKPS1 ; Vorteiler 16:1
BSF T2CON,TMR2ON ; Timer2 ein
; Frequenz auf ca 700Hz einstellen
BSF STATUS,RP0 ; Bank1
MOVLW D'255' ;
MOVWF PR2 ; ca 700 Hz
BCF STATUS,RP0 ; Bank1
; Tastverhältnis auf 0% einstellen
MOVLW D'0'
MOVWF CCPR1L ; 0%
MOVLW D'0'
MOVWF CCPR2L ; 0%
; RC2/CCP1 und RC1/CCP2 auf Ausgang stellen
BSF STATUS,RP0 ; Bank1
BCF TRISC, 2 ; RC2: output=0
BCF TRISC, 1 ; RC1: 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 ;
; PWM MODE mit CCP2 initialisieren
CLRF CCP2CON ; CCP2-Modus aus
BSF CCP2CON,CCP2M3 ; CCP2-Modus PWM-Mode
BSF CCP2CON,CCP2M2 ;
; 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 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
; Ablauf für 1.PWM ausgang
; ADC-Eingang AN0 auswählen
BCF ADCON0, 5 ; ADCHS2=0
BCF ADCON0, 4 ; ADCHS1=0
BCF ADCON0, 3 ; ADCHS0=0
;Pause zum ADC aufladen?
;**********************************************************
; Warteschleife 1 ms für einen 10MHz-PIC-Takt
Wai
movlw .249 ; Zeitkonstante für 1ms
movwf loops2
Wai2 nop
nop
nop
nop
nop
nop
nop
decfsz loops2, F ; 1 ms vorbei?
goto Wai2 ; nein, noch nicht
;Eingangsspannung wandeln
BSF ADCON0, 2 ; ADC starten
loop
BTFSC ADCON0, 2 ; ist der ADC fertig?
GOTO loop ; nein, weiter warten
; Wert auslesen und schreiben
; #### Nebenrechung
;Der Wert von ADRESH wird ausgelesen, wenn er kleiner 15 ist, soll der Ausgang ausgeschaltet bleiben
;dazu wird das carryflag abgefragt: wenn der messwert +240 das flag setzt,bedeutet das, er ist größer/gleich 15,
;also wird normal weitergemacht, wenn die flag nicht gesetzt wird, ist der wert kleiner 15, und der pwm ausgang soll "aus" bleiben
;dafür wird dann adresh 0 gesetzt,somit wird im folgenden code 0 + 0 + 0 = 0 und der port auf 0 gesetzt.
BCF STATUS,C ; Carry Flag auf 0
movfw ADRESH ; wert auslesen, in work setzen
addlw D'240' ; 240 mit work addieren,
btfss STATUS,C ; carryflag gesetzt durch addition?
clrf ADRESH ; dann wird der befehl übergangen, da wert größer 15 (sonst adresh=0 => PWM=ausschalten da wert zu klein)
; sonst normal weiter
; #### Nebenrechnung Ende
BCF STATUS,C ; Carry Flag auf 0
movfw ADRESH ; wert auslesen (0 oder messwert), in work setzen
addwf ADRESH,0 ; wert verdoppelt
addwf ADRESH,0 ; wert verdreifacht
btfsc STATUS,C ; wenn carry flag gesetzt,
movlw D'255' ; dann: wert auf maximum setzen=255=5V
movwf PORTB ; sonst: normal weiter, obere 8 Bit nach PortB schreiben
; Wert an PWM1 übergeben
MOVWF CCPR1L ; obere 8 Bit sind PWM
; Warten, damit der ADC sich erholen kann
clrf wait
warten
DECFSZ wait, f
goto warten
; Ablauf für 2.PWM ausgang
; ADC-Eingang AN1 auswählen
BCF ADCON0, 5 ; ADCHS2=0
BCF ADCON0, 4 ; ADCHS1=0
BSF ADCON0, 3 ; ADCHS0=1
;Pause zum ADC aufladen?
;**********************************************************
; Warteschleife 1 ms für einen 10MHz-PIC-Takt
Waii
movlw .249 ; Zeitkonstante für 1ms
movwf loops2
Wai3 nop
nop
nop
nop
nop
nop
nop
decfsz loops2, F ; 1 ms vorbei?
goto Wai3 ; nein, noch nicht
;Eingangsspannung wandeln
BSF ADCON0, 2 ; ADC starten
loop2
BTFSC ADCON0, 2 ; ist der ADC fertig?
GOTO loop2 ; nein, weiter warten
; Wert auslesen und schreiben
; #### Nebenrechung
;Der Wert von ADRESH wird ausgelesen, wenn er kleiner 15 ist, soll der Ausgang ausgeschaltet bleiben
;dazu wird das carryflag abgefragt: wenn der messwert +240 das flag setzt,bedeutet das, er ist größer/gleich 15,
;also wird normal weitergemacht, wenn die flag nicht gesetzt wird, ist der wert kleiner 15, und der pwm ausgang soll "aus" bleiben
;dafür wird dann adresh 0 gesetzt,somit wird im folgenden code 0 + 0 + 0 = 0 und der port auf 0 gesetzt.
BCF STATUS,C ; Carry Flag auf 0
movfw ADRESH ; wert auslesen, in work setzen
addlw D'240' ; 240 mit work addieren,
btfss STATUS,C ; carryflag gesetzt durch addition?
clrf ADRESH ; dann wird der befehl übergangen, da wert größer 15 (sonst adresh=0 => PWM=ausschalten da wert zu klein)
; sonst normal weiter
; #### Nebenrechnung Ende
BCF STATUS,C ; Carry Flag auf 0
movfw ADRESH ; wert auslesen (0 oder messwert), in work setzen
addwf ADRESH,0 ; wert verdoppelt
addwf ADRESH,0 ; wert verdreifacht
btfsc STATUS,C ; wenn carry flag gesetzt,
movlw D'255' ; dann: wert auf maximum setzen=255=5V
; sonst normal weiter
; Wert an PWM2 übergeben
MOVWF CCPR2L ; obere 8 Bit sind PWM
; Warten, damit der ADC sich erholen kann
clrf wait
warten2
DECFSZ wait, f
goto warten2
goto Main
end
Alles angelehnt an spruts PWM Beispiel..inzwischen etwas erweitert..
Lesezeichen