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