PIC-Lernbeispiel: Schwellwertschalter (Schmitt-Trigger)

mit PIC12F675


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


eine digitaler Ausgang wird in Abhängigkeit von einer analogen Spannung geschaltet
Hier wird der Analog-Digital-Converter (ADC) zur Überwachung einer Spannung verwendet.Überschreitet die Spannung 2V, dann wird ein digitaler Ausgang aktiviert. Unterschreitet die Spannung 1,6V, dann wird der Ausgang abgeschaltet.


Schaltung
Schaltbild Normalerweise würde man das Problem mit einem Schmitt-Trigger lösen, den man aus einem Operationsverstärker und ein paar externen Bauteilen aufbaut. Es geht aber auch mit einem PIC.

Die Schaltung besteht lediglich aus einem PIC12F675. Die analoge Spannung wird an GP0 (AN0, Pin 7) in den PIC gespeist. Der 1k-Widerstand dient nur dem Schutz vor Überspannung (>5V) und Unterspannung (<0V).

Der digitale Ausgang ist Pin GP5 (Pin 2).

Zum Aufbau eignet sich z.B. die 14-Pin/8-Pin-Testplatine mit der Analogplatine als Eingang.



Programmablauf

Spannung messen:


Details

Der ADC wird so eingestellt, dass er sein 10 Bit langes Messergebnis linksbündig in die Ergebnisregister ADRESH&ADRESL schreibt. Die oberen 8 Bit stehen dann in ADRESH. Nur die werte ich aus.
Als Referenzspannung für den ADC verwende ich die 5V Betriebsspannung.
2V Eingangsspannung entsprechen dann einem Messergebnis von 2V/5V*1023 = 409. Wandelt man das in eine Binärzahl, dann erhält man '0110011001'. In ADRESH stehen nur die oberen 8 Bit, das sind dann '01100110', oder als Hexadezimalzahl 0x66.
1,6V Eingangsspannung entsprechen einem Messergebnis von 1,6V/5V*1023 = 327. Wandelt man das in eine Binärzahl, dann erhält man '0101000111'. In ADRESH stehen nur die oberen 8 Bit, das sind dann eigentlich '01010001', aber das bessere Rundungsergebnis ist '01010010' oder als Hexadezimalzahl 0x52.

Steht nach der Spannungsmessung in ADRESH also ein Wert über 0x66, dann liegen >2V am Eingang an, und die LED muss eingeschaltet werden.
Steht nach der Spannungsmessung in ADRESH aber ein Wert unter0x52, dann liegen <1,6V am Eingang an, und die LED muss ausgeschaltet werden.

In jeder Programmschleife lege ich eine Pause von 75 ms ein. Die ist eigentlich unnötig, und soll das Flackern der LED auf maximal 7 Hz begrenzen, wenn der Eingang ein stark verrauschtes Signal bekommt. Man kann diese Warteschleife einfach weglassen, falls man die LED schneller schalten muss.


Programmlisting

        list p=12f675
;***********************************************************************
;*      Pinbelegung
;*      ----------------------------------     
;*      GP:     0 < analog ein
;*              1 -
;*              2 -
;*              3 -
;*              4 -
;*              5 > LED out
;*     
;***********************************************************************
;
;sprut (zero) Bredendiek 12/2010
;http://www.sprut.de
;
; Schwellwertschalter mit Hysteresis
;
; Spannungsmessung mit ADC am Pin  GP0
; Schalttransistor für LED oder LED an GP5
;       LED an  bei >2V         409 = 0x199  -> ADRESH=66
;       LED aus bei <1,6V       327 = 0x147  -> ADRESH=52
;
; Prozessor 12F675
;
; Prozessor-Takt 4 MHz intern
;
;
;***********************************************************************
; Includedatei für den 12F675 einbinden

        #include <P12f675.INC>

        ERRORLEVEL      -302            ;SUPPRESS BANK SELECTION MESSAGES

; Configuration festlegen:
; kein Power on Timer, kein Watchdog, int-Oscillator, kein Brown out
        __CONFIG        _MCLRE_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BODEN_OFF


;***********************************************************************
; Variablen festlegen  20h ... 5Fh

count           equ     0x26    ; universeller zähler
loops           equ     0x27    ; timer für wait
loops2          equ     0x28    ; timer für wait

;16 Bit Rechenregister
f0              equ     0x29    ;
f1              equ     0x2A    ;

Uon1            equ     0x2B    ; Einschaltspannung
Uoff1           equ     0x2C    ; Ausschaltspannung

;***********************************************************************
        org     0x00

        goto    Init

;***********************************************************************
; Initialisierung
;
Init
        ; IO-Pins
        bcf     STATUS, RP0             ; Bank 0
        clrf    GPIO                    ; aus!
        movlw   0x07
        movwf   CMCON                   ; Comparator aus
        bsf     STATUS, RP0             ; Bank 1
        bcf     TRISIO,5                ; GP5 output für Schalttransistor oder LED
        bcf     STATUS, RP0             ; Bank0

        ; internen Taktgenerator kalibrieren
        bsf     STATUS, RP0             ; Bank 1
        call    0x3FF
        movwf   OSCCAL                  ; 4-MHz-Kalibrierung
        bcf     STATUS, RP0             ; Bank 0

        ; Interrupt
        bcf     INTCON, GIE             ; Int deaktiviert


; ADC initialisieren
        ; ADC einschalten
        BSF     ADCON0, ADON    ; ADON=1
        ; ADC-Eingang AN0 auswählen
        BCF     ADCON0, CHS1    ; ADCHS1=0
        BCF     ADCON0, CHS0    ; ADCHS0=0
        ; ADC speed für 1,25 ... 5 MHz einstellen
        BSF     STATUS,RP0      ; Bank1
        clrf    ANSEL
        BSF     ANSEL, ADCS0    ; ADCS0=1 Fosc/8
        ; AN0,1 analog
        BSF     ANSEL, ANS0     ; AN1=analog
        BCF     STATUS,RP0      ; Bank0
        ; Daten linksbündig
        BCF     ADCON0, VCFG    ; RA2=digital
        BCF     ADCON0, ADFM    ; ADFM=1 linksbündig

        ;LED-Schaltspannungen festlegen
        movlw   0x66            ; Uon1   2V
        movwf   Uon1

        movlw   0x52            ; Uoff1  1,6V
        movwf   Uoff1

;***********************************************************************
;Main
Mainloop
        ; Messen
        call    UMessen1        ; AN0 nach f1,f0  (f1 is entscheidend)
        call    LED             ; LED ein-/ausschalten

        call    wait75ms        ; Wartezeit, kann entfallen
        goto    Mainloop

;***********************************************************************
; Spannung wandeln nach f1, f0
UMessen1
        BSF     ADCON0, 1       ; ADC starten
loop
        BTFSC   ADCON0, 1       ; ist der ADC fertig?
        GOTO    loop            ; nein, weiter warten
        movfw   ADRESH          ; obere  8 Bit auslesen
        movwf   f1              ; obere  8-Bit nach f1
        bsf     STATUS,RP0      ; Bank1
        movfw   ADRESL          ; untere 2 Bit auslesen, werden aber  nicht benötigt
        bcf     STATUS,RP0      ; Bank0
        movwf   f0              ; untere 2-Bit nach f0

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

;***********************************************************************
; LED ein/aus-schalten
LED
        ; prüfen ob f1<Uoff
        MOVFW   Uoff1
        subwf   f1, w           ; w:=f1-w
        btfss   STATUS, C
        bcf     GPIO,5          ; LED aus
        ; prüfen ob f1>Uon
        MOVFW   Uon1
        subwf   f1, w           ; w:=f1-w
        btfsc   STATUS, C
        bsf     GPIO,5          ; LED an
        return

;***********************************************************************
; 75 ms warten
wait75ms
        movlw   D'75'           ; 75ms
        movwf   loops  
        goto    WAIT

;***********************************************************************
;Zeitverzögerung um loops * 1 ms
; 4 MHz externer Takt bedeutet 1 MHz interner Takt
; also dauert 1 ms genau 1000 Befehle
; 100 Schleifen a 10 Befehle sind 1000 Befehle = 1 ms
WAIT
top     movlw   .100           ; timing adjustment variable (1ms)
        movwf   loops2
top2    nop                    ; sit and wait
        nop
        nop
        nop
        nop
        nop
        nop
        decfsz  loops2, F      ; inner loops complete?
        goto    top2           ; no, go again
                               ;
        decfsz  loops, F       ; outer loops complete?
        goto    top            ; no, go again
        retlw   0              ; yes, return from subWAIT

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

        end



zurück zu Lernbeispiele , PIC-Prozessoren , Elektronik , Homepage
Autor: sprut
erstellt : 16.12.2010
letzte Änderung: 17.12.2010