⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sht11lcd.asm

📁 SH11温湿度传感器用LCD显示的程序
💻 ASM
字号:
;---------------------------------------------------------------
;Program to read data from SHT sensor, convert it and
;	dispaly on the LCD
;		claudiu.chiculita@ugal.ro
;		http://www.ac.ugal.ro/staff/ckiku/software
;
; Sensor is connected to pins 3,4 of PORTC
; LCD data (4..7) connected to (0..3) of PORTA 
;---------------------------------------------------------------
;
;ConnectionReset
;TransmissionStart
;SHT_WriteByte
;WaitForData
;SHT_ReadByte
;AddCRC1byte, ReverseByte			- used to compute CRC
;SHT_ReadStatus, SHT_WriteStatus  	- not implemented
;
;LinearizeHumidity					- 3xLinear, my method
;BCD8_100							- used to convert % Humidity
;ComputeAsciiTemp					- convert Temperature
;InitLCD, InitTXT, ErrTXT			- LCD dispaly



	LIST      P=16F876A, F=INHX8M	; list directive to define processor
	#include "p16f876a.inc"			; processor specific variable definitions
	__CONFIG  _HS_OSC & _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _LVP_OFF & _DEBUG_OFF & _CPD_OFF
	
	radix dec
	errorlevel -302, -305
xtal EQU 20000000

	CBLOCK 0x20
	cnt1
	cnt2
	cnt3			;cnt1/2/3 for delay
	al
	ah				;ah/al used in crc compuations
	crc				;computed crc so far
	byte			;used in send/rcv
	info1
	info2
	infocrc			;info1/2/crc  store the values received
	contor			;cycle bits
	i
	thebyte, rwbyte
	SHT_reg_image	;image of SHT11 status reg
	humip128,humip32
	txtTemp:5
	t100,t10,t1,tdot,t01
	txtHumi:9
	bcd100,bcd10,bcd1
	txtDewP
	
	hi,lo,shi,slo,digit	; convet temp
	negative
	ENDC
	
;pin assignments:
#define	DATApin  PORTC,4	;PORTC,4
#define	CLKpin   PORTC,3	;PORTC,3

                            ;adr  command  r/w
#define STATUS_REG_W 0x06   ;000   0011    0
#define STATUS_REG_R 0x07   ;000   0011    1
#define MEASURE_TEMP 0x03   ;000   0001    1
#define MEASURE_HUMI 0x05   ;000   0010    1
#define RESET_SHT    0x1e   ;000   1111    0

BANK0_	macro			;BANK1 -> BANK0
		bcf		STATUS,RP0
		endm
BANK1_	macro			;BANK0 -> BANK1
		bsf		STATUS,RP0
		endm

tmic	macro
		goto	$+1
		endm
; at high frequency xtals and *very* long wires to the sensor
; you may wish to add a small delay (several instructions)
; at the end of SDAT and SCLK macros
; also the pull-up resistor should be smaller
SDAT	macro updown
		if updown==0
			bcf		DATApin
		else
			bsf		DATApin
		endif
		endm

SCLK	macro updown
		if updown==0
			bcf		CLKpin
		else
			bsf		CLKpin
		endif
		endm

MakeSDATinput	macro
		BANK1_
		bsf		DATApin		;TRIS=1
		BANK0_
		endm

MakeSDAToutput macro
		BANK1_
		bcf		DATApin		;TRIS=0
		BANK0_
		endm

DelayN	macro msx10
	movlw msx10
	call DelayMs
	endm

loadw	macro	arg1
	movlw	high(arg1)
	movwf	hi
	movlw	low(arg1)
	movwf	lo
	endm
loads	macro	arg1
	movlw	high(arg1)
	movwf	shi
	movlw	low(arg1)
	movwf	slo
	endm
dodigit	macro	arg1
	loads	arg1
	call	dosub
	endm


;ooooooooooooo RESET ooooooooooooooooooooooooo
	ORG       0x0000
	clrf	STATUS
	movlw	0x00
	movwf	PCLATH
	goto	init


;************ initial *******************
init
	clrf PORTA
	bsf     STATUS,RP0		; select bank 1
    movlw   d'10'			; at 20Mhz with 115200 => 10
    movwf   SPBRG			; at  4Mhz with  19200 => 12
    movlw	b'00100100'		; TXEN+BRGH
    movwf	TXSTA
	movlw 6
	movwf ADCON1
	clrf TRISA				;all outputs
	movlw B'11111100'
	movwf TRISC
    ;
    bcf		CLKpin			;TRIS=0	 CLK=output
    ;
    bcf		STATUS,RP0		; select bank 0
    movlw	b'10010000'
    movwf	RCSTA
    bcf		PORTC,0
    bcf		PORTC,1

	clrf	SHT_reg_image	;Status register of SHT11 is initially 0
	call	InitLCD
	call	InitTXT
start
	movlw	5
	call SHT11_acquire
		addlw	0			;check errors
		btfss	STATUS,Z
		goto	treatcommerr
	call	LinearizeHumidity
	movwf	byte
	call	BCD8_100
	
	movlw	3
	call SHT11_acquire
		addlw	0			;check errors
		btfss	STATUS,Z
		goto	treatcommerr
	movf	info1,w
	movwf	hi
	movf	info2,w
	movwf	lo
	loads	4000
	clrf	negative
	call	Sub16
	bc		positive
	loads	1				;take absolute value
	call	Sub16
	comf	hi
	comf	lo
	incf	negative
positive
	call	ComputeAsciiTemp
afisLCD
	movlw	0x02			; home
	call	LCD_Cmd

	bsf		rwbyte,5
	movlw	23
	movwf	contor
	movlw	txtTemp-1
	movwf	FSR
incafis	
	incf	FSR
	movf	INDF,w
	call	LCD_Cmd
	decfsz	contor
	goto	incafis
	clrf	rwbyte
	
	movlw	0
	call	DelayMs
	movlw	0
	call	DelayMs
	goto	start

treatcommerr
	call	ErrTXT
	goto	afisLCD	

;************** PROCEDURES ****************************************	
SHT11_acquire
	; expects in W the command to be sent 3/5
	movwf	byte
	MakeSDAToutput
	call	TransmissionStart
	tmic
		movf	SHT_reg_image,w
		movwf	crc			;crc is initialised with Status Register = 0
	
		movf	byte,w
		call	AddCRC1byte	;command also enters in crc sum
	call	SHT_WriteByte
		btfsc	STATUS,C		; in case of error(ack not received)
		goto	ErrorNoACK     ; Send err 
	call	WaitForData
		xorlw	1				; 1=timeout
		btfsc	STATUS,Z		
		goto	ErrorTimeout	;W=1
	call	SHT_ReadByte		;H
		movwf	info1
		call	AddCRC1byte          
	call	SHT_ReadByte		;L
		movwf	info2
		call	AddCRC1byte
	call	SHT_ReadByte		;CRC
		movf	byte,w
		movwf	infocrc
		call	ReverseByte
		
	;check CRC
		xorwf	crc
		btfss	STATUS,Z
		goto	ErrorCRCFailed
		
	;Here we do whatever we want with the values: info1,info2
	retlw	0		;OK

ErrorNoACK					;treat errors
	movlw	253		
	goto	DoError
ErrorTimeout
	movlw	254		
	goto	DoError
ErrorCRCFailed
	movlw	255		
	goto	DoError
DoError
	;call	SendW
	call	ConnectionReset
	retlw	255			;error


;------------------------------------------------------------------
TransmissionStart
	SDAT 1
	;SCLK  0	;?default
	SCLK 1
	SDAT 0
	SCLK 0
	SCLK 1
	SDAT 1
	SCLK 0
	return


;----------------------------------------------------------------------------------
; writes a byte to the sensor
; -> SDAT must be output already (and the line should be in 1) as left from TransmissionStart
; -> At the end the SDAT will be left as input
; -> Carry=1 if no ACK was received
SHT_WriteByte
	movlw	8
	movwf	contor
altbitw
	SCLK 0				
	rlf		byte
	btfss	STATUS,C
	SDAT 0
	btfsc	STATUS,C
	SDAT 1
	SCLK 1
	decfsz	contor		
	goto	altbitw		
	
	SCLK 0				; see NOTE(1)
	MakeSDATinput		;
	SCLK 1
	bcf		STATUS,C
	btfsc	DATApin
	bsf		STATUS,C		; signal error  Carry=1
	SCLK 0
	return
	

;//----------------------------------------------------------------------------------
;// reads a byte form the sensor
; -> Data from sensor must be now ready to read
; -> SDAT must be input already (and the line should be in zero)
; -> SCLK=0
; output => reading = byte = W
SHT_ReadByte
	movlw	8
	movwf	contor
altbitr
	SCLK 1
	bcf		STATUS,C		
	btfsc	DATApin		;read line
	bsf	STATUS,C
	rlf		byte
	SCLK 0
	decfsz	contor
	goto	altbitr
	
	MakeSDAToutput
	SDAT 0				;gives ACK
	SCLK 1
	SCLK 0
	MakeSDATinput
	
	movf	byte,w
	return 
	
	
;--------------------------------------------
WaitForData				; Timeout of 250ms
	movlw	4			; =4 for xtal=20MHz
	movwf	cnt1
ddc1
	clrf	cnt2
ddc2	
	clrf	cnt3
ddc3
		btfss	DATApin	;wait for data to go low
		retlw	0
	decfsz	cnt3
	goto	ddc3
	decfsz	cnt2
	goto	ddc2
	decfsz	cnt1
	goto	ddc1
	retlw	1			;Timeout
	
	
;----------------------------------------------		
SendW
	btfss	PIR1,TXIF	;empty?
	goto	SendW
	movwf	TXREG
	return
	
	
;----------------------------------------------		
;W=new byte				crc = crc # W
AddCRC1byte
	movwf	al
	movlw	8
	movwf	contor
abitcrc	
	movf	al,w
	xorwf	crc,w
	movwf	ah
	rlf		ah
	movlw	b'00011000'
	btfsc	STATUS,C
	xorwf	crc			
	rlf		crc
	rlf		al
	
	decfsz	contor
	goto	abitcrc
	return


;----------------------------------------------			
;W -> byte to be inverted
ReverseByte
	movwf	ah
	movlw	8
	movwf	contor 
ivbi
	rlf		ah
	rrf		al
	decfsz	contor
	goto	ivbi
	movf	al,w
	return
	
	
;----------------------------------------------			
ConnectionReset
	SDAT 1
	SCLK 0
	movlw	9
	movwf	contor
crac
	SCLK 1
	SCLK 0	
	decfsz	contor
	goto	crac
	call	TransmissionStart
	return
	
;########################################################################3
InitLCD
	DelayN 50
	clrf	rwbyte
	movlw	3
	call	Raw1
	DelayN 5
	movlw	3
	call	Raw1
	DelayN 1
	movlw	3
	call	Raw1
	DelayN 1
	movlw	2
	call	Raw1
	DelayN 1
	
	movlw	0x20		
	call	LCD_Cmd
	movlw	0x08		; off
	call	LCD_Cmd
	movlw	0x01		; clr
	call	LCD_Cmd
	movlw	0x0c		; on:	1 on curs blink
	call	LCD_Cmd
	movlw	0x06		; mode: 0  1  inc shift
	call	LCD_Cmd
	DelayN 10
	return

Raw1
	movwf	PORTA
	bsf		PORTA,4
	nop
	bcf		PORTA,4
	return

LCD_Cmd
	movwf	thebyte
	swapf	thebyte,w
	andlw	0fh
	iorwf	rwbyte,w
	call Raw1
	movf	thebyte,w
	andlw	0fh
	iorwf	rwbyte,w
	call Raw1
	DelayN 5
	return
	
	
; ##########################################################################	
LinearizeHumidity	
	movf	info1,w				;x/128
	movwf	humip128
	rlf		info2,w
	rlf		humip128
	;
	swapf	info1,w				;x/32
	andlw	0f0h
	movwf	humip32
	swapf	info2,w
	andlw	0fh
	iorwf	humip32
	bcf		STATUS,C
	rrf		humip32
	;
	movlw	4
	subwf	info1,w
	btfsc	STATUS,C
	goto	linh_f2
	movf	humip128,w			; x<1024
	addlw	-3
	addwf	humip32
	movlw	200					; do not go below 0
	subwf	humip32,w
	btfsc	STATUS,C
	clrf	humip32
	goto	linh_fe
linh_f2
	movlw	10
	subwf	info1,w
	btfsc	STATUS,C
	goto	linh_f3
	movf	humip32,w			; 1024<=x<2560
	addlw	4
	movwf	humip32
	goto	linh_fe
linh_f3
	movf	humip128,w			; 2560<=x
	addlw	-24
	subwf	humip32
linh_fe
	movf	humip32,w
	return


;##########################################################################	
BCD8_100	;used to convert % Humidity
	;input:  8 bit positive number [0..255]
	;output: bcd100,bcd10,bcd1	(+leading spaces +saturate on 100)
	;
	movwf	byte
	movlw	' '
	movwf	bcd100			; bcd100=' '
	clrf	bcd10
	decf	bcd10			; bcd10 = -1
	movlw	'0'-1
	movwf	bcd1			; bcd1  = '/'
	movlw	100
	subwf	byte,w
	btfsc	STATUS,C
	goto	bcd8_big100
	movlw	10				;below 100
