|
数字式温度计实验(18B20、ZLG7290)
- ; **************主程序(MAIN.ASM)***********************
- ; 向DS18B20发出温度转换信号,延时等待,读出温度;将温度值由十六进制转换成十进制数,使用8155控制LED显示温度
- TEMPER_L EQU 29H ;用于保存读出温度的低8位
- TEMPER_H EQU 28H ;用于保存读出温度的高8位
- TIAO_H EQU 27H ;用于保存设定温度的数据
- ;FLAG1 EQU 38H ;是否检测到DS18B20标志位
- buffer EQU 35H ;温度临时存放区
- ;a_bit EQU 20H ;数码管个位数存放内存位置
- ;b_bit EQU 21H ;数码管十位数存放内存位置
- SL EQU 22H ;设定温度时数码管个位数存放内存位置
- SH EQU 23H ;设定温度时数码管十位数存放内存位置
- sdwd EQU 24H ;设定温度压缩BCD码位
- DQ BIT P3.0 ;数据输入/输出端
- ORG 0000H
- AJMP MAIN0
- ORG 0100H
- MAIN0: MOV SP,#70H
- MOV A,#89H ; ;8155方式控制字0DH(A、C口输出,B口输入)送累加器A
- MOV DPTR,#0F003H
- MOVX @DPTR,A
- MOV sdwd, #25H ;设定初始温度37度,上电后内部设定温度
- MAIN1: LCALL BH_DISBCD
- LCALL KEY
- JNB 00H,MAIN1
- CLR 00H
- MAIN2: LCALL START_Temperature ;向DS18B20发送读温度指令
- LCALL DelayTime
- LCALL RD_Temperature ;读出温度值,并转换为BCD码
- MOV TEMPER_L,B ;温度个位,小数位数据
- MOV TEMPER_H,A ;温度十位数据
- ;LCALL DIS_BCD ;提取温度数据,转换为非压缩型BCD码,并显示
- LCALL BH_DISBCD
- LCALL KEY
- LCALL TContral
- AJMP MAIN2
- ;**********************************************************
- ; 判断DS18B20是否存在,启动DS18B20 ;CY为判断标志
- START_Temperature: SETB DQ
- ACALL INIT_18B20 ;先复位DS18B20
- JC GET_T0
- MOV A,#0CCH ;跳过ROM匹配
- LCALL WRITE_18B20
- MOV A,#44H ;发出温度转换命令
- LCALL WRITE_18B20
- CLR C
- GET_T0: RET
- ;***********************************************************
- ; 读出转换后的温度值,保存于:A-高8位数据,B-低8位数据
- RD_Temperature:LCALL INIT_18B20 ;准备读温度前先复位
- JC GET_T1
- MOV A,#0CCH ;跳过ROM匹配
- LCALL WRITE_18B20
- MOV A,#0BEH ;发出读温度命令
- LCALL WRITE_18B20
- LCALL READ_18B20 ;读出温度
- MOV B,A ;存放到A,B中
- LCALL READ_18B20
- GET_T1: RET
- ;***********************************************************
- ; DS18B20温度转换/显示
- DIS_BCD: MOV R0,#buffer+3 ;设置显示内容存放区首地址
- MOV @R0,#10H ;正数
- MOV A,TEMPER_H
- JNB ACC.3,DIS_BCD1 ;判断温度是否为负
- MOV @R0,#11H ;负数
- CPL A
- XCH A,TEMPER_L
- CPL A
- ADD A,#1
- XCH A,TEMPER_L
- ADDC A,#0
- DIS_BCD1: ANL A,#0FH ;将温度整数位转换为ASCII
- MOV B,A
- MOV A,TEMPER_L
- ANL A,#0F0H
- ORL A,B ;将温度的个位与十位BCD合在一起
- SWAP A
- MOV B,#10
- DIV AB
- JNZ DIS_BCD2 ;判断温度的十位是否为0进行相应处理
- MOV A,#10H ;十位为0
- XCH A,@R0
- DEC R0
- MOV @R0,A
- SJMP DIS_BCD3
- DIS_BCD2: DEC R0
- MOV @R0,A
- DIS_BCD3: DEC R0
- MOV A,B
- ;ORL A,#80H ;小数点
- MOV @R0,A
- DEC R0
- MOV A,TEMPER_L ;转换小数部分
- ANL A,#0FH
- MOV B,A
- CLR A
- JNB B.0, DIS_BCD4
- MOV A,#6
- DIS_BCD4: JNB B.1, DIS_BCD5
- ADD A,#12H
- DA A
- DIS_BCD5: JNB B.2, DIS_BCD6
- ADD A,#25H
- DA A
- DIS_BCD6: JNB B.3, DIS_BCD7
- ADD A,#50H
- DA A
- DIS_BCD7: SWAP A
- ANL A,#0FH
- MOV @R0,A
- MOV R0,#buffer+4 ;显示数据首地址
- MOV @R0,#10H
- INC R0
- MOV @R0,#10H
- INC R0
- MOV @R0,#10H
- INC R0
- MOV @R0,#10H
- MOV R0,#buffer
- LCALL Display
- RET
- ;***********************************************************
- ;DS18B20温度转换/显示
- BH_DISBCD: MOV A,TEMPER_L ;
- MOV C,40H ;将28H中的最低位移入C(28H.0-C)
- RRC A
- MOV C,41H
- RRC A
- MOV C,42H
- RRC A
- MOV C,43H
- RRC A
- MOV TEMPER_L,A ;新字节29H是实际测量的温度
- LCALL BCDBHDA
- LCALL Display
- RET
- ;***********************************************************
- TContral: CLR C ;比较转换值与设定值
- MOV 26H,sdwd ;把温度设定保存到26H单元后减2度,作为低度的数据
- DEC 26H
- MOV A,TEMPER_L
- CJNE A,26H,LOOP1 ;下限设定温度,不相等跳LOOP1
- LJMP HOTTING ;与下限值相等跳HOTTING,加热
- LOOP1: JC HOTTING ;温度小于下限值跳HOTTING,加热
- MOV A,TEMPER_L ;温度大于下限值,与上限值比较
- CLR C
- MOV 27H,sdwd
- INC 27H
- CJNE A,27H,LOOP2 ;上限设定温度,不相等跳LOOP2
- SJMP STOPHOT ;相等跳STOPHOT,停止加热
- LOOP2: JNC STOPHOT ;温度大于上限值跳STOPHOT,停止加热
- SJMP KEEP ;温度小于上限且大于下限值跳KEEP,保温
- HOTTING: CLR P1.0 ;小,加热器驱动
- SETB P1.1 ;关闭保温灯
- KEEP: SJMP BACK ;返回,保持原态,保温
- STOPHOT: SETB P1.0 ;关闭加热器
- CLR P1.1 ;点亮保温灯
- BACK: RET
- ;***********************************************************
- ;键盘响应子程序
- KEY: MOV DPTR,#0F002H
- MOVX A,@DPTR ;读列线状态
- ORL A,#0F0H
- CJNE A,#0FFH,NEXT1
- SS: RET
- NEXT1: LCALL D10ms
- MOV DPTR,#0F002H ;指向8255C口
- MOVX A,@DPTR
- ORL A,#0F0H
- CJNE A,#0FFH,NEXT2
- LJMP SS
- NEXT2: MOV R3,#4
- MOV DPTR,#0F002H
- MOV R4,#00H
- MOVX A,@DPTR
- NEXT3: RRC A
- JNC NEXT4
- INC R4
- DJNZ R3,NEXT3
- LJMP SS
- NEXT4: MOVX A,@DPTR ;等待键释放
- ORL A,#0F0H
- CJNE A,#0FFH,NEXT4
- MOV DPTR,#TAB ;指向按键转移指令表首地址
- MOV A,R4
- RL A
- JMP @A+DPTR
- TAB: AJMP KEY0
- AJMP KEY1
- AJMP KEY2
- AJMP KEY3
- ;AJMP KEY4
- ;AJMP KEY5
- ;AJMP KEY6
- ;AJMP KEY7
- ;*********************************
- ;按下KEY0后转加1程序
- KEY0: MOV R5,#30H
- LCALL Displa
- MOV A,sdwd ;把设定温度送累加器判断
- CJNE A,62H,JIA0 ;比较设定温度是否到99度,不是则加
- MOV sdwd,#00H
- LJMP JIA1
- JIA0: INC sdwd
- JIA1: LCALL Displa
- DJNZ R5,JIA1
- LJMP SS
- ;*************************
- KEY1: MOV R5,#30H
- LCALL Displa
- MOV A,sdwd ;把设定温度送累加器判断
- CJNE A,01H,JIAN0 ;比较设定温度是否到0度,不是则减
- MOV sdwd,#62H
- LJMP JIAN1
- JIAN0:DEC sdwd
- JIAN1:LCALL Displa
- DJNZ R5,JIAN1
- LJMP SS
- ;*************************
- KEY2: SETB 00H
- LJMP SS
- ;*************************
- KEY3: LJMP SS
- ;***********************************************************
- ;DS18B20复位初始化子程序
- INIT_18B20: SETB DQ
- NOP
- CLR DQ ;主机发出501us的复位低脉冲
- MOV R7,#250
- DJNZ R7,$
- SETB DQ ;拉高数据线
- MOV R7,#30
- TSR: JNB DQ,TSR1 ;等待DS18B20回应
- DJNZ R7,TSR
- SETB C ;置位标志位,表示DS18B20不存在
- RET
- TSR1: CLR C ;复位标志位,表示DS18B20存在
- MOV R7,#250
- DJNZ R7,[ DISCUZ_CODE_2 ]nbsp; ;时序要求延时一段时间
- RET
- ;***************************************************************
- ;DS18B20写操作
- WRITE_18B20: MOV R7,#8 ;一共8位数据
- CLR C
- WRI: NOP
- CLR DQ
- MOV R6,#3
- DJNZ R6,[ DISCUZ_CODE_2 ]nbsp;
- RRC A
- MOV DQ,C
- MOV R6,#26
- DJNZ R6,[ DISCUZ_CODE_2 ]nbsp;
- SETB DQ
- DJNZ R7,WRI
- SETB DQ
- RET
- ;****************************************************************
- ;DS18B20读操作
- READ_18B20: MOV R7,#8 ;数据一共有8位
- READ1: CLR DQ
- NOP
- NOP
- SETB DQ
- NOP
- MOV R6,#3
- DJNZ R6,[ DISCUZ_CODE_2 ]nbsp;
- MOV C,DQ
- MOV R6,#26
- DJNZ R6,[ DISCUZ_CODE_2 ]nbsp;
- RRC A
- DJNZ R7,READ1
- RET
-
- ;******************************************************************
- BCDBHDA: MOV R0,#buffer
- MOV A,TEMPER_L ;将29H中的十六进制数转换成10进制
- MOV B,#10 ;10进制/10=10进制
- DIV AB
- MOV @R0,B ;个位在buffer(35H)
- INC R0
- MOV @R0,A ;十位在buffer+1(36H)
- ;*************************
- INC R0
- MOV A,sdwd
- MOV B,#10 ;10进制/10=10进制
- DIV AB
- MOV @R0,B ;个位在buffer+2(37H)
- INC R0
- MOV @R0,A ;十位在buffer+3(38H)
- RET
- ;******************************************************************
- Display: MOV R0,#buffer
- MOV R7,#04H ;----1显示子程序开始
- MOV R1,#60H ;60H 61H(62H 63H)存放测量(设定)温度个位、十位段码
- DISP0: MOV A,@R0
- MOV DPTR,#TABLE
- MOVC A,@A+DPTR
- MOV @R1,A
- INC R0
- INC R1
- DJNZ R7,DISP0
- ;*****************************
- MOV R7,#04H
- MOV R0,#60H
- MOV R3,#0FEH
- DISP1: MOV DPTR,#0F001H ;指定字位码入口地址:8155的C口
- MOV A,R3
- MOVX @DPTR,A
- RL A
- MOV R3,A
- MOV DPTR,#0F000H ;指定字型码入口地址:8155的A口
- MOV A,@R0
- MOVX @DPTR,A
- INC R0
- LCALL DELAY
- DJNZ R7,DISP1
- RET ;----1显示子程序结束
- ;******************************************************************
- ;;闪烁设定显示
- Displa: MOV A,sdwd
- MOV B,#10 ;10进制/10=10进制
- DIV AB
- MOV SL,B ;十位在b
- MOV SH,A ;个位在a
- MOV R1,#250 ;显示250次
- dpl2: MOV A,SL ;取设定温度个位数
- MOV DPTR,#TABLE ;指定查表启始地址
- MOVC A,@A+DPTR ;查个位数的7段代码
- MOV DPTR,#0F000H
- MOVX @DPTR,A ;送出个位的7段代码
- MOV DPTR,#0F001H
- MOV A,#0FBH
- MOVX @DPTR,A ;开个位显示
- ACALL D1ms ;显示1ms
- MOV A,#0FFH
- MOVX @DPTR,A
- MOV A,SH ;取设定温度十位数
- MOV DPTR,#TABLE ;指定查表启始地址
- MOVC A,@A+DPTR ;查十位数的7段代码
- MOV DPTR,#0F000H
- MOVX @DPTR,A ;送出十位的7段代码
- MOV DPTR,#0F001H
- MOV A,#0F7H
- MOVX @DPTR,A ;开十位显示
- ACALL D1ms ;显示1ms
- MOV A,#0FFH
- MOVX @DPTR,A
- DJNZ R1,dpl2 ;250次没完循环
- RET
- TABLE: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
- ;******************************************************************
- ;延时程序
- DelayTime: PUSH 07H
- PUSH 06H
- PUSH 05H
- MOV R7,#1
- DelayTime_1: MOV R6,#1
- DelayTime_2: MOV R5,#0
- DJNZ R5,$
- DJNZ R6,DelayTime_2
- DJNZ R7,DelayTime_1
- POP 05H
- POP 06H
- POP 07H
- RET
- ;*************************************************
- DELAY: NOP
- MOV R6,#2 ;----2延时子程序开始
- DEL2: MOV R5,#0FFH
- DEL1: NOP
- NOP
- DJNZ R5, DEL1
- DJNZ R6, DEL2
- RET
- ;*************************************************
- D10ms: MOV R5,#20
- DL: MOV R6,#0FFH
- DL0: DJNZ R6,DL0
- DJNZ R5,DL
- RET
- ;*************************************************
- D1ms: MOV R7,#1
- DJNZ R7,$
- RET
- ;*************************************************
- END
复制代码
|
|