TCN75 alapú hőmérsékletmérő alapprogram

Az alábbi program egy TCN75 hőmérséklet érzékelővel kialakított egyszerű hőmérő, ami I2C-buszt használ. A TCN75 A0:A2 vonalainak bináris kombinációjával adható meg az eszköz SLAVE címe. A program a 0x00 című SLAVE-re hivatkozik, illetve itt kell megadnunk egy fix azonósítót és hogy írni vagy olvasni akarunk.

A hőmérséklet egy 16 bites regiszterből olvasható, ami 0,5 °C fokok reprezentációja. Ez azt jelenti, hogy ha egész értékre akarjuk kerekíteni a hőmérsékletet osztanunk kellene kettővel (RRF), vagyis ugyis kirotálnák ezt a bitet. Tehát, ha lemondunk az 0,5-ről akkor elég a HIGH Byte-ot olvasnunk és megkapjuk a hőmérsékletet. (Végül is a regiszter kialakításakor nyilván ez volt a cél)

A kondenzátor beépítése alapvető jelentőségű, nélküle akár 2-3 °C ugrálás is lehetséges.

Lásd még:
TCN75, 2-Wire Serial Temperature Sensor and Thermal Monitor


 
; PIC16F873 4MHz
; HŐMÉRSÉKLETMÉRŐ ALAPPROGRAM
; TCN75 HŐMÉRSÉKLETÉRZÉKELŐ
; HD44780 ALAPÚ LCD
; JErvin © 2005

LIST P=16F873
#include "P16F873.INC" 

TEMPW		EQU		0x020	; TEMPW
LO		EQU		0x021	; DELAY LO
HI		EQU		0x022	; DELAY HI
INTLO		EQU		0x023
INTHI		EQU		0x024
NUM		EQU		0x025
I2CDATA		EQU		0x026
TCNTEMPINT	EQU		0x027
TCNCONFIG	EQU		0x028	

BANK0:		MACRO
		BCF		STATUS, RP0
		ENDM

BANK1:		MACRO
		BSF		STATUS, RP0
		ENDM		

		ORG		0x0000
		GOTO	INIT


;
; INIT
;
INIT:	
	CALL	LCDINIT			; LCD BEÁLLÍTÁS
	CALL	LCDCRSOFF
	CALL	I2CINIT			; I2C BEÁLLÍTÁS
	MOVLW	b'00000000'		; MINDEN ALAPRA
	CALL	TCNSETCONFIG

;
; MAIN
;
MAIN		
	CALL	LCDCLR			; LCD TÖTLÉSE
	CALL	LCDHOME0		; LCD HOME
	MOVLW	'T'			; 'T=' KIÍRÁSA
	CALL	LCDCHAR
	MOVLW	'='
	CALL	LCDCHAR
	CALL	TCNREADTEMP		; HŐMÉRÉKLET OLVASÁSA
	BANK0
	MOVFW	TCNTEMPINT		; INTLO = TCNTEMPINT
	MOVWF	INTLO
	CLRF	INTHI			; INTHI = 0
	CALL	INTTOSTR
	MOVLW	b'11011111'		; A FOK ASCII KÓDJA
	CALL	LCDCHAR
	MOVLW	'C'
	CALL	LCDCHAR
	CALL	PROGRESSBAR		; SZÜNET
	GOTO	MAIN

;
; PROGRESSBAR: PONTOKAT ÍR AZ LCD-RE AZ ÚJ MÉRÉSIG
; 
PROGRESSBAR:
	CALL	LCDHOME1
	MOVLW	0x0A
	MOVWF	NUM
	MOVLW	'.'
	CALL	LCDCHAR
	CALL	DELAYLCD
	DECFSZ	NUM
	GOTO	$-4
	RETURN

