; Project�� : Digital thermometer
; By� : Chow Ying Hau
; Date����� : 03 Dec 04
; Status��� : Success!
; Comment�� : 2 Wires Interface between DS1631 & PIC
;���� � Temperature displayed via 4 7-segment using time
;���� � division technique
;--------------------------------------------------------------------
����� #include <p16f84a.inc>
����� __config��� _CP_OFF & _PWRTE_OFF & _WDT_OFF & _RC_OSC
;--------------------------------------------------------------------
����������������� ;define variable in RAM
Data_Byte�� equ�� 0x0c
Bit_Count�� equ�� 0x0d
MS_Byte���� equ�� 0x0e
LS_Byte���� equ�� 0x0f
BCD�� equ�� 0x10
_7SegmentA� equ�� 0x11
_7SegmentB� equ�� 0x12
_7SegmentC� equ�� 0x13
_7SegmentD� equ�� 0x14
Loop_Count� equ�� 0x4d
temp2 equ�� 0x4e
temp1 equ�� 0x4f
main: org�� 0x000 ; program section
����� bsf�� STATUS,RP0� ; bank 1
����� clrf� TRISA ; set PORTA<4:0> as output
����� clrf� TRISB ; set PORTB<7:0> as output
����� bcf�� STATUS,RP0� ; bank 0
����� clrf� PORTA ; initialize PORTA & B
����� clrf� PORTB
�����
����� call� delay
�����
����� ; issue a "Start Convert T"��
����� call Start_Con�� ; Start Condition
����� movlw 0x90
����� call Command���� ; Control Byte,W
����� movlw 0x51
����� call� Command���� ; "Start Convert T" Command Byte
����� call� Stop_Con��� ; Stop Condition
�����
����� call� delay
�����
����� ; read from Temperature Register
LoopA:����� call Start_Con�� ; Start Condition
����� movlw 0x90
����� call Command���� ; Control Byte,W
����� movlw 0xaa
����� call� Command���� ; "Read Temperature" Command Byte
����� call� Start_Con�� ; Repeat Start
����� movlw 0x91
����� call Command���� ; Control Byte,R
����� call� Read_Byte�� ; retrieve MS Data Byte (from THERM)�����
����� call� Zero� ; ACK
����� movfw Data_Byte
����� movwf MS_Byte
����� call� Read_Byte�� ; retrieve MS Data Byte (from THERM)�����
����� call� One�� ; NACK
����� movfw Data_Byte
����� movwf LS_Byte
����� call� Stop_Con
����� ; change magnitude of MS to BCD
DEC2BCD:��� clrf� _7SegmentA� ; initialize variable
����� btfss MS_Byte,7�� ; MS<7>=1?� Temperature sign bit
����� goto� Label_E
����� bsf�� _7SegmentA,6; _7SegmentA as negative indicator
����� movlw 0xff� ; get MS & LS's magnitude
����� xorwf MS_Byte,f
����� xorwf LS_Byte,f
����� incf� LS_Byte,f
����� btfsc STATUS,C
����� incf� LS_Byte,f��
Label_E:��� movlw 0x0f
����� andwf MS_Byte,w�� ; mask out lower nibble
����� movwf BCD
����� call� Limit
����� btfss MS_Byte,4
����� goto� Label_F
����� movlw 0x16
����� addwf BCD,f
����� call� Limit
Label_F:��� btfss MS_Byte,5
����� goto� Label_G
����� movlw 0x32
����� addwf BCD,f
����� call� Limit
Label_G:��� btfss MS_Byte,6
����� goto� Label_H
����� movlw 0x64
����� addwf BCD,f
����� call� Limit
����� ; assign data to 7-segments' buffer
Label_H:��� movlw 0x0f
����� andwf BCD,w ; mask out lower nibble
����� call� Table
����� movwf _7SegmentC
����� swapf BCD,f
����� movlw 0x0f
����� andwf BCD,w ; mask out upper nibble
����� call� Table
����� movwf _7SegmentB
����� movlw 0x3F� ; 0
����� btfsc LS_Byte,7
����� movlw 0x6d� ; 5
����� movwf _7SegmentD
�����
����� ; display result via 7-segments
����� movlw 0x20
����� movwf Loop_Count
LoopB:����� movfw _7SegmentA� ; display first digit
����� movwf PORTB
����� bsf�� PORTB,7
����� call� delay
����� bcf�� PORTB,7
����� movfw _7SegmentB� ; display second digit
����� movwf PORTB
����� bsf�� PORTA,0
����� call� delay
����� bcf�� PORTA,0
����� movfw _7SegmentC� ; display third digit
����� movwf PORTB
����� bsf�� PORTA,1
����� call� delay
����� bcf�� PORTA,1
����� movfw _7SegmentD� ; display fourth digit
����� movwf PORTB
����� bsf�� PORTA,2
����� call� delay
����� bcf�� PORTA,2
����� decfsz����� Loop_Count,f
����� goto LoopB
����� goto� LoopA
;------Seven segment lookup table-----------------------------------
Table:����� addwf PCL,f
����� retlw 0x3F� ; 0
����� retlw 0x06� ; 1
����� retlw 0x5b� ; 2
����� retlw 0x4f� ; 3
����� retlw 0x66� ; 4
����� retlw 0x6d� ; 5
����� retlw 0x7d� ; 6
����� retlw 0x07� ; 7
����� retlw 0x7f� ; 8
����� retlw 0x6f� ; 9
�����
;------Sub Ensure BCD within range 0-9 ------------------------------
Limit:����� movlw 0x06
����� addwf BCD,w
����� btfsc STATUS,DC
����� movwf BCD
����� movlw 0x60
����� addwf BCD,w
����� btfss STATUS,C���
����� return
����� movwf BCD
����� movlw 0x06� ; 1
����� movwf _7SegmentA
����� return�����
�����
;------Sub Command/Control Byte (C>P)--------------------------------
����� ; mov DATA into W before call this sub program!
Command:��� movwf Data_Byte
����� movlw 0x08� ; Command/Control Byte=8bits
����� movwf Bit_Count�� ; initialize bit counter
Next_Bit1:� rlf�� Data_Byte,f
����� btfsc STATUS,C
����� goto� Label_A
����� call� Zero
����� goto� Label_B
Label_A:��� call� One
Label_B:��� decfsz����� Bit_Count,f
����� goto� Next_Bit1��
����� call� Zero� ; ACK
����� return�����
;------Sub Read Data Byte (C<P)--------------------------------------
����� ; read data from I2C into "Data_Byte"
����� ; need call NACK or ACK after call this sub program
Read_Byte:� bsf�� STATUS,RP0� ; bank 1
����� bsf�� TRISA,4���� ; set PORTA<4> as input (SDA)
����� bcf�� STATUS,RP0� ; bank 0
����� movlw 0x08� ; Data Byte=8bits
����� movwf Bit_Count�� ; initialize bit counter
Next_Bit2:� bsf�� PORTA,3���� ; SCL=1
����� btfsc PORTA,4���� ; read SDA=1
����� goto� Label_C
����� bcf�� STATUS,C
����� goto� Label_D
Label_C:��� bsf�� STATUS,C
Label_D:��� rlf�� Data_Byte,f ; save data
����� bcf�� PORTA,3���� ; SCL=0
����� decfsz����� Bit_Count,f
����� goto� Next_Bit2��
����� bsf�� STATUS,RP0� ; bank 1���
����� bcf�� TRISA,4���� ; set PORTA<4> as output (SDA)
����� bcf�� STATUS,RP0� ; bank 0
����� return
;------Sub Start Condition-------------------------------------------
Start_Con:� bsf�� PORTA,4���� ; SDA=1
����� bsf�� PORTA,3���� ; SCL=1����
����� bcf�� PORTA,4���� ; SDA=0
����� bcf � PORTA,3���� ; SCL=0
����� return
�����
;------Sub Stop Condition--------------------------------------------
Stop_Con:�� bcf�� PORTA,4���� ; SDA=0
����� bsf�� PORTA,3���� ; SCL=1����
����� bsf�� PORTA,4���� ; SDA=1
����� return
;------Sub One/NACK--------------------------------------------------
One:� bsf�� PORTA,4���� ; SDA=1
����� bsf�� PORTA,3���� ; SCL=1
����� bcf�� PORTA,3���� ; SCL=0
����� return
;------Sub Zero/ACK--------------------------------------------------
Zero: bcf�� PORTA,4���� ; SDA=0
����� bsf�� PORTA,3���� ; SCL=1
����� bcf�� PORTA,3���� ; SCL=0
����� return
;------Sub Delay-----------------------------------------------------
delay:����� movlw 0x20� ;delay
����� movwf temp1
level1:���� decfsz ���� temp1,f
����� goto level1
����� return
����� end