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

📄 ds18b20.asm

📁 基于8051编写的温度计程序 采用汇编语言 在LED上显示温度
💻 ASM
字号:
N	EQU	8		;读出ROM的位数
DQ	EQU	P3.2		;单总线的数据线
TH	EQU	40		;最高极限温度
TL	EQU	10		;最低极限温度
SROMC	EQU	0F0H		;搜索ROM命令
MROMC	EQU	55H		;匹配ROM命令
LROMC	EQU	0CCH		;跳过读ROM命令
RROMC	EQU	33H		;读ROM命令
CTC	EQU	44H		;转换温度命令
WREGC	EQU	4EH		;写暂存器命令
RREGC	EQU	0BEH		;读暂存器命令
CONFIG	EQU	1FH		;配置寄存器的值,9位温度值

	DSEG	AT 30H
DAT:	DS	1		;温度值存储单元
POINT:	DS	1		;小数点后温度值的存储单元
ROMA:	DS	8		;器件A的ROM存储单元
BUF:	DS	9		;暂存器中数据存储单元
BUFT:	DS	4		;数码管动态显示的4个数据缓冲单元
BTH:	DS	1		;显示ROM中某一字节高四位
BTL:	DS	1		;显示ROM中某一字节低四位

	CSEG	AT 0000H
	LJMP 	MAIN

	ORG 	0100H
MAIN:	mov p0,#0
MOV 	SP,#70H
	MOV	PSW,#00H
	LCALL	Initial
	MOV	A,#LROMC	;写跳过ROM命令
	LCALL	W8BIT
	MOV	A,#WREGC	;写暂存器命令,可写入TH,TL,Configuration
	LCALL	W8BIT
	MOV	A,#TH		;写18B20的TH寄存器
	LCALL	W8BIT
	MOV	A,#TL		;写18B20的TL寄存器
	LCALL	W8BIT
	MOV	A,#CONFIG	;写18B20的配置寄存器,9位温度值
	LCALL	W8BIT

RETN:	LCALL	Initial		;18B20初始化
	MOV	A,#LROMC	;写跳过ROM命令
	LCALL	W8BIT
	MOV	A,#CTC		;写转换温度命令
	LCALL	W8BIT
BUSY:	LCALL	Disply		;显示温度
	CLR	DQ		;读18B20的忙位
	NOP
	SETB	DQ
	NOP
	MOV	C,DQ
	LCALL	DLY70		;延时70微秒
	JNC	BUSY		;如果18B20忙,转BUSY
	LCALL	Initial		;初始化
	MOV	A,#LROMC	;写跳过ROM命令
	LCALL	W8BIT
	MOV	A,#RREGC	;写读18B20暂存器命令
	LCALL	W8BIT
	MOV	R3,#2		;设置计数器R3=2,从18B20读2个字节的温度值
	MOV	R1,#BUF		;置R1温度值缓冲区
RER:	LCALL	R8BIT		;读温度值
	MOV	@R1,A		;将温度值存入缓冲区
	INC	R1		;温度值缓冲区地址加1
	DJNZ	R3,RER		;如2个字节温度值没读完,转RER
	LCALL	STORE		;温度转换并存储子程序
	LCALL	Disply		;温度显示子程序,只所以调用2次该子程序
				;是为了增强数码管的亮度
	SJMP	RETN


	;18B20初始化子程序,使用R7
Initial:CLR	DQ		;数据线为低700微秒
	LCALL	DLY700
	SETB	DQ		;置数据线为高,以便接收18B20信号
I1:	MOV	C,DQ		;等待数据线为低
	JC	I1
	LCALL	DLY700		;延时700微秒
	RET

	;向18B20写8位子程序,被写的数在ACC中
	;使用R2、R7
W8BIT:	MOV	R2,#8		;设置计数器R2为8
W1:	CLR	DQ		;使数据线为低
	RRC	A		;右移将被写位移如进位C
	JNC	W2		;被写位为0,转W2
	SETB	DQ		;被写位为1,使数据线为高
W2:	LCALL	DLY70		;延时70微秒
	SETB	DQ		;使数据线为高
	DJNZ	R2,W1		;如果8位数据没写完,转W1
	RET

	;读8位子程序,读的数在ACC中
	;使用R2、R7
R8BIT:	MOV	R2,#8		;设置计数器R2为8
RR1:	CLR	DQ		;使数据线为低,启动读过程
	NOP			;等待4微秒
	SETB	DQ		;使数据线为高,以便从18B20读数据
	NOP			;等待4微秒
	MOV	C,DQ		;将数据读入进位C
	RRC	A		;通过右移将进位C送入ACC
	LCALL	DLY70		;延时70微秒
	DJNZ	R2,RR1		;如果8位数据没读完,转RR1
	RET


	;温度值存储子程序,使用R0
STORE:	MOV	R0,#BUF		;将温度缓冲区首址送R0
	MOV	A,@R0
	MOV	B,A
	ANL	A,#08H		;保留小数位
	MOV	POINT,A
	MOV	A,B
	ANL	A,#0F0H		;保留高4位
	MOV	B,A
	INC	R0
	MOV	A,@R0
	ANL	A,#0FH		;保留低4位
	ORL	A,B		;组成1个字节
	SWAP	A
	MOV	R0,#BUFT
	JB	ACC.7,NEG	;如果温度为负,转NEG
	MOV	DAT,A		;温度为正值,直接存到DAT里
	MOV	A,#00H		;正号显示
	MOV	@R0,A
	JMP	NST
NEG:	CPL	A		;将相应的负值转换为其绝对值
	MOV	B,A
	MOV	A,POINT
	CPL	A
	CLR	ACC.4
	ADD	A,#08H
	MOV	C,ACC.4
	XCH	A,B
	ADDC	A,#0
	MOV	DAT,A		;把负温度值1-8位变正存储
	MOV	POINT,B		;把负温度值第9位变正存储
	MOV	A,#40H		;负号显示
	MOV	@R0,A
NST:	INC	R0
	MOV	A,DAT		;取温度值
	MOV	B,#10		;十位数在ACC中,个位数在B中
	DIV	AB
	MOV	DPTR,#TAB	;将十位数转换为数码管字形码值存入BUFT中
	MOVC	A,@A+DPTR
	MOV	@R0,A
	INC	R0		;字形码缓冲区地址加1
	MOV	A,B
	MOVC	A,@A+DPTR	;将个位数字形码连同小数点存入BUFT中
	SETB	ACC.7
	MOV	@R0,A
	INC	R0		;字形码缓冲区地址加1
	MOV	A,POINT		;取小数点后的值字形码存入缓冲区BUFT中
	JB	ACC.3,FLOAT
	MOV	A,#3FH
	MOV	@R0,A
	JMP	E
FLOAT:	MOV	A,#6DH
	MOV	@R0,A
E:	RET

	;显示温度子程序,使用了DPTR、R0、R5。
	;BUFT中存放的是温度值的字形码
Disply:	MOV	R0,#BUFT
        MOV     A,@R0
        MOV	P1,A	;送出正负位的7段代码
	SETB	P3.4	;开个位显示
        CALL    DISP
	CLR	P3.4

        MOV     A,@R0
        MOV	P1,A	;送出十位的7段代码
	SETB	P3.5	;开十位显示
        CALL    DISP
	CLR	P3.5

	MOV     A,@R0
        MOV	P1,A	;送出个位的7段代码
	SETB	P3.6	;开个位显示
        CALL    DISP
	CLR	P3.6

        MOV     A,@R0
        MOV	P1,A	;送出小数位的7段代码
	SETB	P3.7	;开小数位显示
        CALL    DISP
	CLR	P3.7
	RET

	;显示一个数字子程序
DISP:   MOV	R5,#250		;等待600微秒
	DJNZ	R5,$

        INC	R0		;BUFT字形码缓冲区地址加1,准备显示下一个数字
	RET

DLY700:	MOV	R7,#157		;延时700微秒子程序,使用R7
	DJNZ	R7,$
DLY70:	MOV	R7,#17		;延时70微秒子程序,使用R7
	DJNZ	R7,$
	RET

	;延时1分钟子程序,使用R5、R6、R7
DLY1M:	MOV	R5,#240
LOOP1:	MOV	R6,#250
LOOP2:	MOV	R7,#250
	DJNZ	R7,$
	DJNZ	R6,LOOP2
	DJNZ	R5,LOOP1
	RET


TAB:    DB      0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
        ;DB	3FH,06H,5BH,4FH,66H,6DH,7DH,07H		;a~f字形码
	DB	7FH,6FH,77H,7CH,58H,5EH,79H,71H


	END

⌨️ 快捷键说明

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