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

📄 ds18b20_web.asm

📁 这是有关单总线数字温度芯片DS18B20的keilC和ASM汇编的混合编程
💻 ASM
字号:
	;用DP-51+ 来读DS18B20单总线温度传感器
	
	;进行温度显示,显示范围00到99度,显示精度为1度
	;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位, 16(FFFFH)x0.00625=1度
	;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度,非常简洁无需乘于0.0625系数
	;DS18B20复位初始化子程序,P0和P2已被系统占用,而P1用来驱动LED和数码管,
	;所以用P3口作普通I/O口,P3.2 是输入和输出数据线



	;单片机内存分配申明!	
	TEMPER_L EQU  29H	;用于保存读出温度的低8位, 
				;29H在内部RAM的20H~2FH里(位寻址区)
	TEMPER_H EQU  28H	;用于保存读出温度的高8位
				;28H在内部RAM位寻址区
	FLAG1 	 EQU  38H	;是否检测到DS18B20标志位,是可寻址位

	a_bit    EQU  20h	;数码管个位数存放内存位置
	b_bit    EQU  21h	;数码管十位数存放内存位置
	SDA	 EQU  P1.0
	CLK	 EQU  P1.1

	//ORG 0000H
	ORG 4000H
	LJMP MAIN
		
MAIN:
	LCALL GET_TEMPER   	;调用读温度子程序
	MOV A, 29H		;温度的低8位
	MOV C, 40H		;将28H中的最低位移入C, 40H是位寻址(RAM单元28H)
	RRC A
	MOV C, 41H
	RRC A
	MOV C, 42H
	RRC A
	MOV C, 43H
	RRC A
	MOV 29H, A		;将28H中的低4位移入29H中的高4位,这样获得一个新字节,29H内存所要温度数据
	
	LCALL DISPLAY		;调用数码管显示子程序

	;CPL P1.0		;直接寻址位取反	
	AJMP MAIN

INIT_1820:
	SETB P3.2		;P3.2 是数据线, 
	NOP
	CLR P3.2

	;主机发出延时537微秒的复位低脉冲
	MOV R1, #3
TSR1:
	MOV R0, #107
	DJNZ R0, $
	DJNZ R1, TSR1		;双重循环
	SETB P3.2		;然后拉高数据线,
				;释放总线,读口线前先置"1"
				;过程其实是"读--改--写"
	NOP			;空操作,消耗一个机器周期
	NOP
	NOP
	MOV R0, #25H

TSR2:
	JNB P3.2, TSR3		;等待DS18B20回应, "低"表示DS18B20存在
				;读口线并判断,"低"转移
	DJNZ R0, TSR2		;R0不为零,有时间限制的继续查寻P3.2,否则死循环
				;25x2us=50us 最大时间限制
	LJMP TSR4		;DS18B20不存在,转移

TSR3:
	SETB FLAG1		;置标志位,表示DS1820存在, 
				;是位寻址38H, 指令是位操作指令
	CLR P1.7		;检查到DS18B20就蜂鸣BUZZER
				;see schematic, Q6 bipolar
	
	LJMP TSR5

	TSR4:
	CLR FLAG1		;清标志位,表示DS1820不存在
	;CLR P1.1		;
	LJMP TSR7

TSR5:
	MOV R0, #117

TSR6:
	DJNZ R0, $		;时序要求延时一段时间

TSR7:
	SETB P3.2		;然后拉高数据线
	RET			;结束复位初始化,返回
	
		
	; 读出转换后的温度值子程序
GET_TEMPER:
	SETB P3.2		;
	LCALL INIT_1820		;先复位DS18B20
	JB FLAG1, TSS2		;判断DS1820是否存在
	;CLR P1.2		;
	RET 			;DS18B20不存在则返回

TSS2:
	;CLR P1.3		;DS18B20已经被检测到
				;
	; 发出"温度转换"命令
	MOV A, #0CCH	 	;"跳过ROM匹配"命令
	LCALL  WRITE_1820	;发出命令
	MOV A, #44H		;"起动转换"命令
	LCALL  WRITE_1820	;发出命令
	LCALL  DISPLAY	        ;这里通过调用显示子程序实现延时一段时间,
				;等待AD转换结束,12位的话750微秒
				;时序见 write slot
	LCALL INIT_1820		;准备读温度前先复位, 是否会abort上句的温度转换命令#44H??, 
				;不会, 每一次读写之前都要对DS18B20进行复位
				;发出"读温度"命令
	MOV A, #0CCH		;"跳过ROM匹配"命令
	LCALL WRITE_1820	;发出命令
	MOV A, #0BEH		;"读温度"命令
	LCALL WRITE_1820	;发出命令
	LCALL READ_1820		;读出温度数据
	;CLR P1.4		;
	RET			;结束读出转换后的温度值子程序, 返回

	; /写DS18B20的子程序(有具体的时序要求)
WRITE_1820:		
	MOV R2, #8		;一共8位数据
	CLR C
	WR1:
	CLR P3.2		;clear p3.2, 
				;P3.2口从逻辑高到逻辑低时,写时间隙开始
				;DS18B20将在15us~60us窗口内采样P3.2口线
	MOV R3, #5
	DJNZ R3, $		;2us, $ 代表PC当前值, 可使程序原地踏步等待中断或程序结束
				;total 2x5=10us延时
	
	RRC A			;A中有命令字, 一位一位传递给C
	MOV P3.2, C		;一位一位通过P3.2发
	MOV R3, #21
	DJNZ R3, $		;2us, total 21x2=42us延时,		
				;write slot最少持续60us
	SETB P3.2		;拉高数据线, 为"逻辑高到逻辑低"作准备
	NOP			;延时 2uS
	DJNZ R2, WR1		;循环, 直至命令字8位发完
	SETB P3.2
	RET			;结束写子程序, 返回
	
	; 读DS18B20的子程序,从DS18B20中读出两个字节的温度数据 
READ_1820:
	MOV R4, #2		;将温度高位和低位从DS18B20中读出
	MOV R1, #29H		;低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00:
	MOV R2, #8		;数据一共有8位
RE01:
 	CLR C
	SETB P3.2		;拉高数据线, 为"逻辑高到逻辑低"作准备
	NOP
	NOP
	CLR P3.2		;P3.2口从逻辑高到逻辑低时,读时间隙开始
				;从DS18B20输出的数据在读时间隙的下降沿出现后15us内有效
	NOP			;1us
	NOP			;1us
	NOP			;1us
	SETB P3.2		;1us,释放总线,读口线前先置"1, 停止驱动P3.2口低,而置为高电平
				;read slot, 
	MOV R3, #9		;1us
RE10:
	DJNZ R3, RE10		;2us, total:9x2=18us
	
	MOV C, P3.2		;1us, P3.2传递给C,
	
	MOV R3, #23
RE20:
	DJNZ R3, RE20		;2us, total 23x2=46us, write slot最少持续60us
	
	RRC A			;C位传递给A
	DJNZ R2, RE01		;循环,直至8位传递完
	MOV @R1, A		;A->29H
	DEC R1			;28H
	DJNZ R4, RE00		;开始传递 A->28H 的过程
	RET			;结束读子程序, 返回

DISPLAY:
	MOV R2,#0BFH		;10111111,P1.6->LED1,P1.5->LED2,P1.4->LED3,P1.3->LED4
	;MOV R2,#0EFH			;11101111,P1.4
	MOV A,29H
	MOV B,#10
	DIV AB
	MOV b_bit, A		;十位数
	MOV a_bit, B		;个位数
	MOV A, b_bit		;先显示十位数->LED1,
	ACALL TAB
	ACALL TXDBYTE
	
	MOV A, R2		;LED位选, 10111111,P1.6
	MOV A, #0BFH
	MOV P1, A
	ACALL DELAY
	MOV P1,#0FFH
	
	MOV A, a_bit		;显示个位数->LED2,
	ACALL TAB
	ACALL TXDBYTE
	MOV A,#0DFH		;LED位选, 11011111,P1.5
	MOV P1,A
	ACALL DELAY
	MOV P1,#0FFH
	RET

TXDBYTE:
	MOV R3, #08H
TXDUP:
	RLC A
	MOV SDA, C
	CLR CLK
	SETB CLK
	DJNZ R3,TXDUP
	RET


DELAY:
	MOV R7,#50H
DELAY0:
	MOV R6,#10H
DELAY1:
	DJNZ R6, DELAY1
	DJNZ R7, DELAY0

TAB:
	;INC A
	;MOVC A,@A+PC

	;或者
	MOV DPTR, #numtab
	MOVC A,@A+DPTR

	RET
numtab:
	DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,80H,090H

	END






⌨️ 快捷键说明

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