;-------------------------------------------------------------------
; TCN75 RUTINOK
;
; USES: TCNCONFIG, TCNTEMPINT
;
; TCNSETCONFIG: CONFIGURATION REGISTER = W
; TCNREADTEMP: TCNTEMPINT = TEMERATURE REGISTER (!CSAK A HI-BYTE)
;
;-------------------------------------------------------------------
;TCN75 ADDRESS: [A7:A4]=FIX(1001b), [A3:A1]=SLAVE(000b), [A0]=W/R
#define TCNWADDRESS	b'10010000'	; CÍM ÍRÁSRA
#define TCNRADDRESS	b'10010001'	; CÍM OLVASÁSRA
#define TCNTEMPREG	0x00		; TEPERATURE REGISTER
#define TCNCONFIGREG	0x01		; CONFIGURATION REGISTER
#define TCNHYSTREG	0x02		; HYSTERESIS REGISTER
#define TCNPOINTREG	0x03		; SET POINT REGISTER
;
; TCNSETCONFIG: CONFIGURATION REGISTER = W
;
TCNSETCONFIG:
	BANK0
	MOVWF	TCNCONFIG
	CALL	I2CSTART
	MOVLW	TCNWADDRESS
	CALL	I2CWRITE
	MOVLW	TCNCONFIGREG
	CALL	I2CWRITE
	CALL	I2CSTOP
	CALL	I2CSTART
	MOVLW	TCNWADDRESS
	CALL	I2CWRITE
	BANK0
	MOVFW	TCNCONFIG
	CALL	I2CWRITE
	CALL	I2CSTOP
	RETURN
;
; TCNREADTEMP: KIOLVASSA A TEMERATUR REGISTERT
; ! A TEMPERATURE REGISTER HI BYTE TARTALMA KERÜL A TCNTEMPINT-BE, 
; ! ÍGY KIEJTJÜK A 0.5 C FOKOT ÉS EGÉSZKÉNT KAPJUK A HŐMÉRSÉKLETET 
; ! KETTES KOMPLEMENSBEN.
;
TCNREADTEMP:
	CALL	I2CSTART
	MOVLW	TCNWADDRESS
	CALL	I2CWRITE
	MOVLW	TCNTEMPREG
	CALL	I2CWRITE
	CALL	I2CSTOP
	CALL	I2CSTART
	MOVLW	TCNRADDRESS
	CALL	I2CWRITE
	CALL	I2CREAD				; HI BYTE OLVASÁSA
	MOVWF	TCNTEMPINT			; TCNTEMPINT = HI
	CALL	I2CREAD
	CALL	I2CSTOP
	RETURN

;-------------------------------------------------------------------
; I2C RUTINOK
;
; USES: I2CDATA
;
; I2CINIT		: 100 kHz, MASTERMODE
; I2CSTART		: START	KÜLDÉSE
; I2CSTOP		: STOP KÜLDÉSE
; I2CWRITE		: W KIÍRÁSA I2CBUS-RA ÉS I2CDATA-BA
; I2CREAD		: I2CBUS OLVASÁSA W-BE ÉS I2CDATA-BA
; I2CWAIT		: VÁRAKOZÁS, AMÍG A BUS FOGLALT 
; I2CCHECKACK	: NYUGTA ELLENŐRZÉS, HIBA ESETÉN GOTO I2CHALT
; I2CHALT		: PROGRAM LEÁLLÍTÁS I2CACK MIATT, HIBA AZ LCD-RE
;-------------------------------------------------------------------
#define FOSC 		.4000
#define	BAUD 		.100
#define I2CTRIS	TRISC
#define I2CSCL		3
#define I2CSDA		4
;
; I2CINIT: 100 kHz, MASTERMODE
;
I2CINIT:
	BANK1		
	BSF	I2CTRIS, I2CSCL			; SCL KIMENET
	BSF	I2CTRIS, I2CSDA			; SDA KIMENET
	MOVLW	b'10000000'			; STANDARD MODE
	MOVWF	SSPSTAT				; SET
	MOVLW	FOSC/(4*BAUD)-1			; 100 kHz
	MOVWF	SSPADD				; SET
	BANK0					;
	MOVLW	b'00101000'			; SSPEN, MASTERMODE
	MOVWF	SSPCON				; SET
	RETURN
;
; I2CSTART: START KÜLDÉSE
;
I2CSTART:
	BANK1
	BSF	SSPCON2, SEN			; START BIT
	BTFSC	SSPCON2, SEN			; KÉSZ?
	GOTO	$-1
	RETURN
;
; I2CSTOP: STOP KÜLDÉSE
;
I2CSTOP:
	BANK1
	BSF	SSPCON2,PEN			; STOP BIT
	BTFSC	SSPCON2,PEN			; KÉSZ?
	GOTO	$-1
	RETURN
;
; I2CWRITE: W KIÍRÁSA I2CBUS-RA ÉS I2CDATA-BA
;
I2CWRITE
	BANK0
	MOVWF	I2CDATA				; I2CDATA = W
	CALL	I2CWAIT				; VÁRAKOZÁS
	BANK0

	MOVFW	I2CDATA				; W = I2CDATA
	MOVWF	SSPBUF				; SSPBUF = W
	BANK1
	BTFSC	SSPSTAT, R_W			; ÍRÁS KÉSZ?
	GOTO	$-1
	CALL	I2CCHECKACK			; ACK ?
	RETURN
;
; I2CREAD: I2CBUS OLVASÁSA W-BE ÉS I2CDATA-BA
;
I2CREAD
	CALL	I2CWAIT
	BANK1
	BSF	SSPCON2, RCEN			; OLVASÁS
	BTFSC	SSPCON2, RCEN			; KÉSZ?
	GOTO	$-1
	CALL	I2CCHECKACK			; ACK ?
	BANK0
	MOVFW	SSPBUF				; W = SSPBUF
	MOVWF	I2CDATA				; I2CDATA = W
	RETURN
;
; I2CWAIT: VÁRAKOZÁS, AMÍG A BUS FOGLALT 
;
I2CWAIT
	BANK1
	BTFSC 	SSPSTAT,R_W 			; R/W SZABAD ? 
	GOTO 	$-1 				;
	MOVFW	SSPCON2				; W = SSPCON2 
	ANDLW	0x1F 				; TEST ACKEN,RCEN,PEN,RSEN,SEN 
	BTFSS	STATUS,Z 			; SZABAD ?
	GOTO	 $-4 				;
	RETURN 
;
; I2CCHECKACK: NYUGTA ELLENŐRZÉS, HIBA ESETÉN GOTO I2CHALT
;
I2CCHECKACK	
	BANK1
	BTFSC	SSPCON2, ACKSTAT		; ACK ?
	GOTO	I2CHALT				; LEÁLLÁS
	RETURN
;
; I2CHALT: PROGRAM LEÁLLÍTÁS I2CACK MIATT, HIBA AZ LCD-RE
;
I2CHALT:			
	CALL	LCDCLR
	CALL	LCDHOME0
	MOVLW	'E'
	CALL	LCDCHAR
	MOVLW	':'
	CALL	LCDCHAR
	MOVLW	'A'
	CALL	LCDCHAR
	MOVLW	'C'
	CALL	LCDCHAR
	MOVLW	'K'
	CALL	LCDCHAR
	MOVLW	' '
	CALL	LCDCHAR
	MOVLW	'H'
	CALL	LCDCHAR
	MOVLW	'A'
	CALL	LCDCHAR
	MOVLW	'L'
	CALL	LCDCHAR
	MOVLW	'T'
	CALL	LCDCHAR
	GOTO	$
	RETURN

