📄 toutestfini.asm
字号:
; Projet electronique court ;
; Th閞mom鑤re num閞ique ;
;capteur : DS1820 ;
;PIC :Pic16f84a ;
;LCD :DEM 16101 SYH ;
; R閍lis?par : ;
; ;
#include <p16f84a.inc>
; DEFINITION PORTA (A0-A4)
#define IN_OUT_PORTA
#define DATA_DS1820 PORTA,4;patte3 fil de donn閑s avec capteur
#define VDD_LCD PORTA,0 ;pin 17
#DEFINE RS_LCD PORTA,2
#DEFINE E_LCD PORTA,3
; BASIC PARAMETERS
org H'00' ;adresse de debut
goto MAIN_PROGRAM ;main
RAM equ H'0C' ;debut de la RAM
cblock RAM
count
COUNTER_1
COUNTER_2
count_erreur
BIT
BITS
BYTE
MEM_1
DS1820_SIGN
DS1820_TEMP
DS1820_ERROR
REG_1 ; signe
REG_2 ; premier chiffre
REG_3 ; deuxi鑝e chiffre
REG_4 ; virgule "."
REG_5 ; "5" et demi
endc
; BITS
#define DS1820_INPUT_BIT BITS,0
#define DS1820_VIRGULE BITS,1
; DS1820_ERROR
#define DS1820_SHORTED DS1820_ERROR,0 ;shorted to ground
#define DS1820_NO_DEVICE DS1820_ERROR,1 ;no device or shorted to +5V
;=================================================================================
;=======================================================
;Debut programme principale
MAIN_PROGRAM
movlw b'00010100'
movwf count
movlw b'00000100'
movwf count_erreur
call INIT
main_0
call READ_DS1820
movf DS1820_ERROR,1
btfss STATUS,Z
goto main_1
call AFFICHE_TEMP
movlw D'250'
call WAIT_1ms
decfsz count,1
goto main_0
call go_sleep
main_1
call AFFICHE_ERROR
movlw D'250'
call WAIT_1ms
decfsz count_erreur,1
goto main_0
call go_sleep
;=========================================================
INIT
bsf STATUS,RP0
movlw B'00000000' ;
movwf TRISA
movlw B'00000000' ;
movwf TRISB
bcf STATUS,RP0
clrf PORTA ;
clrf PORTB ;
bsf DATA_DS1820 ;
CALL LCD_INIT
return
;==========================================================
LCD_INIT
bsf VDD_LCD
MOVLW D'30'
CALL WAIT_1ms
BCF RS_LCD
BSF E_LCD
MOVLW B'00110100' ;fuction set
MOVWF PORTB
MOVLW D'3'
CALL WAIT_5us
bcf E_LCD
MOVLW D'8' ;wait 40us
CALL WAIT_5us
bsf E_LCD
MOVLW B'00001100' ;DISPLAY CONTROL
MOVWF PORTB
MOVLW D'3'
CALL WAIT_5us
bcf E_LCD
MOVLW D'8' ;wait 40us
CALL WAIT_5us
bsf E_LCD
MOVLW B'00000001' ;DISPLAY clear
MOVWF PORTB
MOVLW D'3'
CALL WAIT_5us
bcf E_LCD
MOVLW D'2'
CALL WAIT_1ms
bsf E_LCD
MOVLW B'00000110' ;entry mode set (pas claire)
MOVWF PORTB
MOVLW D'3'
CALL WAIT_5us
BCF E_LCD
MOVLW D'8' ;wait 40us
CALL WAIT_5us
bsf E_LCD
MOVLW B'00000010' ;return home
MOVWF PORTB
MOVLW D'3'
CALL WAIT_5us
bcf E_LCD
MOVLW D'2'
CALL WAIT_1ms
bsf E_LCD
MOVLW 0x1C ;cursor
MOVWF PORTB
MOVLW D'3'
CALL WAIT_5us
bcf E_LCD
MOVLW D'8' ;wait 40us
CALL WAIT_5us
call bonjour
movlw D'250'
call WAIT_1ms
movlw D'250'
call WAIT_1ms
movlw D'250'
call WAIT_1ms
movlw D'250'
call WAIT_1ms
movlw D'250'
call WAIT_1ms
movlw D'250'
call WAIT_1ms
return
;=================================================================================
READ_DS1820
clrf DS1820_ERROR ;clear ERROR-code
call ONE_WIRE_RESET_AND_PRESENCE
movlw H'CC' ;SKIP ROM
call ONE_WIRE_WRITE_BYTE
movlw H'44' ;CONVERT T
call ONE_WIRE_WRITE_BYTE
read_DS1820_1
movf DS1820_ERROR,1 ;check DS1820_ERROR and ...
btfss STATUS,Z ;... if DS1820_ERROR is not 0 ...
goto read_DS1820_2 ;... then stop reading here
call ONE_WIRE_READ_BIT ;check dataline to find out when ...
btfss DS1820_INPUT_BIT ;... conversion is ready
goto read_DS1820_1
call ONE_WIRE_RESET_AND_PRESENCE
movf DS1820_ERROR,1 ;check DS1820_ERROR and ...
btfss STATUS,Z ;... if DS1820_ERROR is not 0 ...
goto read_DS1820_2 ;... then stop reading here
movlw H'CC' ;SKIP ROM
call ONE_WIRE_WRITE_BYTE
movlw H'BE' ;READ DATA
call ONE_WIRE_WRITE_BYTE
call ONE_WIRE_READ_BYTE ;read TEMP
movwf DS1820_TEMP
call ONE_WIRE_READ_BYTE ;read SIGN
movwf DS1820_SIGN
call ONE_WIRE_READ_BYTE ;TH
call ONE_WIRE_READ_BYTE ;TL
call ONE_WIRE_READ_BYTE ;FFh
call ONE_WIRE_READ_BYTE ;FFh
call ONE_WIRE_READ_BYTE ;REMAIN
call ONE_WIRE_READ_BYTE ;10h
call ONE_WIRE_READ_BYTE ;CRC
read_DS1820_2
return
;========================================
ONE_WIRE_RESET_AND_PRESENCE
; premiere partie: dataline low pour 480 us (RESET)
bcf DATA_DS1820 ;dataline low
movlw D'96' ;wait for 96 x 5 us = 480 us
call WAIT_5us
; part two: release dataline for 70 us and read dataline (PRESENCE)
bsf DATA_DS1820 ;release dataline
bsf STATUS,RP0 ;select BANK 1
bsf TRISA,4 ;define DATA_DS1820 for input ('1')
bcf STATUS,RP0 ;go back to BANK 0
movlw D'13' ;wait for 13 x 5 us = 65 us
call WAIT_5us
btfsc DATA_DS1820 ;if dataline is low ...
bsf DS1820_NO_DEVICE ;... then no device found
; part three: releae dataline for 400 us more
movlw D'80' ;wait for 80 x 5 us = 400 us
call WAIT_5us
btfss DATA_DS1820 ;if dataline is low ...
bsf DS1820_SHORTED ;... then it is shorted to ground
bsf STATUS,RP0 ;select BANK 1
bcf TRISA,4 ;redefine DATA_DS1820 for output ('0')
bcf STATUS,RP0 ;go back to BANK 0
return
;================================================================
wait_1s
movlw D'250'
call WAIT_1ms
movlw D'250'
call WAIT_1ms
movlw D'250'
call WAIT_1ms
movlw D'250'
call WAIT_1ms
movlw D'250'
call WAIT_1ms
movlw D'250'
call WAIT_1ms
return
;=================================================================
WAIT_1ms
; Wait as many times 1ms as the number in the workspace presents
movwf COUNTER_2
wait_1ms_1
movlw D'200'
call WAIT_5us
decfsz COUNTER_2,1
goto wait_1ms_1
return
;================================================================
WAIT_5us
;cette fonction va attendre 5us fois le nombre qui se trouve dans
; W,
addlw D'255'
movwf COUNTER_1
wait_5us_1
nop
nop
decfsz COUNTER_1,1
goto wait_5us_1
return
;==================
ONE_WIRE_READ_BYTE
movwf BYTE ;store workspace in BYTE
movlw D'8' ;read D0-D7 ...
movwf BIT ;... and follow bit-counter in BIT
one_wire_read_byte_1
call ONE_WIRE_READ_BIT ;read next bit in workspace
rrf BYTE,1 ;move bits in BYTE 1 position to the right
bcf BYTE,7 ;clear leftmost bit in BYTE ...
btfsc DS1820_INPUT_BIT ;... if INPUT_BIT = '1' ...
bsf BYTE,7 ;... then set leftmost bit in BYTE
; repeat for next bit
decfsz BIT,1 ;countdown until BIT=0
goto one_wire_read_byte_1
movf BYTE,0 ;put BYTE in workspace
return
;=================================================================================
ONE_WIRE_WRITE_BYTE
movwf BYTE
movlw D'8' ;write D7-D0 ...
movwf BIT ;... en follow bit-counter in BIT
one_wire_write_byte_1
; part one: dataline low for 10 us
bcf DATA_DS1820 ;dataline low
movlw D'2'
call WAIT_5us ;wait for 2 x 5 = 10 us
; part two: if you send a '1', then release dataline
btfsc BYTE,0
bsf DATA_DS1820
; part three: wait 50 us and finally always release the dataline
movlw D'10'
call WAIT_5us ;wait for 10 x 5 = 50 us
bsf DATA_DS1820
rrf BYTE,1 ;move bits in BYTE 1 position to the right
decfsz BIT,1 ;countdown until BIT=0
goto one_wire_write_byte_1
return
;=================================================================================
ONE_WIRE_READ_BIT
; part one: dataline low for 5 us
bcf DATA_DS1820 ;dataline low
call WAIT_4us ;wait 4 us more
; part two: release dataline during 10 us and read dataline
bsf DATA_DS1820 ;release dataline
bsf STATUS,RP0 ;select BANK 1
bsf TRISA,4 ;define DATA_DS1820 for input ('1')
bcf STATUS,RP0 ;back to BANK 0
call WAIT_4us
nop
bcf DS1820_INPUT_BIT ;clear input-bit ...
btfsc DATA_DS1820 ;... and if DATA is not '0' ...
bsf DS1820_INPUT_BIT ;... then set input-bit
; part three: release dataline 45 us more
movlw D'7'
call WAIT_5us ;wait 7 x 5 = 35 us
btfss DATA_DS1820 ;if dataline is 0 ...
bsf DS1820_SHORTED ;... then line is shorted
bsf STATUS,RP0 ;selectBANK 1
bcf TRISA,4 ;define DATA_DS1820 back for output ('0')
bcf STATUS,RP0 ;and back again to BANK 0
return
;==============================================
WAIT_4us
; Wait 4 us (call included)
return
;=====================================================================
AFFICHE_TEMP
;initialisation des registre
clrf REG_1
clrf REG_2
clrf REG_3
clrf REG_4
clrf REG_5
bcf DS1820_VIRGULE ; initialisation : pas de virgule dans la temperature
movlw B'00101110' ; code de la virgule ds LCD
movwf REG_4
movlw B'00110101' ; code de "5" ds lcd
movwf REG_5
call CALCUL_REG1 ; sign
call CALCUL_REG2_REG3
CALL display_temp
RETURN
;=============================================
CALCUL_REG2_REG3
btfsc DS1820_TEMP,0
call ADD_5 ; ajouter "5" au registre REG_5
btfss DS1820_TEMP,0
call ADD_0
rrf DS1820_TEMP,1 ; decalage a droite pour enlever la virgule
bcf DS1820_TEMP,7 ; MSB = 0
movf DS1820_SIGN,1 ;check DS1820_ERROR and ...
btfss STATUS,Z ;... if DS1820_ERROR is not 0 ...
CALL calcul_negative
btfsc STATUS,Z
CALL calcul_positif
RETURN
calcul_positif
movlw D'10'
ici subwf DS1820_TEMP , 1
btfsc STATUS,C
incf REG_2 ,1
btfsc STATUS,C
goto ici
addwf DS1820_TEMP,0
movwf REG_3
return
calcul_negative
comf DS1820_TEMP,1 ; inverser, ajouter 1 et apres binaire -> bcd
incf DS1820_TEMP,1
ici2 movlw D'10'
subwf DS1820_TEMP,1
btfsc STATUS,C
incf REG_2,1
btfsc STATUS,C
goto ici2
addwf DS1820_TEMP,0
movwf REG_3
RETURN
;============================================
ADD_5
movlw B'00110101'
movwf REG_5
return
;=============================================
ADD_0
movlw B'00110000'
movwf REG_5
return
;=============================================
CALCUL_REG1
MOVF DS1820_SIGN,1
BTFSS STATUS , Z
CALL SIGNE_NEGATIF
BTFSC STATUS , Z
CALL SIGNE_POSITIF
return
SIGNE_POSITIF
MOVLW B'00101011'
MOVWF REG_1
RETURN
SIGNE_NEGATIF
MOVLW B'00101101'
MOVWF REG_1
RETURN
;=============================================
bonjour
BCF RS_LCD
MOVLW 0X80
MOVWF PORTB
bsf E_LCD
MOVLW D'3'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -