;这是关于DS18B20的读写程序,数据脚P3.2,晶振12MHz ;温度传感器18B20汇编程序,采用器件默认的12位转化,最大转化时间750微秒 ;可以将检测到的温度直接显示到AT89C2051的p1口输数码管段码到两位一体数码管上 ;显示温度00到99度,很准确哦~~无需校正! ;p3.1驱动加热管装置,让温度保温在0-99度内 ;p3.0保温指示灯,p3.4是温度设定按键加1度;p3.5是温度设定按键减1度,p3.7是数码管高位位码,p3.3是数码管低位位码 ;程序16进制的温度值放在29h里,我用可调节0度到99度的16进制值(#08H/#0EH)与之比较 ;1至40度的16进制为:01H 02H 03H 04H 05H 06H 07H 08H 09H 0AH 1-10度 ; 0BH 0CH 0DH 0EH 0FH 10H 11H 12H 13H 14H 11-20度 ; 15H 16H 17H 18H 19H 1AH 1BH 1CH 1DH 1EH 21-30度 ; 1FH 2OH 21H 22H 23H 24H 25H 26H 27H 28H 31-40度 ; 29H 2AH 2BH 2CH 2DH 2EH 2FH 30H 31H 32H 41-50度 ; 33H 34H 35H 36H 37H 38H 39H 3AH 3BH 3CH 51-60度 ; 3CH 3DH 3EH 3FH 40H 41H 42H 43H 44H 45H 61-70度 ; 46H 47H 48H 49H 4AH 4BH 4CH 4DH 4EH 4FH 71-80度 ; 51H 52H 53H 54H 55H 56H 57H 58H 59H 5AH 81-90度 ; 5BH 5CH 5DH 5EH 5FH 60H 61H 62H 63H 64H 91-100度 ;========================================================================================= ;单片机内存分配申明! TEMPER_L EQU 29H ;用于保存读出温度的低8位 TEMPER_H EQU 28H ;用于保存读出温度的高8位(特别是可位寻址,程序中用的着哦) TIAO_H EQU 27H ;用于保存设定温度的数据(最低温度的设定,高温度为低温度加2度) FLAG1 EQU 38H ;是否检测到DS18B20标志位 a_bit equ 20h ;数码管个位数存放内存位置 b_bit equ 21h ;数码管十位数存放内存位置 SL EQU 22H ;设定温度时数码管个位数存放内存位置 SH EQU 23H ;设定温度时数码管十位数存放内存位置 sdwd equ 24h ;设定温度压缩BCD码位 DS18B20 BIT P3.2 ;定义DS18B20的数据脚为P3.2端口 ORG 0000H MOV sdwd,#25H ;;;;设定初始温度37度,上电后内部设定温度 MAIN:LCALL INIT_1820 ;调用复位DS18B20子程序 MAIN1:LCALL GET_TEMPER ;调用读温度子程序 ;进行温度显示,这里我是用两位数码管来显示温度,显示范围00到99度,显示精度为1度 ;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位 ;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度 ;这个转化温度的方法可是我想出来的哦~~非常简洁无需乘于0.0625系数 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 ;调用数码管显示子程序 ;这里是后加的,做为控制在0-99度内恒温的程序!p3.1驱动加热管装置 setb p3.4 setb p3.5 jnb p3.4,DD1 ;按下后转加1程序 jnb p3.5,DD2 ;按下后转减1程序 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TT: CLR C ;比较转换值与设定值 MOV 26H,sdwd ;把低温度设定保存到26H单元后减2度,作为低度的数据 DEC 26H MOV A,29H CJNE A,26H,LOOP1 ;下限设定温度度,不相等跳LOOP1 SJMP HOTTING ;与下限值相等跳HOTTING,加热 LOOP1:JC HOTTING ;温度小于下限值跳HOTTING,加热 MOV A,29H ;温度大于下限值,与上限值比较 CLR C mov 27h,sdwd inc 27h CJNE A,27h,LOOP2 ;上限设定温度度,不相等跳LOOP2 SJMP STOPHOT ;相等跳STOPHOT,停止加热 LOOP2:JNC STOPHOT ;温度大于上限值跳STOPHOT,停止加热 SJMP KEEP ;温度小于上限且大于下限值跳KEEP,保温 HOTTING:CLR P3.1 ;小,加热器驱动 setb p3.0 ;关闭保温灯 KEEP:SJMP MAIN ;返回,保持原态,保温 STOPHOT:SETB P3.1 ;关闭加热器 clr p3.0 ;点亮保温灯 AJMP MAIN ;反回主程序 ;;;;;;;;;;;;;;;;;;;;;按键处理;;;;;;;;;;;; ;;;;;加限设定温度度;;;;;;;;;; DD1:LCALL displa ;调用数码管闪烁设定显示子程序 mov r5,#30 JNB P3.4,DD1 mov a,sdwd ;把设定温度送累加器判断 cjne a,#62h,ty1 ;比较设定温度是否到99度,不是则加 ajmp dh2 ty1: INC sdwd dh2:jnb p3.4,DD1 jnb p3.5,DD2 ;按下后转减1程序 LCALL displa ;调用数码管闪烁设定显示子程序 djnz r5,dh2 LJMP TT ;;;减限设定温度度;;;;;;;;;;;; DD2:LCALL displa ;调用数码管闪烁设定显示子程序 mov r5,#30 JNB P3.5,DD2 mov a,sdwd ;把设定温度送累加器判断 cjne a,#01h,ty ;比较设定温度是否到0度,不是则减 ajmp dh1 ty: DEC sdwd dh1:jnb p3.5,DD2 jnb p3.4,DD1 ;按下后转加1程序 LCALL displa ;调用数码管闪烁设定显示子程序 djnz r5,dh1 LJMP TT ;========================================================================================= ; DS18B20复位初始化程序 INIT_1820:SETB DS18B20 NOP CLR DS18B20 MOV R0,#06BH ;主机发出延时537微秒的复位低脉冲 MOV R1,#03H TSR1:DJNZ R0,TSR1 MOV R0,#6BH DJNZ R1,TSR1 SETB DS18B20 ;然后拉高数据线 NOP NOP NOP MOV R0,#25H TSR2:JNB DS18B20,TSR3 ;等待DS18B20回应 DJNZ R0,TSR2 LJMP TSR4 ;延时 TSR3:SETB FLAG1 ;置标志位,表示DS1820存在 LJMP TSR5 TSR4:CLR FLAG1 ;清标志位,表示DS1820不存在 LJMP TSR7 TSR5:MOV R0,#06BH TSR6:DJNZ R0,TSR6 ;时序要求延时一段时间 TSR7:SETB DS18B20 RET ;========================================================================================= ; 读出转换后的温度值 GET_TEMPER:SETB DS18B20 ;定时入口 LCALL INIT_1820 ;先复位DS18B20 JB FLAG1,TSS2 RET ;判断DS1820是否存在?若DS18B20不存在则返回 TSS2:MOV A,#0CCH ;跳过ROM匹配 LCALL WRITE_1820 MOV A,#44H ;发出温度转换命令 LCALL WRITE_1820 LCALL DISPLAY ;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒. LCALL INIT_1820 ;准备读温度前先复位 MOV A,#0CCH ;跳过ROM匹配 LCALL WRITE_1820 MOV A,#0BEH ;发出读温度命令 LCALL WRITE_1820 LCALL READ_18200 ;将读出的温度数据保存到35H/36H RET ;写DS18B20的子程序(有具体的时序要求) WRITE_1820:MOV R2,#8 ;一共8位数据 CLR C WR1:CLR DS18B20 MOV R3,#6 DJNZ R3,$ RRC A MOV DS18B20,C MOV R3,#23 DJNZ R3,$ SETB DS18B20 NOP DJNZ R2,WR1 SETB DS18B20 RET ; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据 READ_18200:MOV R4,#2 ;将温度高位和低位从DS18B20中读出 MOV R1,#29H ;低位存入29H(TEMPER_L),高位存入28H(TEMPER_H) RE00:MOV R2,#8 RE01:CLR C SETB DS18B20 NOP NOP CLR DS18B20 NOP NOP NOP SETB DS18B20 MOV R3,#09 RE10:DJNZ R3,RE10 MOV C,DS18B20 MOV R3,#23 RE20:DJNZ R3,RE20 RRC A DJNZ R2,RE01 MOV @R1,A DEC R1 DJNZ R4,RE00 RET[page] ;========================================================================================= ;;;;;;;;;;;;;;;显示子程序;;;;;;;;;;;;;;;;;; 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 r1,#250 ;显示250次 dplop:mov a,a_bit ;取个位数 MOVC A,@A+DPTR ;查个位数的7段代码 mov p1,a ;送出个位的7段代码 clr p3.3 ;开个位显示 acall d1ms ;显示1ms setb p3.3 mov a,b_bit ;取十位数 MOVC A,@A+DPTR ;查十位数的7段代码 mov p1,a ;送出十位的7段代码 clr p3.7 ;开十位显示 acall d1ms ;显示1ms setb p3.7 djnz r1,dplop ;250次没完循环 RET ;;;=============================================================== ;;;;;;;闪烁设定显示子程序===================== displa: MOV A,sdwd mov b,#10 ;10进制/10=10进制 div ab mov SL,a ;十位在a mov SH,b ;个位在b mov r1,#250 ;显示250次 dpl2: mov a,SL ;取设定温度个位数 mov dptr,#numtab ;指定查表启始地址 MOVC A,@A+DPTR ;查个位数的7段代码 mov p1,a ;送出个位的7段代码 clr p3.7 ;开个位显示 acall d1ms ;显示1ms setb p3.7 mov a,SH ;取设定温度十位数 MOVC A,@A+DPTR ;查十位数的7段代码 mov p1,a ;送出十位的7段代码 clr p3.3 ;开十位显示 acall d1ms ;显示1ms setb p3.3 djnz r1,dpl2 ;250次没完循环 acall D1s ;显示1ms RET ;;========================================================================================= ;1MS延时(按12MHZ算) D1MS:MOV R7,#80 DJNZ R7,$ RET ;;1S延时(按12MHZ算) D1s:MOV R7,#255 l1:nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop DJNZ R7,l1 RET ;========================================================================================= numtab: DB 0EEH;0 DB 048H;1 DB 0D6H;2 DB 0DCH;3 DB 078H;4 DB 0BCH;5 DB 0BEH;6 DB 0C8H;7 DB 0FEH;8 DB 0FCH;9 END
上一篇:STC51单片机SPI接口单主单从模式通信-汇编语言
下一篇:89s51和89s52不同晶振之间通信实验
推荐阅读最新更新时间:2024-03-16 14:04