Code:
;*******************************************************************************
;* Bestimmung des Prozessortyps für den Assembler und das Programmiergerät *
;*******************************************************************************
LIST p=16F84A
;*******************************************************************************
;* Includedatei für den 16F84A einbinden (vordef. Reg. und Konst.) *
;*******************************************************************************
#include <p16f84A.INC>
; Diese Datei enthält Vordefinitionen für wichtige Register und Konstanten.
; (Z.B. gibt es die Konstante PORTB mit der sich ohne Angabe der
; absoluten Adresse H'0006' der Port B des Prozessors ansprechen lässt)
;*******************************************************************************
;* Konfigurationseinstellungen für IC-Prog vordefinieren *
;*******************************************************************************
__CONFIG _PWRTE_ON & _CP_OFF & _HS_OSC & _WDT_OFF
; Hier werden verschiedene Prozessoreigenschaften festgelegt:
; PWRTE_ON schaltet den Power Up Timer ein, d.h. der Prozessor wartet nach
; dem Einschalten ca. 70ms mit dem Programmstart, um sicher zu sein,
; dass alle angeschlossene Peripherie bereit ist.
; CP_OFF schaltet die Code-Protection des Prozesors aus. Damit ist das im Prozessor
; befindliche Programm jederzeit auslesbar und überschreibbar.
; HS_OSC spezifiziert einen Quarzoszillator (Highspeed) als Zeitbasis für den Prozessor.
; WDT_OFF schaltet den Watchdog-Timer des Prozesors aus.
;*******************************************************************************
;* Register / Variablen festlegen *
;*******************************************************************************
; hier werden Adressen von Registern / Variablen festgelegt. Diese werden beginnend
; mit der Adresse H'20' aufsteigend vergeben.
CBLOCK H'20'
d0
d1
d2
zaehler ;Variable für einen Zähler
temp1 ;Variable für die Temp. des Sensors in Binärer Form
temp2 ;Variable zum Merken ob die Temp POS/NEG ist
DS18S20 ;Variable an die die Commands geschrieben werden
w2
ENDC
;*******************************************************************************
;* Konstanten festlegen *
;*******************************************************************************
; Hier sollten alle im Verlauf des Programms verwendeten Konstanten deklariert werden.
; Die Deklaration sieht z.B. folgendermaßen aus:
;*******************************************************************************
;* Definition von einzelnen Bits in einem Register / in einer Variable *
;*******************************************************************************
; hier kann mit Hilfe der #DEFINE Direktive einzelnen Bits in einem Register ein
; Name zugewiesen werden.
; Eine Definition sieht z.B. folgendermaßen aus:
;
rest EQU 0x18
loops EQU 0x0C
loops2 EQU 0x0D
huns EQU 0x1D
tens EQU 0x1E
ones EQU 0x1F
;*******************************************************************************
;* Name * Port * Bedeutung / Funktion *
;*******************************************************************************
#DEFINE Sensor PORTA,0 ;Anschluss für 1-Wire Sensor
#DEFINE TH PORTA,1 ;Taster für höchste Temperatur -->TH =Temp High
#DEFINE TL PORTA,2 ;Taster für niedrigste Temperatur -->TL =Temp Low
#DEFINE T1 PORTB,7 ;Transistor T1 --> Für Anzeige 1
#DEFINE T2 PORTB,6 ;Transistor T2 --> Für Anzeige 2
#DEFINE T3 PORTB,5 ;Transistor T3 --> Für Anzeige 3
#DEFINE bank1 STATUS, RP0 ;Spezielle Register Bank
;*******************************************************************************
;*******************************************************************************
;* Programmstart *
;*******************************************************************************
ORG H'00' ; Das Programm wird ab Speicherstelle 0 in den Speicher geschrieben
GOTO init ; Springe zur Grundinitialisierung der Ports A und B
;*******************************************************************************
;* Initialisierung *
;*******************************************************************************
init BSF bank1 ; wechsle zu Registerbank 1 (spezielle Register)
MOVLW B'00011111'
MOVWF TRISA ; RA0 .. RA4 Eingänge
MOVLW B'00000000'
MOVWF TRISB ; RB0-RB7 Ausgänge
BCF bank1 ; wechsle zu Registerbank 0 (normaler Speicherbereich)
CLRF PORTA ; Port A löschen
CLRF PORTB ; Port B löschen
; Die Register TRISA und TRISB legen fest, welche Bits in den jeweiligen Ports Ein- bzw.
; Ausgänge sind. Eine '1' an der entsprechenden Stelle setzt das Bit des Ports als Ein-
; gang eine '0' setzt das Bit als Ausgang.
;*******************************************************************************
;* Hauptprogramm *
;*******************************************************************************
main
clrf rest ; rest löschen
CALL UP_read_temp
CALL UP_convert_temp
CALL UP_Send_Temp
GOTO main
;*******************************************************************************
;* Unterprogramme *
;*******************************************************************************
;*****************************Schleifen*****************************************
UP_Wait_1s
;4999993 cycles
movlw 0x2C
movwf d0
movlw 0xE7
movwf d1
movlw 0x0B
movwf d2
UP_Wait_1s_0
decfsz d0, f
goto $+2
decfsz d1, f
goto $+2
decfsz d2, f
goto UP_Wait_1s_0
;3 cycles
goto $+1
nop
;4 cycles (including call)
return
;*******************************************************************************
UP_WAIT_480µs ;
;2393 cycles
movlw 0xDE
movwf d0
movlw 0x02
movwf d1
UP_WAIT_480µs_0
decfsz d0, f
goto $+2
decfsz d1, f
goto UP_WAIT_480µs_0
;3 cycles
goto $+1
nop
;4 cycles (including call)
return
;*******************************************************************************
UP_WAIT_60µs ;
;295 cycles
movlw 0x62
movwf d0
UP_WAIT_60µs_0
decfsz d0, f
goto UP_WAIT_60µs_0
;1 cycle
nop
;4 cycles (including call)
return
;*******************************************************************************
UP_Wait_50µs
;244 cycles
movlw 0x51
movwf d0
UP_Wait_50µs_0
decfsz d0, f
goto UP_Wait_50µs_0
;2 cycles
goto $+1
;4 cycles (including call)
return
;*******************************************************************************
UP_Wait_600µs
;2993 cycles
movlw 0x56
movwf d0
movlw 0x03
movwf d1
UP_Wait_600µs_0
decfsz d0, f
goto $+2
decfsz d1, f
goto UP_Wait_600µs_0
;3 cycles
goto $+1
nop
;4 cycles (including call)
return
;*******************************************************************************
UP_Wait_80µs
;394 cycles
movlw 0x83
movwf d0
UP_Wait_80µs_0
decfsz d0, f
goto UP_Wait_80µs_0
;2 cycles
goto $+1
;4 cycles (including call)
return
;*******************************************************************************
UP_Wait_3µs
;10 cycles
movlw 0x03
movwf d0
UP_Wait_3µs_0
decfsz d0, f
goto UP_Wait_3µs_0
;1 cycle
nop
;4 cycles (including call)
return
;*************************Sensor Unterprogramme*********************************
UP_init_ds18s20;Dient zur Initialisierung des 1-Wire Sensors DS18S20
CALL UP_Ausgang
BCF PORTA, 0
CALL UP_Wait_600µs ;600 µs low -> Reset
BSF PORTA, 0
CALL UP_Eingang
CALL UP_Wait_50µs ;50 us Pause
init_ds18s20_loop
BTFSC PORTA, 0
GOTO init_ds18s20_loop ;Warten bis Presence = Low
Return
;*******************************************************************************
UP_write_ds18S20
CALL UP_Ausgang ;Setze PORTA,0 als Ausgang
MOVLW D'8' ;Lade 8 in die Variable
MOVWF zaehler ;zaehler
write_ds18S20_loop
RRF DS18S20, f ;Nach rechts verschieben
BTFSS STATUS, C ;Prüfe Carrybit auf 1...
GOTO write_zero ;ist es nicht auf 1 dann rufe UP_write_zero auf
CALL UP_write_one ;wenn es auf ist dann Rufe UP_write_one auf
GOTO verkleinere ;
write_zero CALL UP_write_zero ;
verkleinere DECFSZ zaehler, f ;Verkleinere Zähler
GOTO write_ds18S20_loop ;Weitermachen, bis alle 8 Bits gesendet
CALL UP_Eingang ;Setze nun PORTA,0 wieder als Eingang
RETURN
;*******************************************************************************
UP_read_ds18S20
CLRF DS18S20 ;lösche den Inhalt von der Variable
BCF STATUS, C ;setze Carrybit auf 0
MOVLW D'8' ;Lade 8 in die Variable zaehler
MOVWF zaehler
read_ds18S20_loop
CALL UP_Ausgang
BCF PORTA, 0 ;Ziehe ihn nun auf Low
nop
CALL UP_Eingang
BSF PORTA, 0 ;High, wird nicht ausgegeben
CALL UP_Wait_3µs
BSF STATUS, C
BTFSS PORTA,0 ;Prüfe auf 1
BCF STATUS, C ;setze Carrybit auf 0
RRF DS18S20, f ;Nach rechts verschieben ins File Register
CALL UP_Wait_80µs ;80 µs Pause
DECFSZ zaehler, f
GOTO read_ds18S20_loop ;Weitermachen, bis alle 8 Bits empfangen
RETURN
;*******************************************************************************
UP_read_temp;Lese aus dem Sensor die Temperatur aus -->Binär Daten
CALL UP_init_ds18s20 ;DS1820 initialisieren & erkennen
CALL UP_Wait_600µs ;Warte 600µs
MOVLW 0xCC ;ROM-Kommando 0xCC: Skip ROM
MOVWF DS18S20
CALL UP_write_ds18S20
CALL UP_Wait_600µs
MOVLW 0x44 ;Kommando 0x44: Convert Temperature
MOVWF DS18S20
CALL UP_write_ds18S20
CALL UP_Wait_1s
CALL UP_init_ds18s20
CALL UP_Wait_600µs
MOVLW 0xCC ;ROM-Kommando 0xCC: Skip ROM
MOVWF DS18S20
CALL UP_write_ds18S20
MOVLW 0xBE ;Kommando 0xBE: Read Scratchpad
MOVWF DS18S20
CALL UP_write_ds18S20
CALL UP_read_ds18S20 ;Aufruf des Unterprogrammes UP_read_ds18S20
MOVWF DS18S20
MOVF temp1 ;Temperatur LSB
CALL UP_read_ds18S20
MOVWF DS18S20
MOVLW temp2 ;Temperatur MSB
Return
;*******************************************************************************
UP_convert_temp
;This routine will return the number of decimal
;hundreds from an 8-bit binary
;Input: w
;Output: w
;RAM:2
;Cycles: 12-24
GETHNDS movwf temp1
clrf w2
gethnds_loop movlw .100
incf w2,f
subwf temp1,f
btfsc STATUS,C
goto gethnds_loop
decf w2,w
return
;---
;This routine will return the number of decimal
;tens from an 8-bit binary
;Loop based, so it might take some time...
;It needs getones too
GETTENS movwf temp1
clrf w2
gettens_loop movlw .10
incf w2,f
subwf temp1,f
btfsc STATUS,C
goto gettens_loop
decf w2,w
goto GETONES
;---
;This routine will return the number of decimal
;ones from an 8-bit binary
GETONES movwf w2
movlw .10
deltens_loop subwf w2,f
btfsc STATUS,C
goto deltens_loop
addwf w2,w
return
;*******************************************************************************
UP_Send_Temp ;Dient zum Senden der Temperatur
MOVLW temp1
MOVWF PORTB
call UP_Wait_1s
Return
;*******************************************************************************
UP_Eingang ;Unterprogramm das dazu dient einen Ausgang als Eingang zusetzen
BSF STATUS, RP0
BSF TRISA,0
BCF STATUS, RP0
Return
;*******************************************************************************
UP_Ausgang ;Unterprogramm das dazu dient einen Eingang als Ausgang zusetzen
BSF STATUS, RP0
BCF TRISA,0
BCF STATUS, RP0
Return
;*******************************************************************************
UP_write_zero ;Dient zum Schreiben einer log 0.
BCF TRISA,0
CALL UP_WAIT_60µs
BSF TRISA,0
Return
;*******************************************************************************
UP_write_one ;Dient zum Schreiben einer log 1.
BCF TRISA, 0
CALL UP_WAIT_60µs
BSF TRISA,0
CALL UP_WAIT_60µs
Return
;*******************************************************************************
END
Habe ich irgendwas vergessen bzw gebe ich den BCD Code falsch aus?
Lesezeichen