Code:
;***************************************
; Syntax zur PIC-Programmierung
List P=16F887
; Einbindung der Includedatei
#include <P16F887.INC>
; Konfigurationseinstellungen
__CONFIG _CONFIG1, _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF & _LVP_OFF & _DEBUG_OFF
__CONFIG _CONFIG2, _BOR21V & _WRT_OFF
;**************************************
;Deklarieren der Variablen
cblock 0x27
loop_A ;Variable für delay
loop_B ;Variable für delay
loop_C ;Variable für delay
Ergebnis ;Ergebnis der AD-Wandlung
old_level ;Merker für Pegel
bin_val ;Hilfsvariable fuer BCD-Converter
dispval ;Variable fuer 7-Segment-Converter
bcd1 ;Einerstellen
bcd10 ;Zehnerstellen
bcd100 ;Hunderterstellen
bcd1000 ;Tausenderstellen
endc
;**************************************
; PROGRAMMSTART
org 0x00 ;Startadresse
goto init ;Springe zu "init"
;********************************************
; Grundinitialisierung
init
;bsf STATUS, RP0 ;Setze Bit RP0
;bsf STATUS, RP1 ;Setze Bit RP1
BANKSEL ANSEL ;Bankauswahl
movlw B'11111111' ;PORTA wird als Analog definiert
movwf ANSEL
BANKSEL ANSELH ;Bankauswahl
clrf ANSELH ;PORTB wird als Digital definiert
BANKSEL TRISA ;Bankauswahl
movlw B'11111111' ;PORTA wird als Eingang definiert
movwf TRISA
clrf TRISB ;PORTB wird als Ausgang definiert
clrf TRISD ;PORTD wird als Ausgang definiert
clrf ADCON1 ;loesche Register ADCON1
BANKSEL ADCON0 ;Bankauswahl
movlw B'01000001' ;Einstellungen für Register ADCON0
movwf ADCON0 ;Einstellungen in Register ADCON0 laden
clrf PORTA ;PORTA loeschen
clrf PORTB ;PORTB loeschen
clrf PORTD ;PORTD loeschen
goto main ;springe zu "main"
;*************************************************************************************
;Hauptprogramm
main
btfss PORTA, 7 ;Abfrage Schalter 1, springe wenn gesetzt
goto Schalter1_nein ;springe zu "Schalter1_nein"
goto Schalter1_ja ;springe zu "Schalter1_ja"
Schalter1_nein
btfss PORTA, 6 ;Abfrage Schalter 2, springe wenn gesetzt
goto Automatik ;springe zu "Automatik"
goto Temperatur ;springe zu "Temperatur"
Schalter1_ja
btfss PORTA, 6 ;Abfrage Schalter 2, springe wenn gesetzt
goto Luftfeuchtigkeit ;springe zu "Luftfeuchtigkeit"
goto Luftdruck ;springe zu "Luftdruck"
Temperatur
BANKSEL ADCON1 ;Bankauswahl
movlw B'00000000' ;Ergebnis = linksbündig
movwf ADCON1
BANKSEL ADCON0 ;Bankauswahl
movlw B'01000001' ;FOSC/8---Kanal 0---AD-Wandlung aktiviert
movwf ADCON0
bsf ADCON0, 1 ;starte AD-Wandlung
btfsc ADCON0, 1 ;fertig?
goto $-1 ;sonst warte
;Speichern
movf ADRESH, w ;kopiere Inhalt aus ADRESH in Arbeitsregister
movwf Ergebnis ;schreibe Inhalt aus Arbeitsregister in "Ergebnis"
goto main ;springe zu "main"
Luftfeuchtigkeit
BANKSEL ADCON1 ;Bankauswahl
movlw B'00000000' ;Ergebnis = linksbündig
movwf ADCON1
BANKSEL ADCON0 ;Bankauswahl
movlw B'01000101' ;FOSC/8---Kanal 1---AD-Wandlung aktiviert
movwf ADCON0
bsf ADCON0, 1 ;starte AD-Wandlung
btfsc ADCON0, 1 ;fertig?
goto $-1 ;sonst warte
;Speichern
movf ADRESH, w ;kopiere Inhalt aus ADRESH in Arbeitsregister
movwf Ergebnis ;schreibe Inhalt aus Arbeitsregister in "Ergebnis"
goto main ;springe zu "main"
Luftdruck
BANKSEL ADCON1 ;Bankauswahl
movlw B'00000000' ;Ergebnis = linksbündig
movwf ADCON1
BANKSEL ADCON0 ;Bankauswahl
movlw B'01001001' ;FOSC/8---Kanal 2---AD-Wandlung aktiviert
movwf ADCON0
bsf ADCON0, 1 ;starte AD-Wandlung
btfsc ADCON0, 1 ;fertig?
goto $-1 ;sonst warte
;Speichern
movf ADRESH, w ;kopiere Inhalt aus ADRESH in Arbeitsregister
movwf Ergebnis ;schreibe Inhalt aus Arbeitsregister in "Ergebnis"
goto main ;springe zu "main"
Automatik
;***Temperatur***
BANKSEL ADCON1 ;Bankauswahl
movlw B'00000000' ;Ergebnis = linksbündig
movwf ADCON1
BANKSEL ADCON0 ;Bankauswahl
movlw B'01000001' ;FOSC/8---Kanal 0---AD-Wandlung aktiviert
movwf ADCON0
bsf ADCON0, 1 ;starte AD-Wandlung
btfsc ADCON0, 1 ;fertig?
goto $-1 ;sonst warte
;Speichern
movf ADRESH, w ;kopiere Inhalt aus ADRESH in Arbeitsregister
movwf Ergebnis ;schreibe Inhalt aus Arbeitsregister in "Ergebnis"
call delay2s
;***Luftfeuchtigkeit***
BANKSEL ADCON1 ;Bankauswahl
movlw B'00000000' ;Ergebnis = linksbündig
movwf ADCON1
BANKSEL ADCON0 ;Bankauswahl
movlw B'01000101' ;FOSC/8---Kanal 1---AD-Wandlung aktiviert
movwf ADCON0
bsf ADCON0, 1 ;starte AD-Wandlung
btfsc ADCON0, 1 ;fertig?
goto $-1 ;sonst warte
;Speichern
movf ADRESH, w ;kopiere Inhalt aus ADRESH in Arbeitsregister
movwf Ergebnis ;schreibe Inhalt aus Arbeitsregister in "Ergebnis"
call delay2s
;***Luftdruck***
BANKSEL ADCON1 ;Bankauswahl
movlw B'00000000' ;Ergebnis = linksbündig
movwf ADCON1
BANKSEL ADCON0 ;Bankauswahl
movlw B'01001001' ;FOSC/8---Kanal 2---AD-Wandlung aktiviert
movwf ADCON0
bsf ADCON0, 1 ;starte AD-Wandlung
btfsc ADCON0, 1 ;fertig?
goto $-1 ;sonst warte
;Speichern
movf ADRESH, w ;kopiere Inhalt aus ADRESH in Arbeitsregister
movwf Ergebnis ;schreibe Inhalt aus Arbeitsregister in "Ergebnis"
call delay2s
goto main
delay500us
movlw D'5' ;schreibe "5" in "loop_A"
movwf loop_A
z6
movlw D'50' ;schreibe "50" in "loop_B"
movwf loop_B
z5
movlw D'50' ;schreibe "50" in "loop_C"
movwf loop_C
z4
decfsz loop_C ;ziehe "1" von "loop_C" ab
goto z4
decfsz loop_B ;ziehe "1" von "loop_B" ab
goto z5
decfsz loop_A ;ziehe "1" von "loop_A" ab
goto z6
return
;Unterprogramm Displayausgabe mit BCD dreistellig (sr_display, sr_conv7seg)
; ------------------------------------------------------------------------
; Display Ausgabe auf 7-Segmentdisplay mit BCD dreistellig
; ------------------------------------------------------------------------
sr_display
clrf bcd1000 ; bcd10000 loeschen
clrf bcd100 ; bcd100 loeschen
clrf bcd10 ; bcd10 loeschen
clrf bcd1 ; bcd1 loeschen
movf Ergebnis,w ; Ergebnis in w laden
movwf bin_val ; w nach bin_val
; Division durch 1000
movlw d'1000' ; lade w mit 1000
loop1000
subwf bin_val,1 ; subtrahiere 1000 von bin_val, Resultat nach bin_val
btfss STATUS,C ; Resultat < 1000 ?
goto end1000 ; ja -> dann 100er Stelle
incf bcd1000 ; bcd1000 + 1
goto loop1000 ; naechster Durchgang
end1000
addwf bin_val,1 ; addiere 1000 zu bin_val, Korrektur der letzten Pruefung
; Division durch 100
movlw d'100' ; lade w mit 100
loop100
subwf bin_val,1 ; subtrahiere 100 von bin_val, Resultat nach bin_val
btfss STATUS,C ; Resultat < 100 ?
goto end100 ; ja -> dann 10er Stelle
incf bcd100 ; bcd100 + 1
goto loop100 ; naechster Durchgang
end100
addwf bin_val,1 ; addiere 100 zu bin_val, Korrektur der letzten Pruefung
; Division durch 10
movlw d'10' ; lade w mit 10
loop10
subwf bin_val,1 ; subtrahiere 10 von bin_val, Resultat nach bin_val
btfss STATUS,C ; Resultat < 10 ?
goto end10 ; ja -> dann 1er Stelle
incf bcd10 ; war groesser oder gleich 10, dann bcd10 + 1
goto loop10 ; naechster Durchgang
end10
addwf bin_val,0 ; addiere 10 zu bin_val, Korrektur der letzten Pruefung
movwf bcd1 ; Rest ist gleich Einerstelle
movf bcd1,0 ; Uebergebe Einerstelle an Converter
movwf dispval
call sr_conv7seg ; Convertiere nach 7-Segment
bsf PORTB,0 ; Schreibe nach Einerstelle
call delay500us
bcf PORTB,0
call delay500us
movf bcd10,w ; Uebergebe Zehnerstelle an Converter
movwf dispval
call sr_conv7seg ; Convertiere nach 7-Segment
bsf PORTB,1 ; Schreibe nach Zehnerstelle
call delay500us
bcf PORTB,1
call delay500us
movf bcd100,w ; Uebergebe Hunderterstelle an Converter
movwf dispval
call sr_conv7seg ; Convertiere nach 7-Segment
bsf PORTB,2 ; Schreibe nach Hunderterstelle
call delay500us
bcf PORTB,2
call delay500us
movf bcd1000,w ; Uebergebe Tausenderterstelle an Converter
movwf dispval
call sr_conv7seg ; Convertiere nach 7-Segment
bsf PORTB,3 ; Schreibe nach Tausenderterstelle
call delay500us
bcf PORTB,3
return
; ------------------------------------------------------------------------
; 7-Segment Display Converter
; ------------------------------------------------------------------------
sr_conv7seg
movlw b'00111111' ; Displaycode für 0
movwf PORTD ; nach PORTD
movf dispval,0
sublw D'0' ; subtrahiere den Pruefwert = 0
btfsc STATUS,Z ; wenn dispval = 0, dann Z=1?
goto write_sign ; ja, dann springe zur Ausgabe
; nein, dann pruefe nächsten Wert
movlw b'00000110' ; Displaycode für 1
movwf PORTD ; nach PORTD
movf dispval,0
sublw D'1' ; subtrahiere den Pruefwert = 1 ;
btfsc STATUS,Z ; wenn dispval = 1, dann Z=1?
goto write_sign ; ja, dann springe zur Ausgabe
; nein, pruefe nächsten Wert
movlw b'01011011' ; Displaycode für 2
movwf PORTD
movf dispval,0
sublw D'2' ;
btfsc STATUS,Z
goto write_sign
movlw b'01001111' ; Displaycode für 3
movwf PORTD
movf dispval,0
sublw D'3' ;
btfsc STATUS,Z
goto write_sign
movlw b'01100110' ; Displaycode für 4
movwf PORTD
movf dispval,0
sublw D'4' ;
btfsc STATUS,Z
goto write_sign
movlw b'01101101' ; Displaycode für 5
movwf PORTD
movf dispval,0
sublw D'5' ;
btfsc STATUS,Z
goto write_sign
movlw b'01111101' ; Displaycode für 6
movwf PORTD
movf dispval,0
sublw D'6' ;
btfsc STATUS,Z
goto write_sign
movlw b'00000111' ; Displaycode für 7
movwf PORTD
movf dispval,0
sublw D'7' ;
btfsc STATUS,Z
goto write_sign
movlw b'01111111' ; Displaycode für 8
movwf PORTD
movf dispval,0
sublw D'8' ;
btfsc STATUS,Z
goto write_sign
movlw b'01101111' ; Displaycode für 9
movwf PORTD
movf dispval,0
sublw D'9' ;
btfsc STATUS,Z
goto write_sign
write_sign
return
Lesezeichen