标题:
多功能检测仪程序(4路温度控制)
[打印本页]
作者:
daniu
时间:
2014-12-26 23:39
标题:
多功能检测仪程序(4路温度控制)
;*******************************************************************
;*温度控制程序,在LCD屏幕上显示4路温度(车内外温度、水温、油温)
;分两页显示,每页显示2路温度,温度传感器开路时语音报警和显示故障
;水温、油温超温报警
;*LCD12864显示,晶振11.0592M
;*******************************************************************
;-----------------------------------------------------------
;以下参数可以修改
;-----------------------------------------------------------
XSYSSJ DATA 40 ;显示延时时间
XSGZSJ DATA 40 ;故障显示延时时间
CNBJCS DATA 2 ;车内温度传感器出故障报警次数
CWBJCS DATA 2 ;车外温度传感器出故障报警次数
SWBJCS DATA 2 ;水温传感器故出障报警次数
YWBJCS DATA 2 ;油温度传感器出故障报警次数
SWGWSD DATA 50 ;水温超高报警值(单位℃)
SWDWSD DATA 23 ;水温超低报警值(单位℃)
YWGWSD DATA 40 ;油温超高报警值(单位℃)
YWDWSD DATA 25 ;油温超低报警值(单位℃)
;-----------------------------------------------------------
;以下参数不宜修改
;-----------------------------------------------------------
FLAG0 BIT 20H.0 ;车内温度传感器标志
FLAG1 BIT 20H.1 ;车外温度传感器标志
FLAG2 BIT 20H.2 ;水温传感器标志
FLAG3 BIT 20H.3 ;油温传感器标志
FLAG4 BIT 20H.4 ;车内温度传感器故障标志位,1为故障0为正常
FLAG5 BIT 20H.5 ;车外温度传感器故障标志位,1为故障0为正常
FLAG6 BIT 20H.6 ;水温传感器故障标志位,1为故障0为正常
FLAG7 BIT 20H.7 ;油温传感器故障标志位,1为故障0为正常
FLAH0 BIT 21H.0 ;温度正负标志,1为负0为正,正不显示
FLAH1 BIT 21H.1 ;水温过高标志,1为过高
FLAH2 BIT 21H.2 ;油温过高标志,1为过高
;-----------------------------------------------------------
XSYS DATA 22H ;显示延时时间存放单元
LCD_X EQU 23H ;LCD 地址变量
TEMP_ZH DATA 24H ;实时温度值存放单元
TEMPL DATA 25H ;温度低位值存放单元
TEMPH DATA 26H ;温度高位值存放单元
TEMP_TH DATA 27H ;高温报警值存放单元
TEMP_TL DATA 28H ;低温报警值存放单元
YY_DAT DATA 29H ;语音地址存放单元
CNBJ DATA 2AH ;车内温度传感器故障报警次数存放单元
CWBJ DATA 2BH ;车外温度传感器故障报警次数存放单元
SWBJ DATA 2CH ;水温传感器故障报警次数存放单元
YWBJ DATA 2DH ;油温传感器故障报警次数存放单元
YYDAT DATA 2EH ;语音发码值暂存地址
;-----------------------------------------------------------
CNCGBJ DATA 30 ;“车内温度传感器出故障,请检查”语音地址
CWCGBJ DATA 31 ;“车外温度传感器出故障,请检查”语音地址
SWCGBJ DATA 32 ;“水温传感器出故障,请检查”语音地址
YWCGBJ DATA 33 ;“油温传感器出故障,请检查”语音地址
;-----------------------------------------------------------
;以下参数是固定的,不要修改
;-----------------------------------------------------------
YYRST EQU P3.3 ;语音模块复位信号引脚
BUSY EQU P1.0 ;语音忙控制端,0为正在播放1为没有播放
YYSDA EQU P1.1 ;语音模块数据引脚
CG_CHENEI EQU P1.4 ;车内温度传感器数据线
CG_CHEWAI EQU P1.5 ;车外温度传感器数据线
CG_SHUIWE EQU P1.6 ;水温传感器数据线
CG_YOUWEN EQU P1.7 ;油温传感器数据线
;-----------------------------------------------------------
LCD_RS EQU P4.0 ;LCD 数据/命令选择端
LCD_RW EQU P4.1 ;LCD 读/写选择端
LCD_EN EQU P4.2 ;LCD 使能信号
LCD_BG EQU P4.3 ;LCD 背光控制端
LCD_SJ EQU P0 ;LCD 数据
;===========================================================
ORG 0000H
AJMP MAIN
ORG 0100H
;===========================================================
MAIN: MOV SP,#60H
MOV A,#00H
MOV R0,#20H ;将 20H-2FH 单元清零
MOV R1,#10H
CLEAR: MOV @R0,A
INC R0
DJNZ R1,CLEAR
CLR LCD_BG ;打开LCD背光
CALL SET_LCD ;初始化 LCD
MOV CNBJ,#CNBJCS ;设置车内温度传感器故障报警次数
MOV CWBJ,#CWBJCS ;设置车外温度传感器故障报警次数
MOV SWBJ,#SWBJCS ;设置水温传感器故障报警次数
MOV YWBJ,#YWBJCS ;设置油温传感器故障报警次数
;LCALL TEMP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;##########################################################
;以下温度显示程序(车内外温度、水温、油温)
;-----------------------------------------------------------
;用到的资源:R0~R7,A、B、C,20H~2EH,P4,P3.3,P1.0,P1.4~P1.7
;-----------------------------------------------------------
;##########################################################
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;**************显示第一页温度(车内外温度)
TEMP: CALL MENU_OK1 ;显示温度菜单1
MOV TEMP_TH,#00H ;温度低位值存放单元
MOV TEMP_TL,#00H ;温度低位值存放单元
SETB FLAG0 ;开始读取车内温度传感器,设标志为1
CLR FLAG1
CLR FLAG2
CLR FLAG3
MOV XSYS,#XSYSSJ ;每页显示时间
;读取和显示车内温度
L1: CALL RESET ;18B20复位子程序
JB FLAG4,L2 ;检查车外温度传感器是否正常
CALL BJ1 ;调用报警程序
MOV XSYS,#XSGZSJ ;重新设每页显示时间
SJMP L3 ;传感器出故障不再显示该温度
L2: CALL READ_TEMP ;读出温度与报警数据
CALL CONVTEMP ;转换处理温度为BCD码
CALL CONV01 ;显示车内温度
L3: CLR FLAG0
SETB FLAG1
CLR FLAG2
CLR FLAG3
;读取和显示车外温度
CALL RESET ;18B20复位子程序
JB FLAG5,L4 ;检查车内温度传感器是否正常
CALL BJ2 ;调用报警程序
SJMP L5 ;传感器出故障不再显示该温度
L4: CALL READ_TEMP ;读出温度与报警数据
CALL CONVTEMP ;转换处理温度为BCD码
CALL CONV02 ;显示车外温度
L5: SETB FLAG0
CLR FLAG1
CLR FLAG2
CLR FLAG3
JB FLAG4,L71
JB FLAG5,L71
MOV R0,#XSGZSJ
L70: ACALL DELAY
DJNZ R0,L70
SJMP L6
L71: ACALL DELAY ;延时
DEC XSYS ;车内外温度显示页显示一段时间,以便观察
MOV A,XSYS
JZ L6
SJMP L1
;**************显示第二页温度(水温和油温)
L6: CALL MENU_OK2 ;显示温度菜单2
MOV XSYS,#XSYSSJ ;重新设每页显示时间
CLR FLAG0
CLR FLAG1
SETB FLAG2
CLR FLAG3
;读取和显示水温
L7: CALL RESET ;传感器复位子程序
JB FLAG6,L8 ;检查水温传感器是否正常
CALL BJ3 ;调用报警程序
SJMP L9
L8: CALL READ_TEMP ;读出温度与报警数据
CALL CONVTEMP ;转换处理温度为BCD码
CALL TEMP_COMP ;温度比较子程序
CALL CONV01 ;显示水温
L9: CLR FLAG0
CLR FLAG1
CLR FLAG2
SETB FLAG3
;读取和显示油温
CALL RESET ;传感器复位子程序
JB FLAG7,L10 ;检查油温传感器是否正常
CALL BJ4 ;调用报警程序
SJMP L11
L10: CALL READ_TEMP ;读出温度与报警数据
CALL CONVTEMP ;转换处理温度为BCD码
CALL TEMP_COMP ;温度比较子程序
CALL CONV02 ;显示油温
L11: CLR FLAG0
CLR FLAG1
SETB FLAG2
CLR FLAG3
JB FLAG6,L81
JB FLAG7,L81
MOV R0,#XSGZSJ
L80: ACALL DELAY
DJNZ R0,L80
SJMP L82
L81: ACALL DELAY
DEC XSYS ;水温、油温显示页显示一段时间,以便观察
MOV A,XSYS
JZ L82
AJMP L7
L82: AJMP MAIN
RET
;------------------------------------------------------
;报警程序,传感器故障声音报警和LCD显示
;------------------------------------------------------
BJ1: MOV A,CNBJ ;车内温度故障报警和显示
JZ L13 ;声音报警N次后不再报警,只显示故障
MOV YY_DAT,#CNCGBJ;报出“车内温度传感器出故障,请检查”
JNB BUSY,L13 ;如果正在播放语音则跳过,只显示故障
DEC CNBJ ;车内温度传感器语音报警次数倒计数
SJMP L12 ;故障语音报警
BJ2: MOV A,CWBJ ;车外温度故障报警和显示
JZ L15 ;声音报警N次后不再报警,只显示故障
MOV YY_DAT,#CWCGBJ;报出“车外温度传感器出故障,请检查”
JNB BUSY,L15 ;如果正在播放语音则跳过,只显示故障
DEC CWBJ ;车外温度传感器语音报警次数倒计数
SJMP L14 ;故障显示
BJ3: MOV A,SWBJ ;水温故障报警和显示
JZ L13 ;声音报警N次后不再报警,只显示故障
MOV YY_DAT,#SWCGBJ;报出“水温传感器出故障,请检查”
JNB BUSY,L13 ;如果正在播放语音则跳过,只显示故障
DEC SWBJ ;水温传感器语音报警次数倒计数
L12: ACALL YUYIN ;语音播放
L13: MOV A,#90H ;显示在第二行
SJMP L16 ;故障显示
BJ4: MOV A,YWBJ ;油温故障报警和显示
JZ L15 ;声音报警N次后不再报警,只显示故障
MOV YY_DAT,#YWCGBJ;报出“油温传感器出故障,请检查”
JNB BUSY,L15 ;如果正在播放语音则跳过,只显示故障
DEC YWBJ ;油温传感器语音报警次数倒计数
L14: ACALL YUYIN ;语音播放
L15: MOV A,#98H ;显示在第四行
L16: MOV DPTR,#MUNE1 ;指针指到显示信息区
CALL WCOM
L203: CLR A ;填入字符
MOVC A,@A+DPTR ;由信息区取出字符
CJNE A,#0,L205 ;判断是否为结束码
RET
L205: CALL WDATA ;写入数据
INC DPTR ;指针加1
JMP L203 ;继续填入字符
MUNE1: DB"探头故障请检查!",0 ;温度探头不正常报警程序
;--------------------------------------------------------------------
;传感器读温度子程序
; 将温度低位、高位、TH、TL从传感器中读出
; 分别存入 25H、26H、27H、28H 单元中
;--------------------------------------------------------------------
READ_TEMP:MOV A,#0CCH ; 跳过ROM匹配
CALL WRITE
MOV A,#44H ; 发出温度转换命令
CALL WRITE
CALL RESET
MOV A,#0CCH ; 跳过ROM匹配
CALL WRITE
MOV A,#0BEH ; 发出读温度命令
CALL WRITE ;先写入命令
MOV R4,#4 ;存入4个单元中
MOV R1,#TEMPL ;存入单元的首地址送入 R1
RE00: MOV R2,#8 ;8位数据长度
RE01: CLR CY
;***********************
JNB FLAG0,L01
SETB CG_CHENEI
NOP
NOP
CLR CG_CHENEI ;读前总线保持为低
NOP
NOP
NOP
SETB CG_CHENEI ;开始读总线释放
MOV R3,#07 ;延时15微妙
DJNZ R3,$
MOV C,CG_CHENEI ;从传感器总线读得一个BIT
AJMP L5A
L01: JNB FLAG1,L02
SETB CG_CHEWAI
NOP
NOP
CLR CG_CHEWAI ;读前总线保持为低
NOP
NOP
NOP
SETB CG_CHEWAI ;开始读总线释放
MOV R3,#07 ;延时15微妙
DJNZ R3,$
MOV C,CG_CHEWAI ;从传感器总线读得一个BIT
AJMP L5A
L02: JNB FLAG2,L03
SETB CG_SHUIWE
NOP
NOP
CLR CG_SHUIWE ;读前总线保持为低
NOP
NOP
NOP
SETB CG_SHUIWE ;开始读总线释放
MOV R3,#07 ;延时15微妙
DJNZ R3,$
MOV C,CG_SHUIWE ;从传感器总线读得一个BIT
L0: AJMP L5A
L03: JNB FLAG3,L0
SETB CG_YOUWEN
NOP
NOP
CLR CG_YOUWEN ;读前总线保持为低
NOP
NOP
NOP
SETB CG_YOUWEN ;开始读总线释放
MOV R3,#07 ;延时15微妙
DJNZ R3,$
MOV C,CG_YOUWEN ;从传感器总线读得一个BIT
;*****************************
L5A: MOV R3,#3CH
DJNZ R3,$ ;等待100微妙
RRC A ;把读得的位值环移给A
DJNZ R2,RE01 ;读下一个BIT
MOV @R1,A
INC R1
DJNZ R4,RE00 ;没有读完,继续
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; JB FLAG0,L000
; PUSH A
; MOV A,#WENDSD
; CLR C
; SUBB A,TEMPL ;减数>被减数,则
; JC L00
; SETB FLAH3
;L00: POP A
L000: RET
;*****************************************************
;处理温度 BCD 码子程序
;整数部分:取出 TEMPL 高四位和 TEMPH 低四位进行重新组合
;小数部分:取出 TEMPL 低四位,查小数码表
;****************************************************
CONVTEMP:MOV A,TEMPH ;判温度是否零下
ANL A,#80H
JZ TEMPC1 ;温度零上转
SETB FLAH0 ;温度为负值
CLR C
MOV A,TEMPL ;二进制数求补(双字节)
CPL A ;取反加1
ADD A,#01H
MOV TEMPL,A
MOV A,TEMPH
CPL A
ADDC A,#00H
MOV TEMPH,A
JMP TEMPC2
TEMPC1: CLR FLAH0 ;温度为正值
TEMPC2: MOV A,TEMPL
ANL A,#0FH ;取出小数部分
MOV B,#10 ;将TEMP_L的低四位X10/16得小数后一位数.
MUL AB
MOV B,#16
DIV AB
MOV 70H,A ;小数部分 BCD
MOV A,TEMPL ;整数部分
ANL A,#0F0H ;取出高四位
SWAP A
MOV TEMPL,A
MOV A,TEMPH ;取出低四位
ANL A,#0FH
SWAP A
ORL A,TEMPL ;重新组合温度数据
MOV TEMP_ZH,A ;重新组合的温度数据存入TEMP_ZH
LCALL HEX2BCD1
MOV TEMPL,A ;(A)=十位数和个位数
ANL A,#0F0H
SWAP A
MOV 72H,A ;十位数 BCD
MOV A,TEMPL
ANL A,#0FH
MOV 71H,A ;个位数 BCD
MOV A,R4 ;(R4)= 百位数
MOV 73H,A
TEMPC3: RET
;====================================================
;单字节十六进制转BCD
;入口:(A)=单字节十六进制的温度值
;出口:(R4)= 百位数,(A)=十位数和个位数
;====================================================
HEX2BCD1:MOV B,#64H
DIV AB
MOV R4,A ;(R4)=百位数
MOV A,#0AH
XCH A,B
DIV AB
SWAP A
ORL A,B ;(A)=十位数和个位数
RET
;==========================================================
; LCD 温度值显示子程序
;73H-70H 分别存放百位、十位、个位、小数位的数据
;==========================================================
CONV01: MOV A,73H ;加载百位数据
MOV LCD_X,#1 ;设置显示位置
JNB FLAH0,CONV0 ;
MOV A,#"-" ;显示"-"
MOV B,LCD_X
CALL LCDP2
MOV A,72H ;十位
CJNE A,#00H,CONV3
INC LCD_X ;调整显示地址
MOV A,#" " ;十位数等于0显示空格
MOV B,LCD_X
CALL LCDP2
JMP CONV4
CONV0: CJNE A,#00H,CONV2
CONV1: MOV A,#" " ;百位数等于0显示空格
MOV B,LCD_X
CALL LCDP2
MOV A,72H ;十位
CJNE A,#00H,CONV3
INC LCD_X ;调整显示地址
MOV A,#" " ;十位数等于0显示空格
MOV B,LCD_X
CALL LCDP2
JMP CONV4
CONV2: CALL SHOW_DIG2 ;显示数据
CONV3: INC LCD_X ;调整显示地址
MOV A,72H ;十位
CALL SHOW_DIG2
CONV4: INC LCD_X ;调整显示地址
MOV A,71H ;个位
CALL SHOW_DIG2
INC LCD_X ;调整显示地址
MOV A,#'.'
MOV B,LCD_X
CALL LCDP2
MOV A,70H ;加载小数位
INC LCD_X ;设置位置
CALL SHOW_DIG2 ;显示数据
RET
;=============================================
;在LCD的第二行显示数据字符
;A=ASCII 数据, B=位置变量
;==============================================
LCDP2: PUSH ACC ;在LCD的第二行显示字符
MOV A,B ;设置显示地址
ADD A,#90H ;设置LCD的第二行地址
CALL WCOM ;写入命令
POP ACC ;由堆栈取出A
CALL WDATA ;写入数据
RET
;-------------------------------------------------------
SHOW_DIG2: ;在 LCD 的第二行显示数字
ADD A,#30H ;加30H,转换为ASCII码
MOV B,LCD_X ;确定显示位置
CALL LCDP2 ;送显示
RET
;*************************************************************************
;==========================================================
; LCD 温度值显示子程序2,显示在第四行
;73H-70H 分别存放百位、十位、个位、小数位的数据
;==========================================================
CONV02: MOV A,73H ;加载百位数据
MOV LCD_X,#1 ;设置显示位置
JNB FLAH0,CONV10 ;
MOV A,#"-" ;显示"-"
MOV B,LCD_X
CALL LCDP4
MOV A,72H ;十位
CJNE A,#00H,CONV13
INC LCD_X ;调整显示地址
MOV A,#" " ;十位数等于0显示空格
MOV B,LCD_X
CALL LCDP4
JMP CONV14
CONV10: CJNE A,#00H,CONV12
CONV11: MOV A,#" " ;百位数等于0显示空格
MOV B,LCD_X
CALL LCDP4
MOV A,72H ;十位
CJNE A,#00H,CONV13
INC LCD_X ;调整显示地址
MOV A,#" " ;十位数等于0显示空格
MOV B,LCD_X
CALL LCDP4
JMP CONV14
CONV12: CALL SHOW_DIG4 ;显示数据
CONV13: INC LCD_X ;调整显示地址
MOV A,72H ;十位
CALL SHOW_DIG4
CONV14: INC LCD_X ;调整显示地址
MOV A,71H ;个位
CALL SHOW_DIG4
INC LCD_X ;调整显示地址
MOV A,#'.'
MOV B,LCD_X
CALL LCDP4
MOV A,70H ;加载小数位
INC LCD_X ;设置位置
CALL SHOW_DIG4 ;显示数据
RET
;=============================================
;在LCD的第二行显示数据字符
;A=ASCII 数据, B=位置变量
;==============================================
LCDP4: PUSH ACC ;在LCD的第二行显示字符
MOV A,B ;设置显示地址
ADD A,#98H ;设置LCD的第二行地址
CALL WCOM ;写入命令
POP ACC ;由堆栈取出A
CALL WDATA ;写入数据
RET
;-------------------------------------------------------
SHOW_DIG4: ;在 LCD 的第二行显示数字
ADD A,#30H ;加30H,转换为ASCII码
MOV B,LCD_X ;确定显示位置
CALL LCDP4 ;送显示
RET
;*************************************************************************
;------------------------------------------------------------------
;传感器 写命令、数据子程序
;根据命令的内容,进行写操作
;------------------------------------------------------------------
WRITE: MOV R2,#8 ;8位数据长度
CLR C
WR1: JNB FLAG0,L21
CLR CG_CHENEI ;开始写入传感器总线要处于复位(低)状态
MOV R3,#08
DJNZ R3,$ ;总线复位保持16微妙以上
RRC A ;把一个字节DATA 分成8个BIT环移给C
MOV CG_CHENEI,C ;写入一个BIT
MOV R3,#3CH
DJNZ R3,$ ;等待120微妙
SETB CG_CHENEI ;重新释放总线
NOP
DJNZ R2,WR1 ;写入下一个BIT
SETB CG_CHENEI
RET
L21: JNB FLAG1,L22
CLR CG_CHEWAI ;开始写入传感器总线要处于复位(低)状态
MOV R3,#08
DJNZ R3,$ ;总线复位保持16微妙以上
RRC A ;把一个字节DATA 分成8个BIT环移给C
MOV CG_CHEWAI,C ;写入一个BIT
MOV R3,#3CH
DJNZ R3,$ ;等待120微妙
SETB CG_CHEWAI ;重新释放总线
NOP
DJNZ R2,WR1 ;写入下一个BIT
SETB CG_CHEWAI
RET
L22: JNB FLAG2,L23
CLR CG_SHUIWE ;开始写入传感器总线要处于复位(低)状态
MOV R3,#08
DJNZ R3,$ ;总线复位保持16微妙以上
RRC A ;把一个字节DATA 分成8个BIT环移给C
MOV CG_SHUIWE,C ;写入一个BIT
MOV R3,#3CH
DJNZ R3,$ ;等待120微妙
SETB CG_SHUIWE ;重新释放总线
NOP
DJNZ R2,WR1 ;写入下一个BIT
SETB CG_SHUIWE
RET
L23: JNB FLAG3,L24
CLR CG_YOUWEN ;开始写入传感器总线要处于复位(低)状态
MOV R3,#08
DJNZ R3,$ ;总线复位保持16微妙以上
RRC A ;把一个字节DATA 分成8个BIT环移给C
MOV CG_YOUWEN,C ;写入一个BIT
MOV R3,#3CH
DJNZ R3,$ ;等待120微妙
SETB CG_YOUWEN ;重新释放总线
NOP
DJNZ R2,WR1 ;写入下一个BIT
SETB CG_YOUWEN
L24: RET
;=================================================
MENU_OK1: MOV DPTR,#M_OK11 ;指针指到显示信息区
MOV A,#1 ;显示在第一行
CALL LCD_PRINT
MOV DPTR,#M_OK12 ;指针指到显示信息区
MOV A,#2 ;显示在第二行
CALL LCD_PRINT
MOV DPTR,#M_OK13 ;指针指到显示信息区
MOV A,#3 ;显示在第二行
CALL LCD_PRINT
MOV DPTR,#M_OK14 ;指针指到显示信息区
MOV A,#4 ;显示在第二行
CALL LCD_PRINT
RET
M_OK11: DB"车内温度: ",0
M_OK12: DB" ℃ ",0
M_OK13: DB"车外温度: ",0
M_OK14: DB" ℃ ",0
;=================================================
MENU_OK2: MOV DPTR,#M_OK21 ;指针指到显示信息区
MOV A,#1 ;显示在第一行
CALL LCD_PRINT
MOV DPTR,#M_OK22 ;指针指到显示信息区
MOV A,#2 ;显示在第二行
CALL LCD_PRINT
MOV DPTR,#M_OK23 ;指针指到显示信息区
MOV A,#3 ;显示在第二行
CALL LCD_PRINT
MOV DPTR,#M_OK24 ;指针指到显示信息区
MOV A,#4 ;显示在第二行
CALL LCD_PRINT
RET
M_OK21: DB"水温: ",0
M_OK22: DB" ℃ ",0
M_OK23: DB"油温: ",0
M_OK24: DB" ℃ ",0
;==================================================
;在LCD的第一行或第二行显示字符串
;DPTR = 放字符串的地址
;==================================================
LCD_PRINT:CJNE A,#1,LINE2 ;判断是否为第一行
LINE1: MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;写入命令
JMP FILL
LINE2: CJNE A,#2,LINE3 ;判断是否为第二行
MOV A,#90H ;设置 LCD 的第二行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#90H ;设置 LCD 的第二行地址
CALL WCOM
JMP FILL
LINE3: CJNE A,#3,LINE4 ;判断是否为第三行
MOV A,#88H ;设置 LCD 的第三行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#88H ;设置 LCD 的第三行地址
CALL WCOM
JMP FILL
LINE4: MOV A,#98H ;设置 LCD 的第四行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#98H ;设置 LCD 的第四行地址
CALL WCOM
FILL: CLR A ;填入字符
MOVC A,@A+DPTR ;由信息区取出字符
CJNE A,#0,LC1 ;判断是否为结束码
RET
LC1: CALL WDATA ;写入数据
INC DPTR ;指针加1
JMP FILL ;继续填入字符
;===============================================
;清除一行 LCD 的字符
;输入一行空格,来替代原显示字符
;===============================================
CLR_LINE: MOV R0,#24 ;清除该行 LCD 的字符
CL1: MOV A,#' '
CALL WDATA
DJNZ R0,CL1
RET
;====================================================
;传感器 复位与检测子程序
;传感器 正常 FLAG* 置 1,不正常 FLAG* 置 0。
;====================================================
RESET: JNB FLAG0,L31
SETB CG_CHENEI ;
NOP
CLR CG_CHENEI
MOV R0,#6BH ;主机发出延时复位低脉冲
MOV R1,#04H
TSR11: DJNZ R0,$ ;延时
MOV R0,#6BH
DJNZ R1,TSR11
SETB CG_CHENEI ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#32H
TSR21: JNB CG_CHENEI,TSR31 ;等待传感器回应
DJNZ R0,TSR21
JMP TSR41 ; 延时
TSR31: SETB FLAG4 ; 置标志位,表示DS1820存在
JMP TSR51
TSR41: CLR FLAG4 ; 清标志位,表示DS1820不存在
JMP TSR61
TSR51: MOV R0,#06BH
DJNZ R0,$ ; 时序要求延时一段时间
TSR61: SETB CG_CHENEI
RET
;------------------------
L31: JNB FLAG1,L32
SETB CG_CHEWAI ;
NOP
CLR CG_CHEWAI
MOV R0,#6BH ;主机发出延时复位低脉冲
MOV R1,#04H
TSR12: DJNZ R0,$ ;延时
MOV R0,#6BH
DJNZ R1,TSR12
SETB CG_CHEWAI ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#32H
TSR22: JNB CG_CHEWAI,TSR32 ;等待传感器回应
DJNZ R0,TSR22
JMP TSR42 ; 延时
TSR32: SETB FLAG5 ; 置标志位,表示DS1820存在
JMP TSR52
TSR42: CLR FLAG5 ; 清标志位,表示DS1820不存在
JMP TSR62
TSR52: MOV R0,#06BH
DJNZ R0,$ ; 时序要求延时一段时间
TSR62: SETB CG_CHEWAI
RET
;------------------------
L32: JNB FLAG2,L33
SETB CG_SHUIWE ;
NOP
CLR CG_SHUIWE
MOV R0,#6BH ;主机发出延时复位低脉冲
MOV R1,#04H
TSR13: DJNZ R0,$ ;延时
MOV R0,#6BH
DJNZ R1,TSR13
SETB CG_SHUIWE ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#32H
TSR23: JNB CG_SHUIWE,TSR33 ;等待传感器回应
DJNZ R0,TSR23
JMP TSR43 ; 延时
TSR33: SETB FLAG6 ; 置标志位,表示DS1820存在
JMP TSR53
TSR43: CLR FLAG6 ; 清标志位,表示DS1820不存在
JMP TSR63
TSR53: MOV R0,#06BH
DJNZ R0,$ ; 时序要求延时一段时间
TSR63: SETB CG_SHUIWE
RET
;------------------------
L33: JNB FLAG3,L34
SETB CG_YOUWEN ;
NOP
CLR CG_YOUWEN
MOV R0,#6BH ;主机发出延时复位低脉冲
MOV R1,#04H
TSR14: DJNZ R0,$ ;延时
MOV R0,#6BH
DJNZ R1,TSR14
SETB CG_YOUWEN ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#32H
TSR24: JNB CG_YOUWEN,TSR34 ;等待传感器回应
DJNZ R0,TSR24
JMP TSR44 ; 延时
TSR34: SETB FLAG7 ; 置标志位,表示DS1820存在
JMP TSR54
TSR44: CLR FLAG7 ; 清标志位,表示DS1820不存在
JMP TSR64
TSR54: MOV R0,#06BH
DJNZ R0,$ ; 时序要求延时一段时间
TSR64: SETB CG_YOUWEN
L34: RET
;------------------------
;==========================================================
;=================================================
;对 LCD 做初始化设置
;=================================================
SET_LCD: MOV A,#34H ;34H--扩充指令操作
CALL WCOM ;写入命令
MOV A,#30H ;30H--基本指令操作
CALL WCOM ;写入命令
MOV A,#01H ;清除显示
CALL WCOM ;写入命令
MOV A,#06H ;指定在资料写入或读取时,光标的移动方向
CALL WCOM ;DDRAM 的地址计数器(AC)加1
MOV A,#0CH ;开显示,关光标,不闪烁
CALL WCOM ;写入命令
RET
;==================================================
;===============================================
;命令写入子程序
;RS=L,RW=L,D0-D7=指令码,E=高脉冲
;以8位控制方式将命令写至LCD
;===============================================
WCOM: LCALL CHK_BUSY
CLR LCD_RS
CLR LCD_RW
MOV LCD_SJ,A
SETB LCD_EN
NOP
NOP
CLR LCD_EN
RET
;===============================================
;数据写入子程序
;RS=H,RW=L,D0-D7=指令码,E=高脉冲
;以8位控制方式将数据写至LCD
;===============================================
WDATA: MOV LCD_SJ,A ;写入数据
SETB LCD_RS
CLR LCD_RW
SETB LCD_EN
CALL DE
CLR LCD_EN
CALL DE
RET
;**********************************************************
;测忙碌子程序
;RS=0,RW=1,E=H,D0-D7=状态字
;**********************************************************
CHK_BUSY: MOV LCD_SJ,#0FFH ;测忙碌子程序
CLR LCD_RS
SETB LCD_RW
SETB LCD_EN
JB LCD_SJ.7,$
CLR LCD_EN
RET
;====================================================
;实时温度值与设定报警温度值 TH、TL 比较子程序
;当实际温度大于 TH 的设定值时,显示“过高”并闪动显示
;当实际温度小于 TH 的设定值时,显示“正常”
;当实际温度小于 TL 的设定值时,显示“过低”
;====================================================
TEMP_COMP:JNB FLAG2,L101
MOV TEMP_TH,#SWGWSD
MOV TEMP_TL,#SWDWSD ;设置 LCD 的第一行地址
SJMP L102
L101: JNB FLAG3,L103
MOV TEMP_TH,#YWGWSD
MOV TEMP_TL,#YWDWSD
L102: MOV A,TEMP_ZH
CJNE A,TEMP_TH,T_COMP0
T_COMP0: JNC CHULI1
MOV A,TEMP_ZH
SUBB A,TEMP_TL ;减数>被减数,则
JC CHULI2 ;借位标志位C=1,转
MOV DPTR,#BJ50 ;显示"正常"
CALL TEMP_BJ3
CLR FLAG1 ;清除报警标志
L103: RET
CHULI1: MOV DPTR,#BJ60 ;形成闪烁效果
CALL TEMP_BJ3
MOV R5,#10 ;延时10MS
ACALL DELAY1
MOV DPTR,#BJ30 ;显示"过高"
CALL TEMP_BJ3
SETB FLAG1 ;设置报警标志
RET
CHULI2: MOV DPTR,#BJ40 ;显示"过低"
CALL TEMP_BJ3
CLR FLAG1 ;清除报警标志
RET
;=========================================
;标记字符写入子程序
;=========================================
TEMP_BJ3: JNB FLAG2,L001
MOV A,#86H ;设置 LCD 的第一行地址
SJMP L002
L001: JNB FLAG3,L004
MOV A,#8EH ;设置 LCD 的第三行地址
L002: CALL WCOM
L003: CLR A ;填入字符
MOVC A,@A+DPTR ;由信息区取出字符
CJNE A,#0,L005 ;判断是否为结束码
L004: RET
L005: CALL WDATA ;写入数据
INC DPTR ;指针加1
JMP L003 ;继续填入字符
BJ30: DB "过高",0 ;过高标记
BJ40: DB "过低",0 ;正常标记
BJ50: DB "正常",0 ;过低标记
BJ60: DB " ",0 ;过低标记
;**********************************************************
;语音驱动和播放程序
;**********************************************************
;50H为语音段地址暂存器,1到210段,实际用到40
;50H为E0H~E7H时分别代表自低往高的8级音量
;在语音播放过程中发送F2H至50H可循环播放当前地址语音
;发送FEH至50H停止播放语音
;****************************************************
YUYIN: RET ;$$$$$$$$$$$$$
MOV TMOD,#00000001B ;定时/计数器0工作于方式1
MOV R6,#08H ;发码8位循环数据
LCALL ONE_LINE ;调用一线发码子程序
RET
ONE_LINE: ;////一线发码子程序
SETB YYRST ;复位
MOV R7,#2 ;延时2MS
LCALL DELAY1MS
CLR YYRST ;延时使系统稳定
MOV R7,#6 ;延时6MS
LCALL DELAY1MS
CLR YYSDA ;唤醒语音芯片
MOV R7,#17 ;延时17MS
LCALL DELAY1MS
MOV A,YY_DAT
LP1: SETB YYSDA
RRC A ;分辨50H内的数据各位是高电平还是低电平
JNC DIDIANPIN ;高电平用高:低=2:1的脉宽表示
LCALL DELAY200US
LCALL DELAY200US
LCALL DELAY200US
CLR YYSDA
LCALL DELAY200US
LP2: DJNZ R6,LP1 ;查看数据是否发完,未发完继续发
MOV R6,#08H
SETB YYSDA
RET
DIDIANPIN: ;低电平用高:低=1:2的脉宽表示
LCALL DELAY200US
CLR YYSDA
LCALL DELAY200US
LCALL DELAY200US
LCALL DELAY200US
SJMP LP2
;以下为延时子程序
DELAY200US: ;延时200US子程序,晶振11.0592MHz,方式1
MOV TH0,#0FFH
MOV TL0,#47H
SETB TR0
LOP1: JBC TF0,NEXT1
SJMP LOP1
NEXT1: CLR TR0
RET
DELAY1MS: ;延时1ms子程序
MOV TH0,#0FCH
MOV TL0,#66H
SETB TR0
LOP2: JBC TF0,NEXT2
SJMP LOP2
NEXT2: DJNZ R7,DELAY1MS
CLR TR0
RET
;**********************************************************
;延时子程序
;**********************************************************
DE: MOV R7,#250 ;延时 500 微秒
DJNZ R7,$
RET
;===============================================
DELAY: MOV R5,#20 ;延时20MS
DELAY1: MOV R6,#48 ;50
DL1: MOV R7,#96 ;100
DJNZ R7,$
DJNZ R6,DL1
DJNZ R5,DELAY1
RET ;96*2*48*(12/11.0592)+2*(12/11.0592)≈10000uS=10mS
END
复制代码
作者:
barons
时间:
2015-1-28 11:46
我测试下,感谢分享
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1