;-------------------------------------------------------------------
; LCD RUTINOK
;	
; USES: TEMPW
;
; LCDCHAR: 	A W-BEN LEVŐ ADATOT AZ LCD AKTUÁLIS POZÍCIÓJÁBA ÍRJA
; LCDCMD:	A W-BEN LEVŐ UTASÍTÁSA KÜLDÉSE AZ LCD-NEK
; LCDWAIT:	VÁRAKKOZÁS AMÍG AZ LCD FOGLALT
; LCDINIT:	LCD BEÁLLÍTÁS 8BIT, 2SOR, 5×8DOTS, INCREMENT, DISPLAY SHIFT OFF,
;		LCDCLR, LCDHOME0, LCDCRSON
; LCDCLR:	KIJELZŐ TÖLÉSE
; LCDHOME0: 	CURSOR LINE0 HOME
; LCDHOME1: 	CURSOR LINE1 HOME
; LCDCRSON: 	DISPLAY ON, CURSOR ON, BLINK ON, CURSOR RIGHT SHIFT
; LCDCRSOFF: 	DISPLAY ON, CURSOR OFF, BLINK OFF
;-------------------------------------------------------------------
#define		LCDBUSTRIS	TRISB		; ADATBUSZ TRIS
#define		LCDCTRLTRIS	TRISC		; VEZÉRLŐ TRIS
#define		LCDBUS	 	PORTB		; AZ LCD ARATBUSZA
#define		LCDCTRL		PORTC		; AZ LCD VEZÉRLŐ VONALAI 
#define		RS		0		; PARANCS/ADAT VONAL 
#define		RW		1		; READ/WRITE VONAL
#define		EN		2		; ENGEDÉLYEZŐVONAL
#define 	LINE0		0x00		; LCD 1 SOR CÍME
#define		LINE1		0x40		; LCD 2 SOR CÍME
;
; LCDCHAR: A W-BEN LEVŐ ADATOT AZ LCD AKTUÁLIS POZÍCIÓJÁBA ÍRJA
;
LCDCHAR:
	MOVWF	TEMPW				; TEMPW = W
	CALL	LCDWAIT				; VÁRAKOZÁS AZ LCD-re
	MOVFW	TEMPW				; W = TEMPW
	MOVWF	LCDBUS				; LCDBUS = W
	BSF	LCDCTRL, RS			; RS = 1 (PARANCS/ADAT)
	BCF	LCDCTRL, RW			; RW = 0 (ÍRÁS/OLVASÁS)
	BSF	LCDCTRL, EN			; EN = 1 (ADÁS KEZD)
	NOP		
	BCF	LCDCTRL, EN			; EN = 0 (ADÁS VÉGE)
	RETURN
; 
; LCDCMD: A W-BEN LEVŐ UTASÍTÁS KÜLDÉSE AZ LCD-NEK
;
LCDCMD:	
	MOVWF	TEMPW				; TEMPW = W
	CALL	LCDWAIT				; VÁRAKOZÁS AZ LCD-re
	MOVFW	TEMPW				; W = TEMPW
	MOVWF	LCDBUS				; LCDBUS = W
	BCF	LCDCTRL, RS			; RS = 0 (PARANCS/ADAT)
	BCF	LCDCTRL, RW			; RW = 0 (ÍRÁS/OLVASÁS)
	BSF	LCDCTRL, EN			; EN = 1 (ADÁS KEZD)
	NOP					;
	BCF	LCDCTRL, EN			; EN = 0 (ADÁS VÉGE)
	RETURN
;
; LCDWAIT: VÁRAKKOZÁS AMÍG AZ LCD FOGLALT
;
LCDWAIT:
	BANK1
	MOVLW	0xFF				; LCDBUS OLVASÁSRA
	MOVWF	LCDBUSTRIS			; .
	BANK0
	BCF	LCDCTRL, RS	    		; RS = 0 (PARANCS/ADAT)
	BSF	LCDCTRL, RW			; RW = 1 (ÍRÁS/OLVASÁS)
	BSF	LCDCTRL, EN			; EN = 1 (ADÁS KEZD)	
	MOVFW	LCDBUS				; W = BUSYFLAG ÉS ADDRESS
	BCF	LCDCTRL, EN			; EN = 0 (ADÁS VÉGE)
	ANDLW	0x80		                ; BUSYFLAG == 1 AKKOR VISSZA 
	BTFSS	STATUS, Z			; .
	GOTO	LCDWAIT				; .	
	BCF	LCDCTRL, RW			; RW = 0 (ÍRÁS/OLVASÁS)
	BANK1        					; 
	CLRF	LCDBUSTRIS		 	; LCDBUS ÍRÁSRA
	BANK0					
	RETURN
;
; LCDINIT: LCD BEÁLLÍTÁS
;
LCDINIT:
	CALL	DELAYLCD
	BANK1
	CLRF	LCDBUSTRIS			; LCDBUS KIMENET
	BCF	LCDCTRL, RS
	BCF	LCDCTRL, RW
	BCF	LCDCTRL, EN
	BANK0
	CLRF	LCDBUS				; LCDBUS = 0
	BCF	LCDCTRL, RS			; LCDCTRL = 0
	BCF	LCDCTRL, RW
	BCF	LCDCTRL, EN
	MOVLW	B'00111000'			; 8-BIT, 2-SOR, 5×8 DOTS 
	CALL	LCDCMD				; FUNCTION SET
	MOVLW	B'00001000'			; DISPLAY OFF
	CALL	LCDCMD				; DISPLAY CONTROL
	MOVLW	B'00000110'			; INCREMENT, DISPLAY SHIFT OFF
	CALL	LCDCMD				; ENTRY MODE SET
	CALL	LCDCLR				; DISPLAY CLEAR
	CALL	LCDHOME0			; HOME
	CALL	LCDCRSON			; DISPLAY ON, CURSOR ON, BLINK ON
;
; LCDCLR: KIJELZŐ TÖLÉSE
;
LCDCLR:	
	MOVLW	B'00000001'
	CALL	LCDCMD
	RETURN
;
; LCDHOME0: CURSOR LINE0 HOME
;
LCDHOME0:	
	MOVLW	B'00000010'
	CALL	LCDCMD
	RETURN
;
; LCDHOME1: CURSOR LINE1 HOME
;
LCDHOME1:
	MOVLW	LINE1
	IORLW	0x80
	CALL		LCDCMD
	RETURN
;
; LCDCRSON: DISPLAY ON, CURSOR ON, BLINK ON, CURSOR RIGHT SHIFT
;
LCDCRSON:
	MOVLW	B'00001111'			; DISPLAY ON, CURSOR OFF
	CALL	LCDCMD				; DISPLAY CONTROL
	MOVLW	B'00011100'			; CURSOR SHIFT, SHIFT RIGHT
	CALL	LCDCMD
	RETURN
;
; LCDCRSOFF: DISPLAY ON, CURSOR OFF, BLINK OFF
;
LCDCRSOFF:
	MOVLW	B'00001100'			; DISPLAYON, CURSOROFF, BLINKOFF
	CALL	LCDCMD				; DISPLAY CONTROL
	RETURN
;
; DELAYLCD: SZÜNET AMÍG AZ LCD 'FELÁLL'
;
DELAYLCD:
	BANK0
	CLRF	LO
	CLRF	HI
	DECFSZ	LO
	GOTO	$-1
	DECFSZ	HI
	GOTO	$-3
	RETURN                         

;-------------------------------------------------------------------
;
; MATH
;
;-------------------------------------------------------------------
SAC1	EQU	0x40
SAC2	EQU	0x41
SAC3	EQU	0x42
SAC4	EQU	0x43
ARG1	EQU	0x44
ARG2	EQU	0x45
ARG3	EQU	0x46
ARG4	EQU	0x47
REM1	EQU	0x48
REM2	EQU	0x49
REM3	EQU	0x4A
REM4	EQU	0x4B
LOOP	EQU	0x4C
;
; INTTOSTR: EGÉSZ-STRING KONVERZIÓ (!CSAK KÉT DECIMÁLIS DIGITRE)
;  
INTTOSTR:
	BANK0
	BTFSS	INTLO,7				; ELŐJEL NEGATÍV?
	GOTO	POSITIV
	COMF	INTLO, f			;INTLO = NOT(INTLO)
	INCF	INTLO, f			; INTLO = INTLO+1
	MOVLW	'-'
	CALL	LCDCHAR
POSITIV:
	CALL	FLUSH32
	MOVFW	INTLO				; SAC = INTLO:INTHI
	MOVWF	SAC1				;
	MOVFW	INTHI				;
	MOVFW	SAC2
	MOVLW	LOW .10				; ARG = 10
	MOVWF	ARG1				;
	MOVLW	HIGH .10			;
	MOVWF	ARG2				;
	CALL	DIV16				; DIV16
	MOVFW	SAC1				; 
	ADDLW	.48				; ASCII(W)
	CALL	LCDCHAR
	CALL	MUL16				; SAC= SAC-((SAC DIV 10) MUL 10)
	MOVFW	SAC1				;
	MOVWF	ARG1				;
	MOVFW	SAC2				;
	MOVWF	ARG2				;
	MOVFW	INTLO				;

	MOVWF	SAC1				;
	MOVFW	INTHI				;
	MOVWF	SAC2				;
	CALL	SUB16				;	
	MOVFW	SAC1				;
	ADDLW	.48				; ASCII(W)
	CALL	LCDCHAR
	RETURN
;
; SUB16: 16 BITES EGÉSZ KIVONÁS
; SAC = SAC - ARG
SUB16:
	MOVFW	ARG1
	SUBWF	SAC1,F
	MOVFW	ARG2
	BTFSS	STATUS,C
	INCFSZ	ARG2,W
	SUBWF	SAC2,F
	RETURN
;
; MUL16: 16 BITES EGÉSZ SZORZÁS
; SAC = SAC * ARG
MUL16:
	CLRF   REM4
	CLRF   REM3
	CLRF   REM2
	MOVLW  0x80
	MOVWF  REM1
	RRF    SAC2,F
	RRF    SAC1,F
	BTFSS  STATUS,C
	GOTO   $+.10
	MOVF   ARG1,W
	ADDWF  REM2,F
	MOVF   ARG2,W
	BTFSC  STATUS,C
	INCFSZ ARG2,W
	ADDWF  REM3,F
	BTFSC  STATUS,C
	INCF   REM4,F
	BCF    STATUS,C
	BTFSS  SAC1,7
	GOTO   $+7
	MOVF   ARG1,W
	ADDWF  REM3,F
	MOVF   ARG2,W
	BTFSC  STATUS,C
	INCFSZ ARG2,W
	ADDWF  REM4,F
	RRF    REM4,F
	RRF    REM3,F
	RRF    REM2,F
	RRF    REM1,F
	BTFSS  STATUS,C
	GOTO   $-.26
	MOVFW	REM1
	MOVWF	SAC1
	MOVFW	REM2
	MOVWF	SAC2
	RETURN
;
; 16 BITES EGÉSZ OSZTÁS
; SAC1:SAC2 = SAC1:SAC2 DIV ARG1:ARG2
;
DIV16
	CLRF   REM1
	CLRF   REM2
	MOVLW  0x10
	MOVWF  LOOP
	RLF    SAC2,W
	RLF    REM1,F
	RLF    REM2,F
	MOVF   ARG1,W
	SUBWF  REM1,F
	MOVF   ARG2,W
	BTFSS  STATUS,C
	INCFSZ ARG2,W
	SUBWF  REM2,F
	BTFSC  STATUS,C
	GOTO   $+0x08
	MOVF   ARG1,W
	ADDWF  REM1,F
	MOVF   ARG2,W
	BTFSC  STATUS,C
	INCFSZ ARG2,W
	ADDWF  REM2,F
	BCF    STATUS,C
	RLF    SAC1,F
	RLF    SAC2,F
	DECFSZ LOOP,F
	GOTO   $-0x15
	RETURN
;
; FLUSH32: MATH REIGSZETEREK TÖRLÉSE
;
FLUSH32
	CLRF	SAC1
	CLRF	SAC2
	CLRF	SAC3
	CLRF	SAC4
	CLRF	ARG1
	CLRF	ARG2
	CLRF	ARG3
	CLRF	ARG4
	RETURN


END