📄 ds1620.asm
字号:
title "DS1620 - Show the temperature of a DS160 via a 2-wire LCD interface"
;
; This Code continually polls a DS1620 and writes the temperature on an LCD
; via the 2-wire LCD interface.
;
; 2-Wire LCD INFO - Mike Predko
; The data is shifted out to a 74LS174 with The High Order Bit being a "Gate"
; Bit connected to the LCD's "E" line. The next Highest Bit goes to the
; LCD's "RS" Bit. The lowest Bit goes to D4 (and each Bit is higher from
; there).
;
;
; Data Being Sent looks like:
;
; Clear Shift Register Shift Data Strobe
;
; +----------------------+ +------------------------+
; | | | |
;
; +------+D+-+D+-+D+-+D+-+R+--E-----
; Data ------------------------+ +7+-+6+-+5+-+4+-+S+
; --+ +-+ +-+ +-+ +-+ +-+ +------+ +-+ +-+ +-+ +-+ +-+ +----
; Clock +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
; D7 D6 D5 D4 RS E +-+
; E ---------------------------------------------------+ +----
;
; Shift Data:
; Bit 1 - Always High (Gate for "E")
; Bit 2 - RS Bit
; Bit 3 - LCD D4
; Bit 4 - LCD D5
; Bit 5 - LCD D6
; Bit 6 - LCD D7
;
; DS1620 INFO - Drew Ames
; The data is shifted out on DSDQ clocked with DSCLK whilst DSRST is held
; high.
;
; PIC Hardware Notes:
; Reset is tied directly to Vcc and PWRT is Enabled.
; The PIC is a 12F675 Running at 4 MHz (internal clock).
; GPIO.0 is the LCD Data Bit
; GPIO.1 is the LCD Clock Bit
; GPIO.2 is the DS1620 Data Bit
; GPIO.3 is MCLR
; GPIO.4 is the DS1620 Clock Bit
; GPIO.5 is the DS1620 Reset Bit
;
;
LIST P=12F675, R=DEC ; 12F675 Runs at 4 MHz
; errorlevel 0,-305
INCLUDE "p12f675.inc"
; Register Usage
CBLOCK 0x020 ; Start Registers at End of the Values
; 2-Wire LCD Registers
Dlay ; 8 Bit Delay Variable
Temp ; Temporary Value Used When Sending Out Data
TempBIN ; Temporary area used when Sending binary Data
NOTemp ; Temporary Value to "NybbleOutput"
NOTmp1 ; Loop variable for inside "NybbleOut" only
DlyTmp ; Loop variable for inside Dlay only
; DS1620 registers
pt5 ; Remember if we had 0.5 on the end.
Tens ; When translating to decimal from binary
Units ; for display on the LCD, store the digits
ENDC
; Define Information
#DEFINE Data GPIO,0
#DEFINE Clock GPIO,1
#DEFINE DSDQ GPIO,2
; MCLR uses GPIO,3
#DEFINE DSCLK GPIO,4
#DEFINE DSRST GPIO,5
; 2-Wire LCD Macros
ClockStrobe MACRO ; Strobe the Data Bit
bsf Clock
bcf Clock
ENDM
EStrobe MACRO ; Strobe the "E" Bit
bsf Data
bcf Data
ENDM
PAGE
__CONFIG _CP_OFF & _INTRC_OSC_NOCLKOUT & _PWRTE_ON & _WDT_OFF
; Note that the WatchDog Timer is OFF
; Loop Forever showing the temp.
org 0
; Processor Initialisation
; BANK 1
bsf STATUS,RP0
movlw 0x00 ; Enable All pins for Output
movwf TRISIO
movlw b'11011100' ; Prescaler 16 on WDT from clock
movwf OPTION_REG
clrf ANSEL ; Ensure digital control
; Bank 0
bcf STATUS,RP0
clrf STATUS
clrf INTCON ; Disable all interrupts
clrf GPIO
movlw 0x07
movwf CMCON ; Turn off analog comparators
; LCD Initialisation
call InitLCD
call SndMsg ; Say Hello
call InitDS
MAIN movlw 0xc0 ; Move to line 2 on LCD
call SendINS
call GetTemp ; Read the temperature
call SendDEC ; Display it on the LCD
goto MAIN
;---------------------------------------------------------------
; DS1620 Subroutines
StartC MACRO
bsf DSRST
ENDM
StopC MACRO
bcf DSRST
ENDM
InitDS StartC
movlw 0x0c ; Write config
call SndByte
movlw b'00001010' ; CPU comms, continuous polling
call SndByte
StopC
nop
StartC
movlw 0xEE ; Start Conversion
call SndByte
StopC
return
GetTemp movlw 0xAA ; Read Temperature
StartC
call SndByte ; send the command
nop
call RdByte ; get the value
StopC
return
SndByte movwf NOTemp ; Send a Byte to the DS1620
movlw 8 ; Now, Shift out the Data
movwf NOTmp1
DSLoop1
bcf DSCLK
rrf NOTemp,f ; Shift Through the Nybble to Output
btfss STATUS,C ; Check the carry bit to see what to do
goto DSCLR ; Bit was clear so clear DSDQ
bsf DSDQ ; Bit was set so set DSDQ
goto DSLp1
DSCLR bcf DSDQ
nop
DSLp1 bsf DSCLK
decfsz NOTmp1,f ; Move on to next bit
goto DSLoop1
return
RdByte clrf NOTemp ; Read a Byte from the DS1620
movlw 8 ; Shift in 8 bits
movwf NOTmp1
bsf STATUS,RP0 ; Set DSDQ as an input
bsf TRISIO,2
bcf STATUS,RP0
DSLoop2
bcf DSCLK ; Toggle the clock line to get a bit
nop
rrf NOTemp,f ; Put the bit in NOTemp
btfss DSDQ ; Check the Bit
goto DSCLR2 ; Bit was clear so clear Bit7
bsf NOTemp,7 ; Bit was set so set Bit7
goto DSLp2
DSCLR2 bcf NOTemp,7
nop
DSLp2 bsf DSCLK
decfsz NOTmp1,f ; Move on to next bit
goto DSLoop2
bsf STATUS,RP0 ; Reset DSDQ as an output
bcf TRISIO,2
bcf STATUS,RP0
movfw NOTemp ; Return the byte in w
return
;---------------------------------------------------------------
; LCD Subroutines
Message ; Message to Output
addwf PCL,f ; Output the Characters
dt "Hello DS1620",0
SndMsg clrf FSR ; Output the Message
OutLoop
movf FSR,w ; Get the Offset to Output
incf FSR,f
call Message
iorlw 0 ; At the End of the Message?
btfsc STATUS,Z
goto RtnSnd ; Yes - Equal to Zero
call SendCHAR ; Output the ASCII Character
goto OutLoop
RtnSnd return
InitLCD
call Dlay5 ; Wait 20 msecs before Reset
call Dlay5
call Dlay5
call Dlay5
bcf STATUS,C ; Clear Carry (Instruction Out)
movlw 0x03 ; Reset Command
call NybbleOut ; Send the Nybble
call Dlay5 ; Wait 5msecs before Sending Again
EStrobe
call Dlay160 ; Wait 160 usecs before Sending the Third Time
EStrobe
call Dlay160 ; Wait 160 usecs after Sending the Third Time
bcf STATUS, C
movlw 0x02 ; Set 4 Bit Mode
call NybbleOut
call Dlay160
movlw 0x028 ; Note that it is a 2 Line Display
call SendINS
movlw 0x008 ; Turn off the Display
call SendINS
movlw 0x001 ; Clear the Display RAM
call SendINS
call Dlay5 ; Note, Can take up to 4.1 msecs
movlw 0x006 ; Enable Cursor Move Direction
call SendINS
movlw 0x00F ; Turn the LCD Back On
call SendINS
return
SendDEC ; Show the Decimal value on the LCD
movwf TempBIN
bcf pt5,0 ; Assume not something.5
btfsc TempBIN,0 ; Get the 0.5 DegC Bit
bsf pt5,0 ; Actually something.5
rrf TempBIN,f ; Kill the 0.5 DegC bit
clrf Tens ; Clear the count of tens
movlw 0x0A
count10 subwf TempBIN,f ; Take off 10 (in w) from TempBIN
btfss STATUS,C ; Check for underflow
goto SDEC1
incf Tens,f
goto count10
SDEC1 addwf TempBIN,w ; Put that last one back
; At this point Tens contains the tens and w contains the units
movwf Units
movfw Tens
addlw a'0' ; Send the Tens
call SendCHAR
movfw Units
addlw a'0' ; Send the Units
call SendCHAR
btfss pt5,0 ; Do we have pt5?
goto DEGC ; no
movlw a'.'
call SendCHAR
movlw a'5'
call SendCHAR
DEGC movlw a' '
call SendCHAR
movlw a'D'
call SendCHAR
movlw a'e'
call SendCHAR
movlw a'g'
call SendCHAR
movlw a'C'
call SendCHAR
movlw a' '
call SendCHAR
movlw a' '
call SendCHAR
return
SendBIN ; Send the Byte to the LCD in Binary
movwf TempBIN ; Save the Temporary Value
movlw a'1'
btfss TempBIN,7
movlw a'0'
call SendCHAR
movlw a'1'
btfss TempBIN,6
movlw a'0'
call SendCHAR
movlw a'1'
btfss TempBIN,5
movlw a'0'
call SendCHAR
movlw a'1'
btfss TempBIN,4
movlw a'0'
call SendCHAR
movlw a'1'
btfss TempBIN,3
movlw a'0'
call SendCHAR
movlw a'1'
btfss TempBIN,2
movlw a'0'
call SendCHAR
movlw a'1'
btfss TempBIN,1
movlw a'0'
call SendCHAR
movlw a'1'
btfss TempBIN,0
movlw a'0'
call SendCHAR
return
SendCHAR ; Send the Character to the LCD
movwf Temp ; Save the Temporary Value
swapf Temp,w ; Send the High Nybble
bsf STATUS,C ; RS = 1
call NybbleOut
movf Temp,w ; Send the Low Nybble
bsf STATUS,C
call NybbleOut
return
SendINS ; Send the Instruction to the LCD
movwf Temp ; Save the Temporary Value
swapf Temp,w ; Send the High Nybble
bcf STATUS,C ; RS = 0
call NybbleOut
movf Temp,w ; Send the Low Nybble
bcf STATUS,C
call NybbleOut
call Dlay5
return
NybbleOut ; Send a Nybble to the LCD
movwf NOTemp ; Save the Nybble to Shift Out
swapf NOTemp,f ; Setup to Output to the High Part of the Byte
bsf NOTemp,0 ; Store the CARRY Bit in NOTemp,0
btfss STATUS,C
bcf NOTemp,0
movlw 6 ; Clear the Shift Register
movwf NOTmp1
bcf Data
NOLoop1
ClockStrobe
decfsz NOTmp1,f
goto NOLoop1
bsf Data ; Put out the Gate Bit for E
ClockStrobe
bcf Data ; Put out the RS Bit
bsf STATUS,C ; Restore the CARRY Bit
btfss NOTemp,0
bcf STATUS,C
rlf GPIO,f
ClockStrobe
movlw 4 ; Now, Shift out the Data
movwf NOTmp1
NOLoop2
rlf NOTemp,f ; Shift Through the Nybble to Output
bcf Data ; Clear the Data Bit (which is the Clock)
rlf GPIO,f ; Shift the Carry into the Shift Register
ClockStrobe
decfsz NOTmp1,f
goto NOLoop2
EStrobe ; Strobe out the LCD Data
return
;---------------------------------------------------------------
; Delay Subroutines
Dlay160 ; Delay 160 usecs
movlw 256 - ( 160 / 4 ); Loop Until Carry Set
addlw 1
btfss STATUS,C
goto $-2
return
Dlay100 call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
call Dlay5
return
Dlay5 ; Delay 5 msecs
movlw 4 ; Set up the Delay
movwf DlyTmp
movlw 256 - 0x0E8
addlw 1
btfsc STATUS, Z
decfsz DlyTmp,f
goto $-3
return
org 0x3ff ; Set the OSCCAL value from the target chip.
fill 0x34a4,1
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -