DS18B20 水温控制系统

来源:百度文库 编辑:神马文学网 时间:2024/04/29 22:51:33
在一些温控系统中,广泛采用的是通过热电偶、热电阻或PN结测温电路经过相应的信号调理电路,转换成A/D转换器能接收的模拟量,再经过采样/保持电路进行A/D转换,最终送入单片机及其相应的外围电路,完成监控。但是由于传统的信号调理电路实现复杂、易受干扰、不易控制且精度不高。因此,本系统用一种新型的可编程温度传感器(DS18B20),不需复杂的信号调理电路和A/D转换电路能直接与单片机完成数据采集和处理,实现方便、精度高,可根据不同需要用于各种场合。
二.设计目的
设计并制作一个水温自动控制系统,控制对象为1升净水,容器为搪瓷器皿。水温可以在一定范围内由人工设定,并能在环境温度降低时实现自动控制,以保持设定的温度基本不变。
利用单片机AT89S52实现水温的智能控制,使水温能够在40-90 度之间实现控制温度调节。利用仪器读出水温,并在此基础上将水温调节到我们通过键盘输入的温度(其方式是加热或降温),而且能够将温度显示在我们的七段发光二极管板上。
三.系统功能
1.         可以对温度进行自由设定,到那时必须在0-100摄氏度单位内,设定时可以适时的显示说设定的温度值,温度是可以自由设置的,传感器的检测值与设定的温度比较,可以显示在七段发光二极管上。
2.         温度由1台1000w电炉来实现,如果温度不在40-90度之间,则在LED上显示“8888”,表示错误。
3.         能够保持不间断显示水温,显示位数4位,分别为百位,个位,十位,和小数位。(但由于规定不超过90度,所以百位也就没有实现,默认的百位是不显示的)
四.系统设备
ME300B 最小系统板 DS18B20 数字温度传感器(集成了A/D转换功能) 1000W 电炉 温度计 继电器 风扇 盛水器皿
五.温度控制总体方案与原理
1.系统模块图
系统模块分为:DS18B20模块,显示模块,继电器模块,键盘输入模块,DS18B20可以被编程,所以箭头是双向的,CPU(89S52)首先写入命令给DS18B20,然后DS18B20开始转换数据,转换后通过89S52来处理数据。数据处理后的结果就显示到数码管上。
1.系统模块总关系图
本系统的执行方法是循环查询执行的,键盘扫描也是用循环查询的办法,由于本系统对实时性要求不是很高,所以没有用到中断方式来处理。
六.温度转换核心及其算法
1.温度传感器DS18B20原理与特性
本系统采用了DS18B20单总线可编程温度传感器,来实现对温度的采集和转换,大大简化了电路的复杂度,以及算法的要求。
首先先来介绍一下DS18B20这块传感器的特性及其功能:
DSl8B20的管脚及特点
DS18B20可编程温度传感器有3个管脚。(如图:1) GND为接地线,DQ为数据输入输出接口,通过一个较弱的上拉电阻与单片机相连。VDD为电源接口,既可由数据线提供电源,又可由外部提供电源,范围3.O~5.5 V。本文使用外部电源供电。
主要特点有:
1.         用户可自设定报警上下限温度值。
2.         不需要外部组件,能测量-55~+125℃ 范围内的温度。
3.         -10℃ ~ +85℃ 范围内的测温准确度为±0.5℃ 。
4.         通过编程可实现9~l2位的数字读数方式,可在至多750 ms内将温度转换成12 位的数字,测温分辨率可达0.0625℃ 。
5.         独特的单总线接口方式,与微处理器连接时仅需要一条线即可实现与微处理器双向通讯。

DS18B20的内部结构
DS18B20内部功能模块如图2所示,主要由4部分组成:64位光刻R0M(图3)、温度传感器、非易失性的温度报警触发器TH和TL、配置寄存器。R0M 中的64位序列号是出厂前被光刻好的,他可以看作是该DSISB20的地址序列码,每个DSI8B20的64位序列号均不相同。高低温报警触发器TH 和TL,配置寄存器均由一个字节的E2PROM组成,使用一个存储器功能命令可对 TH,TL或配置寄存器写入。配置寄存器中R1,R0决定温度转换的精度位数:R1R0=’00’,9位精度,最大转换时间为93.75 ms;R1R0 = ‘01’,10位精度,最大转换时间为187.5 ms;R1R0 = ‘10’,11位精度,最大转换时间为375 ms;R1R0 =’11’,12位精度,最大转换时间为750 ms;未编程时默认为12位精度。本系统采用的也是12位的精度。

DS18B20的内存结构
DSI8B20温度传感器的内部存储器包括一个高速暂存RAM (便笺式的内部存储器)和一个非易失性的可电擦除的EEPROM,后者存放高温和低温触发器TH,TL和结构寄存器。便笺存储器包含了9个连续字节(0~8),前两个字节是测得的温度信息(图4),字节0的内容是温度的低8位,字节1是温度的高8位,字节2是TH(温度上限报警),字节3是TL(温度下限报警),字节4是配置寄存器(图5),用于确定输出分辨率9到12位。第5、6、7个字节是预留寄存器,用于内部计算。字节8是冗余检验字节,校验前面所有8个字节的CRC码,可用来保证通信正确。


DS18B20的测温功能
当DSI8B20接收到温度转换命令后,开始启动转换。转换完成后的温度值就以16位带符号扩展的二进制补码形式存储在高速暂存存储器的0,1字节。单片机可通过单线接口读到该数据,读取时低位在前,高位在后,数据格式以0.062 5℃/LSB形式表示。温度值格式如图4所示,其中“S”为标志位,对应的温度计算:当符号位S=0时,直接将二进制位转换为十进制;当S=1时,先将补码变换为原码,再计算十进制值。图4下面的表是对应的一部分温度值。DSI8B20完成温度转换后,就把测得的温度值与 TH做比较,若T>TH或T工作过程中的协议
初始化 -> RoM操作命令 -> 存储器操作命令-> 处理数据
1 初始化
单总线上的所有处理均从初始化开始
2 ROM操作品令
总线主机检测到DSl820的存在便可以发出ROM操作命令之一这些命令如
指令                                       代码
Read ROM(读ROM)                 [33H]
Match ROM(匹配ROM)           [55H]
Skip ROM(跳过ROM]              [CCH]
Search ROM(搜索ROM)           [F0H]
Alarm search(告警搜索)            [ECH]
3 存储器操作命令
指令                                                 代码
Write Scratchpad(写暂存存储器)      [4EH]
Read Scratchpad(读暂存存储器)      [BEH]
Copy Scratchpad(复制暂存存储器)  [48H]
Convert Temperature(温度变换)        [44H]
Recall EPROM(重新调出)                 [B8H]
Read Power supply(读电源)               [B4H]
温度传感器与单片机通讯时序


2.温度转换算法及分析
由于DS18B20转换后的代码并不是实际的温度值,所以要进行计算转换。温度高字节(MS Byte)高5位是用来保存温度的正负(标志为S的bit11~bit15),高字节(MS Byte)低3位和低字节来保存温度值(bit0 ~ bit10)。其中低字节(LS Byte)的低4位来保存温度的小数位(bit0 ~ bit 3)。由于本程序采用的是0.0625的精度,小数部分的值,可以用后四位代表的实际数值乘以0.0625,得到真正的数值,数值可能带几个小数位,所以采取小数舍入,保留一位小数即可。也就说,本系统的温度精确到了0.1度。

算法核心:首先程序判断温度是否是零下,如果是,则DS18B20保存的是温度的补码值,需要对其低8位(LS Byte)取反加一变成原码。处理过后把DS18B20的温度Copy到单片机的RAM中,里面已经是温度值的Hex码了,然后转换Hex码到BCD码,分别把小数位,个位,十位,百位的BCD码存入RAM中。由于百位没有用,默认情况是置为0A,在显示屏上没有任何显示。
温度算法核心代码
DATA_DEAL:
MOV A,TEMPERATURE_H ;TEMPERATURE_H存放的是DS18B20转换后的高8位的值(上图的MS Byte)ANL A,#80H                           ;判温度是否零下
JZ TEMPC1               ;A为0,说明是正数,跳往TEMPC1,如果是负数,则对低8为进行补码处理
CLR C
MOV A,TEMPERATURE_L ;为负数,对低8 位(上图的LS Byte)求补
CPL A                    ;取反加1
ADD A,#01H
MOV TEMPERATURE_L,A ;取补码后存回TEMPERATURE_L,此时TEMPERATURE_L里面的值就可以表示温度了        MOV A,TEMPERATURE_H
CPL A
ADDC A,#00H              ;高位TEMPERATURE_H取反,加上从低位TEMPERATURE_L进来的位
MOV TEMPERATURE_H,A   ;写回TEMPERATURE_H
MOV TEMPERATURE_HC,#0BH
SJMP TEMPC11
TEMPC1: MOV TEMPERATURE_HC,#0AH
TEMPC11:MOV A,TEMPERATURE_HC
SWAP A
MOV TEMPERATURE_HC,A
MOV A,TEMPERATURE_L
ANL A,#0FH            ;取A低4位(小数位,单位是0.0625),得出来的数要乘以0.0625,通过查表来算出值
MOV DPTR,#TEMPDOTTAB
MOVC A,@A+DPTR                   ;查表
MOV TEMPERATURE_LC,A    ;TEMPERATURE_LC的低四位保存 小数部分 BCD
MOV DIS_BUF_X,A          ;小数位的BCD码送入显示buffer中
MOV A,TEMPERATURE_L ;整数部分
ANL A,#0F0H              ;得到个位单个数值
SWAP A                   ;SWAP后就得到个位真正的个位
MOV TEMPERATURE_L,A
MOV A,TEMPERATURE_H
ANL A,#0FH
SWAP A
ORL A,TEMPERATURE_L
MOV TEMPERATURE_ZH,A     ;组合后的值存入TEMPERATURE_ZH
LCALL HtoB                     ;转换HEx值成为BCD码
MOV TEMPERATURE_L,A      ;TEMPERATURE_L目前存入的是十位和个位的BCD编码
ANL A,#0F0H
SWAP A
ORL A,TEMPERATURE_HC     ;TEMPERATURE_HC 低4位 存放 十位数 BCD
MOV TEMPERATURE_HC,A
MOV A,TEMPERATURE_L
ANL A,#0FH
SWAP A                   ;TEMPERATURE_LC高4位 存放 个位数 BCD
ORL A,TEMPERATURE_LC
MOV TEMPERATURE_LC,A
MOV A,R7
JZ TEMPC12
ANL A,#0FH
SWAP A
MOV R7,A
MOV A,TEMPERATURE_HC      ;TEMPERATURE_HC高4位 存放 百位数 BCD
ANL A,#0FH
ORL A,R7
MOV TEMPERATURE_HC,A
TEMPC12:RET
;小数部分码表
TEMPDOTTAB: DB   00H,01H,01H,02H,03H,03H,04H,04H,05H,06H,06H,07H,08H,08H,09H,09H
结果温度值的BCD码存放到TEMPERATURE_HC(百位和十位),TEMPERATURE_LC(个位和小数位)中
七.硬件设计说明
1.系统总体电路图

.各个模块电路图
输入系统
. 键盘模块
我们用的下面四个独立键盘中的三个,分别是:K2,K3,K4。

. 温度测量模块
DS18B20通过P3.3口和AT89S52进行通讯。

输出系统
. 继电器模块
下图是一个蜂鸣器和一个继电器的图,我们只用到了继电器的图,继电器和单片机的P1.3口进行通讯。

1. 显示模块
该显示模块的动态显示数码管,我们用到前面四个数码管,P0口是送字符的,P2口是用来位选数码管的。

芯片系统
本系统采用的是AT89S52芯片。下面是它的引脚图。

八.软件设计说明
本系统采用的是循环查询方式,来显示和控制温度的。
.总模块的流程图

2.各个模块的流程图
读取温度DS18B20模块的流程

键盘扫描处理流程

九.操作指引
按键功能
1.      Enter   → P1.5(k2)
2.      Up      → P1.6(k3)
3.      Down        → P1.7(k4)
显示温度
1.      未插DS18B20时,数码管显示错误888.8.
2.      插入DS18B20是,数码管显示当前温度XX.X
设定温度
1.按下Enter,数码管温度显示停止,显示的数字变的比以前亮。
2.这时可以按Up和Down来调节当前温度。
3.调节好后,按Enter退出。这时数字变的又暗了,数码管继续显示当前温度
继电器随着设定的温度,依据情况跳变。
十.参考文献
[1].              单片机原理与应用技术 .江力 主编 .清华大学出版社 .2006
[2].              微型计算机接口技术 . 王兆月等 编著. 机械工业出版社 .2006
[3].              数字电子技术 . 江晓安等 编著. 西安电子科技大学出版社 .1993
[4].              ME300B说明书 .伟纳电子 编著. 伟纳电子出版 .2006
[5].              DS18B20官方英文文档 . DS18B20官方英文站点下载 .
程序源代码
TEMPERATURE_L DATA 31H   ;DS18B20低8位Buffer
TEMPERATURE_H DATA 30H   ;DS18B20高8位Buffer
TEMPERATURE_HC DATA 32H   ;计算后的百位和十位的BCD码存放BUFFER
TEMPERATURE_LC DATA 33H   ;计算后的个位和小数位的BCD码存放BUFFER
TEMPERATURE_ZH DATA 34H   ;计算后十位和个位HEX码的存放BUFFER
DIS_BUF_X DATA 35H ;数码管小数位Buffer
DIS_BUF_G DATA 36H  ;数码管个位Buffer
DIS_BUF_S DATA 37H  ;数码管十位Buffer
DIS_BUF_B DATA 38H  ;数码管百位Buffer
KEY_BUF_G DATA 39H ;键盘输入后,的个位值
KEY_BUF_S DATA 49H ;键盘输入后,的十位值
KEY_BUF_B DATA 41H ;键盘输入后,的百位值
K_UP EQU P1.5     ;上调按钮
K_DOWN EQU P1.6   ;下调按钮
K_ENTER EQU P1.7  ;输入数据确认按钮
P_DS18B20 EQU P3.3  ;读取DS18B20的输入端口
P_SWITCH EQU P1.3   ;继电器控制端口,1-风扇,0-电炉
FLAG EQU 20H.0        ;标志位,确定是否存在DS18B20
ENTER_FLAG EQU 20H.1  ;键盘输入的标志位,为0说明键盘正在输入,为1说明键盘输入退出
;程序开始执行
ORG 0000H
LJMP MAIN
ORG 0100H
MAIN:  MOV SP,#60H           ;初始化
MOV KEY_BUF_G,#00H   ;由于KEY_BUF是由用户输入的,所以先赋值初始化
MOV KEY_BUF_S,#00H
MOV KEY_BUF_B,#00H
NEXT:
LCALL READ_TEMP ;调用读温度子程序
JB FLAG,NORMAL   ;判断是否有DS18B20的存在
CALL ERR              ;不存在时显示错误信息
AJMP NEXT
NORMAL: LCALL DATA_DEA      ;处理从DS18B20得到的数据
LCALL SET_DIS_BUF        ;赋值给DIS_BUF_X,G,S,B
LCALL DISPLAY       ;调用数码管显示子程序
LCALL SCAN_KEY      ;扫描键盘
LCALL SWITCH             ;处理继电器
AJMP  NEXT
;程序名称:ERR
;功能:程序出错处理,显示四个8,即8888
;入口参数:无
;出口参数:DIS_BUF_X,DIS_BUF_G, DIS_BUF_S, DIS_BUF_B
ERR: MOV DIS_BUF_X,#08H ;如果没有找到DS18B20,那么就显示错误,错误显示为888
MOV DIS_BUF_G,#08H
MOV DIS_BUF_S,#08H
MOV DIS_BUF_B,#08H
LCALL DISPLAY
RET
;程序名称:DATA_DEAL
;功能:处理采集后的的数据
;入口参数:TEMPERATURE_L
;出口参数:DIS_BUF_G, DIS_BUF_S, DIS_BUF_B
DATA_DEAL:
MOV  A,TEMPERATURE_H     ;判温度是否零下
ANL  A,#80H
JZ  TEMPC1          ;A为0,说明是正数,跳往TEMPC1,如果是负数,则对低8为进行补码处理
CLR  C
MOV  A,TEMPERATURE_L     ;二进制数求补(双字节)
CPL  A                   ;取反加1
ADD  A,#01H
MOV  TEMPERATURE_L,A     ;取补码后存回TEMPERATURE_L,此时TEMPERATURE_L里面的值就可以表示温
;度了,不过还要继续处理一下。
MOV  A,TEMPERATURE_H
CPL  A
ADDC  A,#00H               ;高位TEMPERATURE_H取反,加上从低位TEMPERATURE_L进来的位
MOV  TEMPERATURE_H,A       ;写回TEMPERATURE_H
MOV  TEMPERATURE_HC,#0BH
SJMP  TEMPC11
TEMPC1: MOV  TEMPERATURE_HC,#0AH
TEMPC11:MOV  A,TEMPERATURE_HC
SWAP  A
MOV  TEMPERATURE_HC,A
MOV  A,TEMPERATURE_L
ANL  A,#0FH              ;取A低4位(小数位,单位是0.0625),得出来的数要乘以0.0625,通过查表来算出值
MOV  DPTR,#TEMPDOTTAB
MOVC  A,@A+DPTR          ;查表
MOV  TEMPERATURE_LC,A    ;TEMPERATURE_LC  LOW=小数部分 BCD
MOV  DIS_BUF_X,A         ;小数位的BCD码送入显示buffer中
MOV  A,TEMPERATURE_L     ;整数部分
ANL  A,#0F0H             ;得到个位‘单个数值
SWAP  A                  ;SWAP后就得到个位真正的个位
MOV  TEMPERATURE_L,A
MOV  A,TEMPERATURE_H
ANL  A,#0FH
SWAP  A
ORL  A,TEMPERATURE_L
MOV  TEMPERATURE_ZH,A     ;组合后的值存入TEMPERATURE_ZH
LCALL  HtoB               ;转换HEx值成为BCD码
MOV  TEMPERATURE_L,A      ;TEMPERATURE_L目前存入的是十位和个位的BCD编码
ANL  A,#0F0H
SWAP  A
ORL  A,TEMPERATURE_HC     ;TEMPERATURE_HC LOW位 = 十位数 BCD
MOV  TEMPERATURE_HC,A
MOV  A,TEMPERATURE_L
ANL  A,#0FH
SWAP  A                   ;TEMPERATURE_LC HI位 = 个位数 BCD
ORL  A,TEMPERATURE_LC
MOV  TEMPERATURE_LC,A
MOV  A,R7
JZ  TEMPC12
ANL  A,#0FH
SWAP  A
MOV  R7,A
MOV  A,TEMPERATURE_HC      ;TEMPERATURE_HC HI = 百位数 BCD
ANL  A,#0FH
ORL  A,R7
MOV  TEMPERATURE_HC,A
TEMPC12:RET
;  小数部分码表
TEMPDOTTAB:  DB   00H,01H,01H,02H,03H,03H,04H,04H,05H,06H,06H,07H,08H,08H,09H,09H
;0.0625->00H
;0.0625*2 = 0.125->01H
;0.0625*3 = 0.1875->01H
;0.0625*4 = 0.25->02H
;0.0625*5 = 0.3125->03H
;以此类推..........
;程序名称:HtoB
;功能:十六进制转 BCD
;入口参数:A
;出口参数:R7
HtoB:   MOV  B,#064H  ;100
DIV  AB       ;a/100
MOV  R7,A     ;
MOV  A,#0AH
XCH  A,B
DIV  AB
SWAP  A
ORL  A,B
RET
;程序名称:INIT_TEMP
;功能:初始化DS18B20,确定DS18B20是否是存在的
;入口参数:无
;出口参数:FLAG
INIT_TEMP:
SETB P_DS18B20
NOP
CLR  P_DS18B20              ;主机发出延时537微秒的复位低脉冲
MOV  R0,#6BH
MOV  R1,#04H
TSR1:   DJNZ  R0,$
MOV 40,#6BH
DJNZ     R1,TSR1
SETB P_DS18B20             ;然后拉高数据线,释放总线进入接受状态
NOP
NOP
NOP
MOV  R0,#32H
TSR2:   JNB   P_DS18B20,TSR3          ;等待DS18B20回应
DJNZ  R0,TSR2
LJMP  TSR4               ;延时
TSR3:   SETB  FLAG               ;置标志位,表示DS1820存在
LJMP  TSR5
TSR4:   CLR   FLAG               ;清标志位,表示DS1820不存在
LJMP  TSR7
TSR5:   MOV   R0,#06BH
TSR6:   DJNZ  R0,TSR6            ;时序要求延时一段时间
TSR7:   SETB  P_DS18B20
RET
;程序名称:READ_TEMP
;功能:读取DS18B20的数据
;入口参数:TEMPERATURE_L,TEMPERATURE_H
;出口参数:无
READ_TEMP:
SETB  P_DS18B20
LCALL INIT_TEMP   ;先复位DS18B20
JB    FLAG,TSS2
RET                     ;判断DS1820是否存在?若DS18B20不存在则返回
TSS2:    MOV  A,#0CCH            ;跳过ROM匹配
LCALL WRITE_18B20
MOV   A,#44H             ;发出温度转换命令
LCALL WRITE_18B20
;LCALL     DISPLAY        ;等待AD转换结束,12位的话750微秒
LCALL INIT_TEMP   ;准备读温度前先复位
MOV   A,#0CCH            ;跳过ROM匹配
LCALL WRITE_18B20
MOV   A,#0BEH            ;发出读温度命令
LCALL WRITE_18B20
LCALL READ_18B20      ;将读出的温度数据保存到35H/36H
RET
;具体的步骤:初始化完后当拉低电平开始产生写时隙-》15微妙之内送入一位数据-》15~60微妙1820来
;采样读取它
;程序名称:WRITE_18B20
;功能:将A保存的数值写入DS1820中,有具体的时序要求,详细参考附图的说明
;入口参数:A 寄存器
;出口参数:无
WRITE_18B20:
MOV   R2,#8              ;一共8位数据,串行通讯
CLR   C
WR1: CLR  P_DS18B20
MOV   R3,#07
DJNZ  R3,$
RRC   A                  ;循环右移
MOV   P_DS18B20,C
MOV   R3,#3CH
DJNZ  R3,$               ;23*2 = 46微妙
SETB  P_DS18B20
NOP
DJNZ  R2,WR1             ;A里面一共是8位,所以要送8次
SETB  P_DS18B20     ;释放总线
RET
;程序名称:READ_18B20
;功能:读取18B20中的数据,由于是串行通讯,每次读取一个,循环8次读取
;入口参数:TEMPRATURE_L
;出口参数:无
READ_18B20:
MOV   R4,#4                  ;将温度高位和低位从DS18B20中读出
MOV   R1,#TEMPERATURE_L
RE00:    MOV R2,#8              ;数据一共有8位
RE01:    CLR C
SETB P_DS18B20
NOP
NOP
CLR   P_DS18B20
NOP
NOP
NOP
SETB  P_DS18B20
MOV   R3,#09
RE10:    DJNZ R3,RE10
MOV   C,P_DS18B20
MOV   R3,#3CH
RE20:    DJNZ R3,RE20
RRC   A
DJNZ R2,RE01
MOV   @R1,A
DEC   R1
DJNZ R4,RE00
RET
;程序名称:SCAN_KEY
;功能:扫描键盘
;入口参数:DIS_BUF_G,DIS_BUF_S,DIS_BUF_B
;出口参数:KEY_BUF_G,KEY_BUF_S,kEY_BUF_B
SCAN_KEY:
JB K_ENTER,QUIT            ;如果又Enter键入,则开始键盘输入
LCALL K_DELAY
JB K_ENTER,QUIT
CLR ENTER_FLAG                 ;每次进来都赋值输入标志,设置为0
MOV KEY_BUF_G,DIS_BUF_G ;将当前的温度赋值给KEY_BUF,也就是说是以当前温度为基准,进行加减的
MOV KEY_BUF_S,DIS_BUF_S
MOV KEY_BUF_B,DIS_BUF_B
K_LOOP:
JB ENTER_FLAG,QUIT             ;如果输入完成,ENTER_FLAG则为1,退出键盘程序
JB K_ENTER,KUP
CALL PRO_ENTER
KUP:  JB K_UP,KDOWN
CALL PRO_UP
KDOWN:JB K_DOWN,LOOPA
CALL PRO_DOWN
LOOPA:LCALL DISPLAY
SJMP K_LOOP
QUIT: RET
;程序名称:PRO_ENTER
;功能:确认键盘输入和退出键盘输入
;入口参数:ENTER_FLAG
;出口参数:ENTER_FLAG
PRO_ENTER:
CALL K_DELAY
JB K_ENTER,K_LOOP ;按键抖动处理
SETB ENTER_FLAG
CALL K_DELAY
RET
;程序名称:PRO_UP
;功能:数值上调处理
;入口参数:KEY_BUF_G,KEY_BUF_S,KEY_BUF_B
;出口参数:DIS_BUF_G,DIS_BUF_S,DIS_BUF_B
PRO_UP:
CALL K_DELAY
JB K_UP,K_LOOP    ;按键抖动处理
INC KEY_BUF_G     ;个位增一
MOV A,KEY_BUF_G
CJNE A,#0AH,UPNEXT;个位增加到10,回0
MOV KEY_BUF_G,#00H
INC KEY_BUF_S     ;十位加一
MOV A,KEY_BUF_S
CJNE A,#0AH,UPNEXT;十位超过99,溢出了
MOV R0,#200
ERROR1:LCALL ERR        ;出错,显示8888
DJNZ R0,ERROR1
DEC KEY_BUF_S     ;退回99
MOV KEY_BUF_G,#09H
UPNEXT:
MOV DIS_BUF_G,KEY_BUF_G
MOV DIS_BUF_S,KEY_BUF_S
MOV DIS_BUF_B,KEY_BUF_B
CALL K_DELAY
RET
;程序名称:PRO_DOWN
;功能:数值下调处理
;入口参数:KEY_BUF_G,KEY_BUF_S,KEY_BUF_B
;出口参数:DIS_BUF_G,DIS_BUF_S,DIS_BUF_B
PRO_DOWN:
CALL K_DELAY
JB K_DOWN,K_LOOP    ;按键抖动处理
DEC KEY_BUF_G       ;个位减一
MOV A,KEY_BUF_G
CJNE A,#0FFH,DOWNNEXT;个位减到0,回到9
MOV KEY_BUF_G,#09H
DEC KEY_BUF_S        ;十位减一
MOV A,KEY_BUF_S
CJNE A,#0FFH,DOWNNEXT;十位低于0,溢出了
MOV R0,#200
ERROR2:LCALL ERR           ;出错,显示8888
DJNZ R0,ERROR2
INC KEY_BUF_S        ;退回00
MOV KEY_BUF_G,#00H
DOWNNEXT:
MOV DIS_BUF_G,KEY_BUF_G ;增加完成后,赋值退出,然后DISPLAY显示出来
MOV DIS_BUF_S,KEY_BUF_S
MOV DIS_BUF_B,KEY_BUF_B
CALL K_DELAY
RET
K_DELAY:           ;键盘抖动延时子程序
MOV R6,#250
DL20MS_1:
MOV R7,#200
DJNZ R7,$
DJNZ R6, DL20MS_1
RET
;继电器控制
SWITCH:
MOV A,KEY_BUF_G     ;三个Buffer都是0的话,说明还没有输入数值,直接退出
JNZ SNEXT
MOV A,KEY_BUF_S
JNZ SNEXT
MOV A,KEY_BUF_B
JZ  SQUIT
SNEXT:   CALL SET_DIS_BUF
MOV A,KEY_BUF_S
SUBB A,DIS_BUF_S
JC COOL
JNZ HOT                     ;十位如果相等,那么继续比较个位
MOV A,KEY_BUF_G
SUBB A,DIS_BUF_G
JC COOL
HOT:  CLR P_SWITCH               ;P_SWITCH 为0说明当前温度小于设定温度,要升温,所以接电炉
SJMP SQUIT
COOL: SETB P_SWITCH         ;P_SWITCH 为1说明当前温度大于设定温度,要降温,所以接风扇
SQUIT:RET
;程序名称:SET_DIS_BUF
;功能:赋值给DIS_BUF_G, DIS_BUF_S, DIS_BUF_B
;入口参数:TEMPERATURE_LC,TEMPERATURE_HC
;出口参数:DIS_BUF_G, DIS_BUF_S, DIS_BUF_B
SET_DIS_BUF:
MOV  A,TEMPERATURE_LC
ANL  A,#0FH
MOV  DIS_BUF_X,A                 ;小数位
MOV  A,TEMPERATURE_LC
SWAP  A
ANL  A,#0FH
MOV  DIS_BUF_G,A                 ;个位
MOV  A,TEMPERATURE_HC
ANL  A,#0FH
MOV  DIS_BUF_S,A                 ;十位
MOV  A,TEMPERATURE_HC
SWAP  A
ANL  A,#0FH
MOV  DIS_BUF_B,A                 ;百位
MOV  A,TEMPERATURE_HC
ANL  A,#0F0H
CJNE  A,#010H,NEXT0
SJMP  NEXT1
NEXT0:   MOV  A,TEMPERATURE_HC
ANL  A,#0FH
JNZ  NEXT1                  ;十位数是0
MOV  A,TEMPERATURE_HC
SWAP A
ANL  A,#0FH
MOV  73H,#0AH               ;符号位不显示
MOV  72H,A                  ;十位数显示符号
NEXT1:   RET
;程序名称:DISPLAY
;功能:显示数据到数码管中。
;入口参数:DIS_BUF_G, DIS_BUF_S, DIS_BUF_B
;出口参数:无
DISPLAY:
MOV DPTR,#DISTAB
MOV R3,#0FEH
MOV R1,#DIS_BUF_B
DPLOP:   MOV A,@R1
MOVC A,@A+DPTR
MOV P2,R3
MOV P0,A
CJNE R3,#0FBH,DPNEXT
CLR P0.7
DPNEXT:  MOV A,R3
RL A
MOV R3,A
DEC R1
CALL DS1M
CJNE R3,#0EFH,DPLOP
MOV  P0,#0FFH            ;一次显示结束,P0口复位
MOV  P2,#0FFH            ;P2口复位
RET
DS1M:
MOV R7,#0FFH
DJNZ R7,$
RET
;数码管TAB
DISTAB:
DB    0C0H ;0
DB    0F9H ;1
DB    0A4H ;2
DB    0B0H ;3
DB    099H ;4
DB    092H ;5
DB    082H ;6
DB    0F8H ;7
DB    080H ;8
DB    090H ;9
DB    0FFH ;NONE
END