bcd8_big10					;still >10
	subwf	byte			
	incf	bcd10
	btfsc	STATUS,C
	goto	bcd8_big10
		movlw	'0'
		btfsc	STATUS,Z	;Z=1 if byte<10
		movlw	' '
	addwf	bcd10
	movlw	11
	addwf	byte
	
bcd8_big1
	incf	bcd1
	decfsz	byte
	goto	bcd8_big1
	return
	
bcd8_big100
	movlw	'0'
	movwf	bcd100
	incf	bcd100
	movwf	bcd10
bcd8_end
	return

;########################################################################
;input:  temperature in (hi,lo)
;output: t100,t10,t1,t01	( +leading spaces +[leading minus])
ComputeAsciiTemp
	dodigit	10000
	movwf	t100
	dodigit	1000
	movwf	t10
	dodigit	100
	movwf	t1
	dodigit	10
	movwf	t01
	;"remove" zeroes
	BANKISEL 0
	movlw	t100
	movwf	FSR
	
	movlw	'0'
	xorwf	INDF,w
	skpz
	goto	ddrzend
	movlw	' '
	movwf	t100

	incf	FSR
	movlw	'0'
	xorwf	INDF,w
	skpz
	goto	ddrztn
	movlw	' '
	movwf	t10
	incf	FSR
ddrztn				;test negative
	decfsz	negative
	goto	ddrzend
	decf	FSR
	movlw	'-'
	movwf	INDF
ddrzend	
	return			; done

; "dosub" is called by the "dodigit" macro defined above.
; Subtract the number in shi/slo from hi/lo until the result
; is negative, incrementing the ascii equivelent each time.

dosub
	movlw	'0'-1
	movwf	digit
moresub	
	incf	digit,F		; increment ASCII character
	call	Sub16		; (hi,lo) - (shi,slo)
	btfsc	STATUS,C	; any carry?
	goto	moresub		; no, keep subtracting

	call	Add16		; reverse the last subtraction
	movf	digit,W
	return

Sub16
	movf	slo,w		; subtract current power of 10
	subwf	lo,f		; lo = lo - slo
	movf	shi,w
	btfss	STATUS,C
	addlw	1
	subwf	hi,f		; hi = hi - shi - NC
	return

Add16
	movf	slo,w		
	addwf	lo,f
	movf	shi,w
	btfsc	STATUS,C
	addlw	1
	addwf	hi,f
	return
	
;###########################################################################
; prepare the text: Temp:000.0^C__Humi:000%
InitTXT
	movlw 'T'
	movwf txtTemp
	movlw 'e'
	movwf txtTemp+1
	movlw 'm'
	movwf txtTemp+2
	movlw 'p'
	movwf txtTemp+3
	movlw ':'
	movwf txtTemp+4
	movlw '.'
	movwf tdot
	
	movlw 0xdf
	movwf txtHumi
	movlw 'C'
	movwf txtHumi+1
	movlw ' '
	movwf txtHumi+2
	movlw ' '
	movwf txtHumi+3
	movlw 'H'
	movwf txtHumi+4
	movlw 'u'
	movwf txtHumi+5
	movlw 'm'
	movwf txtHumi+6
	movlw 'i'
	movwf txtHumi+7
	movlw ':'
	movwf txtHumi+8
	movlw '%'
	movwf txtDewP
	return
;###########################################################################
; text on error: Temp:000.0^C__Humi:000%
ErrTXT
	movlw ' '
	movwf t100
	movwf t10
	movwf t01
	movwf bcd100
	movwf bcd1
	movlw '?'
	movwf t1
	movwf bcd10
	return
;###########################################################################
DelayMs				;ms
	;movlw 10		;in W (sau cnt1) parametru intirzierea 1..255
	movwf cnt1		;incarc pe cnt1 din delval din prog Pp
delaymsjcnt1
	movlw d'7'
	movwf cnt2
delaymsjcnt2
	movlw d'236'
	movwf cnt3
delaymsjcnt3
	decfsz cnt3
	goto delaymsjcnt3
	decfsz cnt2
	goto delaymsjcnt2
	decfsz cnt1
	goto delaymsjcnt1
	return
	
            END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -