;这是关于ds18b20的读写程序,数据脚p2.2,晶振12mhz ;温度传感器18b20汇编程序,采用器件默认的12位转化,最大转化时间750微秒 ;可以将检测到的温度直接显示到at89c51开发实验板的两个数码管上 ;显示温度00到99度,很准确哦~~无需校正! org 0000h ;单片机内存分配申明! temper_l equ 29h;用于保存读出温度的低8位 temper_h equ 28h;用于保存读出温度的高8位 flag1 equ 38h;是否检测到ds18b20标志位 a_bit equ 20h ;数码管个位数存放内存位置 b_bit equ 21h ;数码管十位数存放内存位置 temp_th equmain: lcall get_temper;调用读温度子程序 ,显示范围00到99度,显示精度为1度 ;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29h的低4位 ;将28h中的低4位移入29h中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度 mov a,29h mov c,40h;将28h中的最低位移入c rrc a mov c,41h rrc a mov c,42h rrc a mov c,43h rrc a mov 29h,a lcall display ;调用数码管显示子程序 cpl p1.0 ajmp main ; 这是ds18b20复位初始化子程序 init_1820: setb p3.5 nop clr p3.5 ;主机发出延时537微秒的复位低脉冲 mov r1,#3 tsr1:mov r0,#107 djnz r0,$ djnz r1,tsr1 setb p3.5 ;然后拉高数据线 nop nop nop mov r0,#25h tsr2: jnb p3.5,tsr3 ;等待ds18b20回应 djnz r0,tsr2 ljmp tsr4 ; 延时 tsr3: setb flag1 ; 置标志位,表示ds1820存在 clr p1.7 ;检查到ds18b20就点亮p1.7led ljmp tsr5 tsr4: clr flag1 ; 清标志位,表示ds1820不存在 clr p1.1 ;点亮p1。1脚led表示温度传感器通信失败 ljmp tsr7 tsr5: mov r0,#117 tsr6: djnz r0,tsr6 ; 时序要求延时一段时间 tsr7: setb p3.5 ret ; 读出转换后的温度值 get_temper: setb p3.5 lcall init_1820 ;先复位ds18b20 jb flag1,tss2 clr p1.2 ret ; 判断ds1820是否存在?若ds18b20不存在则返回 tss2: clr p1.3 ;ds18b20已经被检测到!!!!!!!!!!!!!!!!!! mov a,#0cch lcall write_1820 mov a,#44h ;发出温度转换命令 lcall write_1820 ;这里通过调用显示子程序实现延时一段时间,等待ad转换结束,12位的话750微秒 lcall display lcall init_1820 ;准备读温度前先复位 mov a,#0cch ; 跳过rom匹配 lcall write_1820 mov a,#0beh ; 发出读温度命令 lcall write_1820 lcall read_18200; 将读出的温度数据保存到35h/36h clr p1.4 ret ;写ds18b20的子程序(有具体的时序要求) write_1820: mov r2,#8;一共8位数据 clr c wr1: clr p3.5 mov r3,#6 djnz r3,$ rrc a mov p3.5,c mov r3,#23 djnz r3,$ setb p3.5 nop djnz r2,wr1 setb p3.5 ret ; 读ds18b20的程序,从ds18b20中读出两个字节的温度数据 read_18200: mov r4,#2 ; 将温度高位和低位从ds18b20中读出 mov r1,#29h ; 低位存入29h(temper_l),高位存入28h(temper_h) re00: mov r2,#8;数据一共有8位 re01: clr c setb p3.5 nop nop clr p3.5 nop nop nop setb p3.5 mov r3,#9 re10: djnz r3,re10 mov c,p3.5 mov r3,#23 re20: djnz r3,re20 rrc a djnz r2,re01 mov @r1,a dec r1 djnz r4,re00 ret ;显示子程序 display: mov a,29h;将29h中的十六进制数转换成10进制 mov b,#10 ;10进制/10=10进制 div ab mov b_bit,a ;十位在a mov a_bit,b ;个位在b mov dptr,#numtab ;指定查表启始地址 mov r0,#4 dpl1: mov r1,#250 ;显示1000次 dplop: mov a,a_bit ;取个位数 movc a,@a+dptr ;查个位数的7段代码 mov p1,a ;送出个位的7段代码 setb p2.0 ;开个位显示 acall d1ms ;显示1ms clr p2.0 mov a,b_bit ;取十位数 movc a,@a+dptr ;查十位数的7段代码 mov p1,a ;送出十位的7段代码 setb p2.1 ;开十位显示 acall d1ms ;显示1ms clr p2.1 djnz r1,dplop ;100次没完循环 djnz r0,dpl1 ;4个100次没完循环 ret ;1ms延时(按12mhz算) d1ms: mov r7,#80 djnz r7,$ ret numtab: ;数码管共阳极0~9代码 db 0c0h,0f9h,0a4h,0b0h,99h, 92h,82h,0f8h,80h,90hend 感觉对你有用就赏分吧~