;********************************************************
;************************显视温度************************
;********************************************************
COUNT DATA 41H ;地址计数常数
WENDU DATA 37H ;实际温度地址
WENDUD DATA 38H ;温度低位地址
WENDUG DATA 39H ;温度高位地址
SDWDG DATA 3aH ;设定高温度地址
SDWDD DATA 3bH ;设定低温度地址
TEMP EQU 30H
TEMP1 EQU 31H
BUF EQU 32H
DISBUF EQU 40H
PLAYFLAG BIT 22H.0
;----------------------------------------------------------------
RS EQU P2.0 ;
RW EQU P2.1 ;
E EQU P2.2 ;
PSB EQU P2.3 ;
RST EQU P2.5 ;
SHUJU EQU P3.3 ;
K1 EQU P1.4 ;按键1,设定温度值减1
K2 EQU P1.5 ;按键2,设定温度值加1
K3 EQU P1.6 ;按键3,确定修改和确定退出
;============================================================
ORG 0000H
JMP MAIN
ORG 0040H
;============================================================
MAIN: CLR P3.7
LCALL SET_LCD ;初始化 LCD 12864
LCALL W18B20 ;初始化18B20
LCALL CWD
;********************************************************
WANG: LCALL W18B20 ;初始化18B20
LCALL DU18B20 ;读18B20温度
LCALL S18B20 ;送温度显视
LCALL ANJIAN ;按键程序
CLR PLAYFLAG
MOV TMOD,#20H ;定时器1工作于8位自动重载模式,用于产生波特率
MOV TH1,#0FDH
MOV TL1,#0FDH ;波特率9600
MOV SCON,#50H ;设定串行口工作方式
ANL PCON,#00H ;波特率不倍增
SETB TR1 ;启动定时器1
SENDDATA:
MOV A,WENDU
MOV SBUF,A
JNB TI,$ ; 等特数据传送
CLR TI ; 清除数据传送标志
LJMP WANG
;==============================================================
;对 LCD12864 做初始化设置
;==============================================================
SET_LCD:
SETB PSB ;通讯方式为8位数据并口
MOV A,#34H ;34H--扩充指令操作
LCALL SEND_I
MOV A,#30H ;30H--8bit控制界面,基本指令操作
LCALL SEND_I
MOV A,#01H ;清除显示
LCALL SEND_I
MOV A,#06H ;指定在资料写入或读取时,光标的移动方向
LCALL SEND_I ;DDRAM 的地址计数器(AC)加1
MOV A,#0CH ;开显示,关光标,不闪烁
LCALL SEND_I
RET
;==============================================================
;写指令子程序
;RS=0,RW=0,E=高脉冲,D0-D7=指令码
;==============================================================
SEND_I: LCALL CHK_BUSY
CLR RS
CLR RW
MOV P0,A
SETB E
NOP
NOP
CLR E
RET
;==============================================================
;测忙碌子程序
;RS=0,RW=1,E=H,D0-D7=状态字
;==============================================================
CHK_BUSY:
MOV P0,#0FFH ;测忙碌子程序
CLR RS
SETB RW
SETB E
JB P0.7,$
CLR E
RET
;==============================================================
;把 DS18B20 EEROM 里的温度报警值拷贝回暂存器(暂时用不到)
;==============================================================
CWD: LCALL W18B20
MOV A,#0CCH ;跳过ROM匹配
LCALL XIEB20
MOV A,#0B8H ;把EEROM里的温度报警值拷贝回暂存器
LCALL XIEB20
RET
;***************************************************
;DS18B20 复位与检测子程序
;SHUJU=1 OK, SHUJU=0 ERROR
;****************************************************
W18B20: SETB SHUJU
NOP
CLR SHUJU
MOV R0,#64H ; 主机发出延时600微秒的复位低脉冲
MOV R1,#03H
W11: DJNZ R0,$
MOV R0,#64H
DJNZ R1,W11
SETB SHUJU ; 然后拉高数据线
NOP
MOV R0,#25H
WW2: JNB SHUJU,WW3 ; 等待DS18B20回应
DJNZ R0,WW2
JMP WW4 ; 延时
WW3: SETB 20H.1 ; 置标志位,表示DS1820存在
JMP WW5
WW4: CLR 20H.1 ; 清标志位,表示DS1820不存在
JMP WW6
WW5: MOV R0,#064H
DJNZ R0,$ ; 时序要求延时一段时间
WW6: SETB SHUJU
JNB 20H.1,AAAA ;DS18B20出错
RET
;==============================================================
;DS18B20错误时LCD显示子程序
;==============================================================
AAAA: MOV DPTR,#M_ERROR1 ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#80H ;第一行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
MOV DPTR,#M_ERROR2 ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#90H ;第二行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
MOV DPTR,#M_ERROR3 ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#88H ;第三行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
MOV DPTR,#M_ERROR4 ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#98H ;第四行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
LCALL MING1
RET
;--------------------------------------------------------------
; 读18B20温度
;***********************************************************
DU18B20:
MOV A,#0CCH ;
LCALL XIEB20
MOV A,#44H ;发出温度转换命令
LCALL XIEB20 ;
LCALL W18B20 ;
MOV A,#0CCH ;
LCALL XIEB20 ;写18B20指令
MOV A,#0BEH ;发出读温度命令
LCALL XIEB20 ;
LCALL WDSJ ;温度数据
RET
;===========================================================
;写入18B20指令
;===========================================================
XIEB20: MOV R2,#8 ;一共8位数据
CLR CY
XIE: CLR SHUJU ;开始写入DS18B20总线要处于复位(低)状态
MOV R3,#09
DJNZ R3,$ ;总线复位保持18微妙以上
RRC A ;把一个字节DATA 分成8个BIT环移给C
MOV SHUJU,C ;写入一个BIT
MOV R3,#23
DJNZ R3,$ ;等待46微妙
SETB SHUJU ;重新释放总线
NOP
DJNZ R2,XIE ;写入下一个BIT
SETB SHUJU
RET
;******************************************************
;读温度子程序
;从DS18B20中读出温度低位、高位,
;存入33H,34H,35H,36H
;****************************************************
WDSJ: MOV R4,#04H
MOV R1,#WENDUD ; 存入33H,34H
RE00: MOV R2,#8
RE01: CLR C
SETB SHUJU
NOP
NOP
CLR SHUJU ;读前总线保持为低
NOP
NOP
NOP
SETB SHUJU ;开始读总线释放
MOV R3,#07 ;延时15微妙
DJNZ R3,$
MOV C,SHUJU ;从DS18B20总线读得一个BIT
MOV R3,#23
DJNZ R3,$ ;等待46微妙
RRC A ;把读得的位值环移给A
DJNZ R2,RE01 ;读下一个BIT
MOV @R1,A
INC R1
DJNZ R4,RE00
LCALL WDCZ
RET
;==============================================================
;处理入水口实际水温度 BCD 码子程序(未考虑百位和负温度值)
;整数部分:取出 WENDUD 高四位和 WENDUG 低四位进行重新组合
;小数部分:取出 TEMPL1 低四位,查小数码表
;小数部分:73H;个位:74H;十位:75H
;==============================================================
WDCZ:
MOV A,WENDUD
ANL A,#0FH ;取出小数部分
MOV B,#10 ;将TEMP_L的低四位X10/16得小数后一位数.
MUL AB
MOV B,#16
DIV AB
MOV 73H,A ;小数部分 BCD
MOV A,WENDUD ;整数部分
ANL A,#0F0H ;取出高四位
SWAP A
MOV WENDUD,A
MOV A,WENDUG ;取出低四位
ANL A,#0FH
SWAP A
ORL A,WENDUD ;重新组合温度数据
MOV WENDU,A ;重新组合的温度数据存入WENDU
LCALL HEX2BCD1
MOV WENDUD,A ;(A)=十位数和个位数
ANL A,#0F0H
SWAP A
MOV 75H,A ;十位数 BCD
MOV A,WENDUD
ANL A,#0FH
MOV 74H,A ;个位数 BCD
RET
;==============================================================
;单字节十六进制转BCD
;入口:(A)=单字节十六进制的温度值
;出口:(A)=十位数和个位数
;==============================================================
HEX2BCD1:
MOV B,#0AH
DIV AB
SWAP A
ORL A,B ;(A)=个位数和十位数
RET
;**********************************************************
;**********************送显示******************************
;**********************************************************
S18B20:
MOV DPTR,#M_OK2 ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#80H ;第一行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
LCALL SHOW_D ;显示设定的恒温水温度值
MOV DPTR,#M_OK1 ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#90H ;第二行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
LCALL SHOW_G ;显示设定的恒温水温度值
MOV DPTR,#M_OK3 ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#88H ;第三行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
LCALL SHOW_S ;显示实际温度值
MOV DPTR,#M_OK4 ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#98H ;第四行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
RET
;==============================================================
;显示恒温水温度值子程序
;==============================================================
SHOW_G: MOV A,#86H ;设置显示位置
LCALL SEND_I
MOV A,SDWDG
MOV B,#0AH
DIV AB
ADD A,#30H ;十位数转换为 ASCII 码
LCALL SEND_D ;送显示
MOV A,B ;个位数
ADD A,#30H ;个位数转换为 ASCII 码
LCALL SEND_D ;送显示 ;显示恒温水温度值子程序
MOV A,#87H ;设置显示位置
LCALL SEND_I
MOV A,#0A1H ;显示温度标记℃
LCALL SEND_D
MOV A,#0E6H
LCALL SEND_D
SHOW_D: MOV A,#96H ;设置显示位置
LCALL SEND_I
MOV A,SDWDD
MOV B,#0AH
DIV AB
ADD A,#30H ;十位数转换为 ASCII 码
LCALL SEND_D ;送显示
MOV A,B ;个位数
ADD A,#30H ;个位数转换为 ASCII 码
LCALL SEND_D ;送显示 ;显示恒温水温度值子程序
MOV A,#97H ;设置显示位置
LCALL SEND_I
MOV A,#0A1H ;显示温度标记℃
LCALL SEND_D
MOV A,#0E6H
LCALL SEND_D
RET
;==============================================================
; LCD12864 显示实际温度值子程序
;==============================================================
SHOW_S: MOV A,#8DH ;设置显示位置
LCALL SEND_I
MOV A,75H ;加载十位数据
CJNE A,#00H,CONV2
CONV1: MOV A,#" " ;十位数等于0显示空格
LCALL SEND_D ;送显示
JMP CONV3
CONV2: ADD A,#30H ;十位数转换成ASCII码
LCALL SEND_D ;显示数据
CONV3: MOV A,74H ;个位
ADD A,#30H ;个位数转换成ASCII码
CALL SEND_D ;送显示
MOV A,#'.'
CALL SEND_D ;送显示
MOV A,73H ;加载小数位
ADD A,#30H ;小数位转换成ASCII码
CALL SEND_D ;送显示
MOV A,#8FH ;显示温度标记℃
CALL SEND_I
MOV A,#0A1H
CALL SEND_D
MOV A,#0E6H
CALL SEND_D
RET
;==============================================================
;取数子程序
;==============================================================
QUSHU: CLR A
MOVC A,@A+DPTR ;查表取数据
LCALL SEND_D ;送显示
INC DPTR
DJNZ COUNT,QUSHU
RET
;==============================================================
;写数据子程序
;RS=1,RW=0,E=高脉冲,D0-D7=数据
;==============================================================
SEND_D: LCALL CHK_BUSY ;写数据子程序
SETB RS
CLR RW
MOV P0,A
SETB E
NOP
NOP
CLR E
RET
;--------------------------------------------------------------
MING1: SETB P3.7
LCALL YS
CLR P3.7
RET
YS: MOV R5,#8FH
YS1: MOV R6,#0FFH
YS2: DJNZ R6,$
DJNZ R5,YS1
RET
;************************按键程序***********************
ANJIAN: JB K3,ANJIAN_0 ;按键K3确定修改
LCALL YS ;防抖动
JB K3,ANJIAN_0
LCALL MING1
LCALL BBBB
JNB K3,$
ANJI_1: JB K2,JIAN_2 ;按键K2设定值加1
LCALL YS ;防抖动
JB K2,JIAN_2
LCALL MING1
MOV A,SDWDG
INC A
MOV SDWDG,A
CLR C
CJNE A,#63H,JIAN_01
JMP JIAN_02
JIAN_01:JC JIAN_02
MOV SDWDG,#00H
JIAN_02:
LCALL BBBB
JNB K2,$
JIAN_2: JB K1,ANJI_3 ;按键K1设定值减1
LCALL YS ;防抖动
JB K1,ANJI_3
LCALL MING1
MOV A,SDWDG
DEC A
MOV SDWDG,A
CLR C
CJNE A,#63H,JIAN_21
JIAN_21:JC JIAN_22
MOV SDWDG,#63H
JIAN_22:JNB K1,$
LCALL BBBB
ANJI_3: JB K3,ANJI_1 ;按键K3确定退出
LCALL YS ;防抖动
JB K3,ANJI_1
LCALL MING1
LCALL CCCC
JNB K3,$
LJMP ANJI_4
ANJIAN_0:LJMP ANJIAN_9
ANJI_4: JB K2,JIAN_5 ;按键K2设定值加1
LCALL YS ;防抖动
JB K2,JIAN_5
LCALL MING1
MOV A,SDWDD
INC A
MOV SDWDD,A
CLR C
CJNE A,#63H,JIAN_31
JMP JIAN_32
JIAN_31:JC JIAN_32
MOV SDWDD,#00H
JIAN_32:LCALL CCCC
JNB K2,$
JIAN_5: JB K1,ANJI_6 ;按键K1设定值减1
LCALL YS ;防抖动
JB K1,ANJI_6
LCALL MING1
MOV A,SDWDD
DEC A
MOV SDWDD,A
CLR C
CJNE A,#63H,JIAN_41
JIAN_41:JC JIAN_42
MOV SDWDD,#63H
JIAN_42:JNB K1,$
LCALL CCCC
ANJI_6: JB K3,ANJI_4 ;按键K3确定退出
LCALL YS ;防抖动
JB K3,ANJI_4
LCALL MING1
JNB K3,$
ANJIAN_9:LCALL CUN
RET
;==============================================================
;重新对 DS18B20 初始化
;将设定的温度报警值写入 DS18B20
;==============================================================
CUN: LCALL W18b20
MOV A,#0CCH ;跳过ROM匹配
LCALL XIEB20
MOV A,#4EH ;写暂存寄存器
LCALL XIEB20
MOV A,SDWDG
LCALL XIEB20
MOV A,SDWDD
LCALL XIEB20
; MOV A,#7FH ;12位精确度
; LCALL XIEB20
LCALL W18B20 ;把 DS18B20 暂存器里的温度报警值拷贝到EEROM
MOV A,#0CCH ;跳过ROM匹配
LCALL XIEB20
MOV A,#48H ;把暂存器里的温度报警值拷贝到EEROM
LCALL XIEB20
RET
;--------------------------------------------------------------
show_g1:MOV A,#93H ;设置显示位置
LCALL SEND_I
MOV A,SDWDG
MOV B,#0AH
DIV AB
ADD A,#30H ;十位数转换为 ASCII 码
LCALL SEND_D ;送显示
MOV A,B ;个位数
ADD A,#30H ;个位数转换为 ASCII 码
LCALL SEND_D ;送显示 ;显示恒温水温度值子程序
MOV A,#94H ;设置显示位置
LCALL SEND_I
MOV A,#0A1H ;显示温度标记℃
LCALL SEND_D
MOV A,#0E6H
LCALL SEND_D
RET
BBBB:
MOV DPTR,#M_ERRORA ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#80H ;第一行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
MOV DPTR,#M_ERRORB ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#90H ;第二行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
lcall show_g1
LJMP DDDD
CCCC:
MOV DPTR,#M_ERRORC ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#80H ;第一行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
MOV DPTR,#M_ERRORD ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#90H ;第二行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
lcall show_d
DDDD: MOV DPTR,#M_ERROR3 ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#88H ;第三行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
MOV DPTR,#M_ERROR4 ;指针指到显示信息区
MOV COUNT,#10H ;地址计数器设为16
MOV A,#98H ;第四行起始地址
LCALL SEND_I ;调用写指令子程序
LCALL QUSHU
RET
;--------------------------------------------------------------
M_OK1: DB '设定低温度: ' ;显示在第一行
M_OK2: DB '设定高温度: ' ;显示在第二行
M_OK3: DB '实际温度: ' ;显示在第三行
M_OK4: DB ' QQ:80908900 ' ;显示在第四行
M_ERRORA: DB ' 设定高温度! ' ;显示在第一行
M_ERRORB: DB ' ' ;显示在第二行
M_ERRORC: DB ' 设定低温度! ' ;显示在第一行
M_ERRORD: DB ' ' ;显示在第二行
M_ERROR1: DB ' 温度探头错误!' ;显示在第一行
M_ERROR2: DB ' 请检查! ' ;显示在第二行
M_ERROR3: DB ' 风也有情 ' ;显示在第三行
M_ERROR4: DB ' QQ:80908900 ' ;显示在第四行
;*************************************************************
END
这是我的51通信,希望对你有用。 |