|
- LCD_X EQU 23H ;LCD 地址變量(決定文字的在LCD上的顯示位置)
- FSJCQ EQU 33H ;TMOD工作方式暫存寄存器
- BJZC EQU 34H ;需要比較數(shù)據(jù)暫存寄存器,用于報警顯示
- BJWX EQU 35H ;超標設(shè)定值暫存寄存器
- BJJG EQU 36H ;偏高設(shè)定值暫存寄存器
- JJCQ EQU 37H ;酒精顯示0%暫存寄存器
- YYBZ EQU 38H ;語音播放標志
- DJSJCQ EQU 39H ;10S倒計時寄存器
- JJCYCS EQU 4AH ;酒精檢測采樣次數(shù)寄存器
- XSYSSJ DATA 5 ;正常時顯示延時時間
- WXBJZ1 EQU 100 ;有害氣體危險報警設(shè)定值200PPM
- ;實際設(shè)定值=200(顯示設(shè)定值)/2(修正倍率)
- JGBJZ1 EQU 60 ;有害氣體警告報警設(shè)定值120PPM
- ;實際設(shè)定值=120(顯示設(shè)定值)/2(修正倍率)
- WXBJZ2 EQU 50 ;酒精危險報警設(shè)定值0.05% BAC
- ;實際設(shè)定值=0.05%(顯示設(shè)定值)*1000(顯示位修正)/1(修正倍率)
- JGBJZ2 EQU 20 ;酒精警告報警設(shè)定值0.02% BAC
- ;實際設(shè)定值=0.02%(顯示設(shè)定值)*1000(顯示位修正)/1(修正倍率)
- XIUZ1 EQU 10 ;有害氣體濃度顯示數(shù)據(jù)修正值,設(shè)置大時則顯示數(shù)值小,反之顯示大
- XIUZ2 EQU 34 ;酒精濃度顯示數(shù)據(jù)修正值,設(shè)置大時則顯示數(shù)值小,反之顯示大
- ;-----------------------------------------------------------
- LCD_RS EQU P4.0 ;LCD 數(shù)據(jù)/命令選擇端
- LCD_RW EQU P4.1 ;LCD 讀/寫選擇端
- LCD_EN EQU P4.2 ;LCD 使能信號
- LCD_BG EQU P4.3 ;LCD 背光控制端
- LCD_SJ EQU P0 ;LCD 數(shù)據(jù)
- BITE EQU 9 ;串口發(fā)送9位數(shù)據(jù)
- FSSZ EQU 40H ;主機發(fā)送的數(shù)據(jù)塊首址
- JSSZ EQU 50H ;主機接收的數(shù)據(jù)塊首址
- YY_DAT DATA 29H ;語音段地址存放單元
- YYRST EQU P3.3 ;語音模塊復(fù)位信號引腳
- BUSY EQU P1.0 ;語音忙控制端,0為正在播放1為沒有播放空閑時
- YYSDA EQU P1.1 ;語音模塊數(shù)據(jù)線引腳
- ;===========================================================
- ORG 0000H
- AJMP MAIN
- ORG 0003H ;外中斷0中斷程序入口
- RETI ;中斷返回
- ORG 000BH ;定時器T0中斷程序入口
- RETI ;中斷返回
- ORG 0013H ;外中斷1中斷入口
- RETI ;中斷返回
- ORG 001BH ;定時器T1中斷程序入口
- RETI ;跳至INTT1中斷服務(wù)程序
- ORG 0023H ;串口中斷入口地址
- RETI ;中斷返回
- ORG 0100H
- ;=========================================
- ;以下初始化程序
- ;=========================================
- MAIN: MOV SP,#60H
- CLR LCD_BG ;打開LCD背光
- LCALL SET_LCD ;初始化 LCD
- MOV R0,#20H ;將20H-7FH 單元清零
- MOV R1,#95
- CLEAR: MOV @R0,A
- INC R0
- DJNZ R1,CLEAR
- ;=========================================
- ;以下為主程序
- ;=========================================
- ;以下為有害氣體濃度顯示和報警程序
- YHJCCX: LCALL MENU_3 ;顯示菜單1
- MOV R2,#0AH ;與10號從機串口通信,多功能板地址為0AH
- MOV R3,#01H ;主機要求從機發(fā)送數(shù)據(jù)塊
- LCALL COM ;主機與多功能檢測板串口通信,要求其發(fā)送9個字節(jié)數(shù)據(jù)塊
- MOV A,JSSZ+1 ;取出傳感器檢測到的電壓讀數(shù)(原始數(shù)據(jù),16進制)
- MOV B,#2 ;顯示修正倍率,原始數(shù)*倍率+修正值=LCD顯示值
- SUBB A,#XIUZ1 ;顯示修正
- JNC LBB1 ;軟件調(diào)整初值
- MOV A,#0 ;使之正常時顯示0
- LBB1: LCALL HEX2BCD1 ;調(diào)用數(shù)值轉(zhuǎn)換程序
- LCALL CONV100 ;調(diào)用LCD顯示程序
- MOV BJZC,JSSZ+1 ;取出傳感器檢測到的電壓讀數(shù)(原始數(shù)據(jù)),做報警比較
- MOV BJWX,#WXBJZ1+XIUZ1 ;實際危險報警值=設(shè)定值/倍率+修正值
- MOV BJJG,#JGBJZ1+XIUZ1 ;實際警告報警值=設(shè)定值/倍率+修正值
- MOV YYBZ,#JSSZ+1 ;設(shè)有害氣體語音播放標志
- LCALL BJBJ1 ;調(diào)用報警程序
- JB P3.4,LBB5
- LCALL DELAY2
- JB P3.4,LBB5
- LCALL JJJCCX
- LBB5: LCALL DELAY3
- SJMP YHJCCX
- ;以下為酒精濃度顯示和報警程序
- JJJCCX: MOV JJCYCS,#5 ;設(shè)酒精檢測輪回采樣次數(shù)
- LCALL JIUJJC ;顯示準備進入酒精檢測程序的畫面
- JJJCCX1: MOV R2,#0AH ;與10號從機串口通信,多功能板地址為0AH
- MOV R3,#01H ;主機要求從機發(fā)送數(shù)據(jù)塊
- LCALL COM ;主機與多功能檢測板串口通信,要求其發(fā)送9個字節(jié)數(shù)據(jù)塊
- LCALL MENU_4 ;顯示菜單1
- MOV A,JSSZ+2 ;取出傳感器檢測到的電壓讀數(shù)(原始數(shù)據(jù),16進制)
- MOV B,#1 ;顯示修正倍率,原始數(shù)*倍率+修正值=LCD顯示值
- SUBB A,#XIUZ2 ;顯示修正
- JNC LBB2 ;軟件調(diào)整初值
- MOV A,#0 ;使之正常時顯示0%
- LBB2: LCALL HEX2BCD1 ;調(diào)用數(shù)值轉(zhuǎn)換程序
- LCALL CONV200 ;調(diào)用LCD顯示程序
- MOV BJZC,JSSZ+2 ;取出傳感器檢測到的電壓讀數(shù)(原始數(shù)據(jù)),做報警比較
- MOV BJWX,#WXBJZ2+XIUZ2 ;實際危險報警值=設(shè)定值/倍率+修正值
- MOV BJJG,#JGBJZ2+XIUZ2 ;實際警告報警值=設(shè)定值/倍率+修正值
- LCALL DELAY3 ;延時,使其能看清楚看到檢測到的數(shù)值
- DEC JJCYCS
- MOV A,JJCYCS
- JNZ JJJCCX1 ;連續(xù)采樣幾次(未到則返回)
- JNB BUSY,$ ;如果語言正在播放,則等待
- MOV YY_DAT,#6 ;報出“檢測完畢”
- LCALL YUYIN ;開始語音播放
- LCALL DELAY
- LCALL DELAY
- MOV YYBZ,#JSSZ+2 ;設(shè)酒精報警語音播放標志
- LCALL BJBJ1 ;調(diào)用報警程序
- LCALL DELAY3 ;延時
- RET
- ;***************************************************
- ;=========================================
- ;以下為兩個單字節(jié)十六進制相乘
- ;入口:A*B
- ;出口:16位低字節(jié)放A中,高字節(jié)放B中
- ;=========================================
- HEX2BCD1: MUL AB
- MOV R6,B
- MOV R7,A
- MOV JJCQ,A ;為顯示0%作準備
- ;=========================================
- ;以下為雙字節(jié)十六進制整數(shù)轉(zhuǎn)換成雙字節(jié)BCD碼整數(shù)
- ;入口條件:待轉(zhuǎn)換的雙字節(jié)十六進制整數(shù)在R6、R7中。
- ;出口信息:轉(zhuǎn)換后的三字節(jié)BCD碼整數(shù)在R3、R4、R5中。
- ;影響資源:PSW、A、R2~R7,堆棧需求:2字節(jié)
- ;=========================================
- CLR A ;BCD碼初始化
- MOV R3,A
- MOV R4,A
- MOV R5,A
- MOV R2,#10H ;轉(zhuǎn)換雙字節(jié)十六進制整數(shù)
- HB3: MOV A,R7 ;從高端移出待轉(zhuǎn)換數(shù)的一位到CY中
- RLC A
- MOV R7,A
- MOV A,R6
- RLC A
- MOV R6,A
- MOV A,R5 ;BCD碼帶進位自身相加,相當于乘2
- ADDC A,R5
- DA A ;十進制調(diào)整
- MOV R5,A
- MOV A,R4
- ADDC A,R4
- DA A
- MOV R4,A
- MOV A,R3
- ADDC A,R3
- MOV R3,A ;雙字節(jié)十六進制數(shù)的萬位數(shù)不超過6,不用調(diào)整
- DJNZ R2,HB3 ;處理完16bit
- ;=========================================
- ;以下為把BCD碼提取出并送顯示寄存器70H~73H
- ;入口:;三字節(jié)BCD碼整數(shù)在R3(高位為十萬低位為萬)、
- ;R4(高位為千低位為百)、R5(高位為十低位為個)中。
- ;出口:73H-70H(舍去十萬、萬位)
- ;=========================================
- MOV A,R4
- ANL A,#11110000B
- SWAP A
- MOV 73H,A
- MOV A,R4
- ANL A,#00001111B
- MOV 72H,A
- MOV A,R5
- ANL A,#11110000B
- SWAP A
- MOV 71H,A
- MOV A,R5
- ANL A,#00001111B
- MOV 70H,A
- RET
- ;==============================================
- ;以下為LCD顯示有害氣體程序
- ;72H-70H 分別存放百位、十位、個位的數(shù)據(jù)
- ;==============================================
- CONV100: MOV A,73H ;加載百位數(shù)據(jù)
- MOV LCD_X,#1 ;設(shè)置顯示位置
- CJNE A,#00H,CONV110
- MOV A,#" " ;百位數(shù)等于0顯示空格
- MOV B,LCD_X
- CALL LCDP2
- MOV A,72H ;十位
- CJNE A,#00H,CONV120
- INC LCD_X ;調(diào)整顯示地址
- MOV A,#" " ;十位數(shù)等于0顯示空格
- MOV B,LCD_X
- CALL LCDP2
- MOV A,71H ;十位
- CJNE A,#00H,CONV130
- INC LCD_X ;調(diào)整顯示地址
- MOV A,#" " ;十位數(shù)等于0顯示空格
- MOV B,LCD_X
- CALL LCDP2
- JMP CONV140
- CONV110: CALL SHOW_DIG2 ;顯示數(shù)據(jù)
- CONV120: INC LCD_X ;調(diào)整顯示地址
- MOV A,72H ;十位
- CALL SHOW_DIG2
- CONV130: INC LCD_X ;調(diào)整顯示地址
- MOV A,71H ;十位
- CALL SHOW_DIG2
- CONV140: INC LCD_X ;調(diào)整顯示地址
- MOV A,70H ;個位
- CALL SHOW_DIG2
- RET
- ;=================================================
- ;以下為LCD顯示酒精濃度程序
- ;73H-70H 分別存放個位、小數(shù)后1位、后2位、后3位的數(shù)據(jù)
- ;=================================================
- CONV200: MOV A,JJCQ
- JNZ BBL1
- MOV LCD_X,#0 ;當個位、十、百、千分位均為零時顯示0%
- MOV R0,#00H
- BBL2: MOV A,#' '
- MOV B,LCD_X
- CALL LCDP2
- INC LCD_X
- INC R0
- CJNE R0,#4,BBL2
- MOV R0,#00H
- CLR A ;個位
- CALL SHOW_DIG2
- RET
- BBL1: MOV A,73H ;加載個位數(shù)據(jù)
- MOV LCD_X,#0 ;設(shè)置顯示位置
- CALL SHOW_DIG2 ;顯示數(shù)據(jù)
- INC LCD_X ;調(diào)整顯示地址
- MOV A,#'.'
- MOV B,LCD_X
- CALL LCDP2
- SJMP CONV120
- ;=========================================
- ;LCD 顯示菜單1
- ;=========================================
- MENU_3: MOV DPTR,#M_OK31 ;指針指到顯示信息區(qū)
- MOV A,#1 ;顯示在第一行
- CALL LCD_PRINT
- MOV DPTR,#M_OK32 ;指針指到顯示信息區(qū)
- MOV A,#2 ;顯示在第二行
- CALL LCD_PRINT
- MOV DPTR,#M_OK33 ;指針指到顯示信息區(qū)
- MOV A,#3 ;顯示在第二行
- CALL LCD_PRINT
- MOV DPTR,#M_OK34 ;指針指到顯示信息區(qū)
- MOV A,#4 ;顯示在第二行
- CALL LCD_PRINT
- RET
- M_OK31: DB"有害氣體濃度: ",0
- M_OK32: DB" PPM ",0
- M_OK33: DB"檢測結(jié)果: ",0
- M_OK34: DB" ",0
- ;=========================================
- ;LCD 顯示菜單2
- ;=========================================
- MENU_4: MOV DPTR,#M_OK41 ;指針指到顯示信息區(qū)
- MOV A,#1 ;顯示在第一行
- CALL LCD_PRINT
- MOV DPTR,#M_OK42 ;指針指到顯示信息區(qū)
- MOV A,#2 ;顯示在第二行
- CALL LCD_PRINT
- MOV DPTR,#M_OK43 ;指針指到顯示信息區(qū)
- MOV A,#3 ;顯示在第二行
- CALL LCD_PRINT
- MOV DPTR,#M_OK44 ;指針指到顯示信息區(qū)
- MOV A,#4 ;顯示在第二行
- CALL LCD_PRINT
- RET
- M_OK41: DB"酒精濃度: ",0
- M_OK42: DB" % BAC ",0
- M_OK43: DB"檢測結(jié)果: ",0
- M_OK44: DB" ",0
- ;=========================================
- ;LCD 顯示菜單3
- ;=========================================
- MENU_5: MOV DPTR,#M_OK51 ;指針指到顯示信息區(qū)
- MOV A,#1 ;顯示在第一行
- CALL LCD_PRINT
- MOV DPTR,#M_OK52 ;指針指到顯示信息區(qū)
- MOV A,#2 ;顯示在第二行
- CALL LCD_PRINT
- MOV DPTR,#M_OK53 ;指針指到顯示信息區(qū)
- MOV A,#3 ;顯示在第二行
- CALL LCD_PRINT
- MOV DPTR,#M_OK54 ;指針指到顯示信息區(qū)
- MOV A,#4 ;顯示在第二行
- CALL LCD_PRINT
- RET
- M_OK51: DB"進入酒精檢測程序",0
- M_OK52: DB"傳感器預(yù)熱請稍等",0
- M_OK53: DB"... ... ",0
- M_OK54: DB"倒計時: S ",0
- ;=========================================
- ;LCD 顯示菜單4
- ;=========================================
- MENU_6: MOV DPTR,#M_OK61 ;指針指到顯示信息區(qū)
- MOV A,#1 ;顯示在第一行
- CALL LCD_PRINT
- MOV DPTR,#M_OK62 ;指針指到顯示信息區(qū)
- MOV A,#2 ;顯示在第二行
- CALL LCD_PRINT
- MOV DPTR,#M_OK63 ;指針指到顯示信息區(qū)
- MOV A,#3 ;顯示在第二行
- CALL LCD_PRINT
- MOV DPTR,#M_OK64 ;指針指到顯示信息區(qū)
- MOV A,#4 ;顯示在第二行
- CALL LCD_PRINT
- RET
- M_OK61: DB"現(xiàn)在開始酒精檢測",0
- M_OK62: DB"注意: ",0
- M_OK63: DB"嘴巴要距離傳感器",0
- M_OK64: DB"5---10cm輕輕吹氣",0
- ;=========================================
- ;以下為主機串行通信程序
- ;占用資源:R0~R4,A、40H、50H
- ;=========================================
- COM: MOV A,TMOD ;設(shè)置T1工作方式為方式2、T0工作方式保持不變
- MOV FSJCQ,A
- ORL A,#00101111B
- MOV TMOD,A
- MOV TH1,#0FDH ;11.0592MHz 晶振,波特率=9600,時長0.6695
- MOV TL1,#0FDH
- MOV SCON,#0D8H ;置串行模式3,SM2=1,允許接收
- SETB TR1 ;啟動T1
- LCALL COM1 ;調(diào)用一線發(fā)碼子程序
- MOV TMOD,FSJCQ ;恢復(fù)T1、T0原先的工作方式
- RET
- COM1: MOV A,R2 ;發(fā)送地址幀
- MOV SBUF,A
- JNB TI,$
- CLR TI
- JNB RI,$ ;等待從機應(yīng)答
- CLR RI
- MOV A,SBUF
- XRL A,R2
- JNZ MS104 ;判應(yīng)答地址是否相符
- CLR TB8 ;地址符合,準備發(fā)送命令
- MOV SBUF,R3 ;發(fā)送發(fā)送或接收數(shù)據(jù)命令
- JNB TI,$
- CLR TI
- JNB RI,$ ;等待從機應(yīng)答
- CLR RI
- MOV A,SBUF ;取應(yīng)答信息
- JNB ACC.7,MS102 ;判斷是否出錯
- MS101: SETB TB8
- MOV SBUF,#0FFH ;不相符重新聯(lián)絡(luò)
- JNB TI,$
- CLR TI
- SJMP COM1 ;轉(zhuǎn)重發(fā)地址
- MS102: CJNE R3,#00H,MS103 ;判是否要求從機接收數(shù)據(jù)
- JNB ACC.0,MS101 ;從機接收數(shù)據(jù)準備就緒否?
- MOV R0,#FSSZ ;主機發(fā)送的數(shù)據(jù)塊首址
- MOV R4,#BITE ;設(shè)數(shù)據(jù)塊長度(9字節(jié))
- LPTX: MOV SBUF,@R0 ;主機發(fā)送數(shù)據(jù)塊
- JNB TI,$ ;等待發(fā)送完1幀
- CLR TI
- INC R0 ;修改地址指針
- DJNZ R4,LPTX ;判數(shù)據(jù)塊是否傳完
- SJMP MS104 ;返回主程序
- MS103: JNB ACC.1,MS101 ;從機發(fā)送數(shù)據(jù)準備就緒否?
- MOV R1,#JSSZ ;主機接收的數(shù)據(jù)塊首址
- MOV R4,#BITE ;設(shè)數(shù)據(jù)塊長度(9字節(jié))
- LPRX: JNB RI,LPRX ;等待接收完1幀
- CLR RI
- MOV A,SBUF ;取出接收到的字符
- MOV @R1,A
- INC R1
- DJNZ R4,LPRX ;未接收完則繼續(xù)
- MS104: CLR TR1 ;關(guān)閉T1
- RET
- ;=========================================
- ;報警比較和顯示程序
- ;有害氣體濃度:≥200PPM→語音報警并 顯示"濃度超標,危險!"
- ; ≥120PPM→語音報警并 顯示"濃度偏高,請注意!"
- ; <120PPM→語音不報警 顯示"濃度未超標"
- ;酒精濃度: ≥0.05% BCA→語音報警并 顯示"濃度超標,危險!"
- ; ≥0.02% BCA→語音報警并 顯示"濃度偏高,請注意!"
- ; <0.02% BCA→語音不報警 顯示"濃度未超標"
- ;=========================================
- BJBJ1: MOV A,BJZC
- SUBB A,BJWX ;與超標設(shè)定值進行比較
- JC BL2
- LCALL WENZBJ1 ;顯示菜單1
- LCALL DELAY ;延時
- LCALL DELAY ;延時
- LCALL WENZBJ4 ;顯示菜單1-4,形成閃爍效果
- LCALL DELAY ;延時
- LCALL DELAY ;延時
- LCALL WENZBJ1 ;顯示菜單1
- MOV A,YYBZ
- CJNE A,#JSSZ+1,BL1 ;語音段播放識別
- MOV YY_DAT,#2 ;有害氣體檢測時報出“車內(nèi)有害氣體濃度過高,請排除”
- SJMP BL4
- BL1: CJNE A,#JSSZ+2,BL6 ;語音段播放識別
- MOV YY_DAT,#9 ;酒精檢測時報出“酒精濃度偏高,你是不是喝酒了,要小心開車哦”
- SJMP BL4
-
- BL2: MOV A,BJZC ;取ACC讀數(shù)值(存在45H里) ;
- SUBB A,BJJG ;與偏高設(shè)定值進行比較
- JC BL5 ;
- LCALL WENZBJ2 ;顯示菜單2
- LCALL DELAY ;延時
- LCALL DELAY ;延時
- LCALL WENZBJ4 ;顯示菜單4,形成閃爍效果
- LCALL DELAY ;延時
- LCALL DELAY ;延時
- LCALL WENZBJ2 ;顯示菜單2
- MOV A,YYBZ
- CJNE A,#JSSZ+1,BL3 ;語音段播放識別
- JNB BUSY,$
- MOV YY_DAT,#2 ;有害氣體檢測時報出“車內(nèi)有害氣體濃度過高,請排除”
- SJMP BL4
- BL3: CJNE A,#JSSZ+2,BL6 ;語音段播放識別
- JNB BUSY,$
- MOV YY_DAT,#8 ;酒精檢測時報出“酒精濃度過高,你喝多了,為了您的安全,請不要開車”
- BL4: LCALL YUYIN ;開始語音播放
- SJMP BL6
- BL5: LCALL WENZBJ3 ;顯示菜單1-3
- MOV A,YYBZ
- CJNE A,#JSSZ+2,BL6 ;語音段播放識別
- JNB BUSY,$
- MOV YY_DAT,#7 ;酒精檢測時報出“酒精濃度沒有超標”
- LCALL YUYIN ;開始語音播放
- BL6: RET
- WENZBJ1: MOV DPTR,#BJ10 ;超標顯示的內(nèi)容
- SJMP BL7
- WENZBJ2: MOV DPTR,#BJ20 ;偏高顯示的內(nèi)容
- SJMP BL7
- WENZBJ3: MOV DPTR,#BJ30 ;未超標顯示的內(nèi)容
- SJMP BL7
- WENZBJ4: MOV DPTR,#BJ40 ;未超標顯示的內(nèi)容
- BL7: MOV A,#98H ;設(shè)置 LCD 顯示的地址(第四行)
- CALL WCOM ;寫入指令
- BL8: CLR A ;填入字符
- MOVC A,@A+DPTR ;由信息區(qū)取出字符
- CJNE A,#0,BL9 ;判斷是否為結(jié)束碼
- RET
- BL9: CALL WDATA ;寫入數(shù)據(jù)
- INC DPTR ;指針加1
- JMP BL8 ;繼續(xù)填入字符
- BJ10: DB "濃度超標,危險!",0
- BJ20: DB "濃度偏高,請注意",0
- BJ30: DB " 濃度沒有超標 ",0
- BJ40: DB " ",0
- ;***********************************************************
- JIUJJC: MOV FSSZ+1,#01H ;命令10號從機打開有害氣體傳感器
- MOV R2,#0AH ;與10號從機串口通信,多功能板地址為0AH
- MOV R3,#00H ;主機要求從機接收數(shù)據(jù)塊
- LCALL COM ;主機與多功能檢測板串口通信,要求其接收9個字節(jié)數(shù)據(jù)塊
- MOV YY_DAT,#3 ;報出“現(xiàn)在進入酒精檢測程序,請等待十秒鐘”
- JNB BUSY,$
- LCALL YUYIN ;開始語音播放
- ACALL MENU_5
- JNB BUSY,$
- MOV DJSJCQ,#10
- MOV A,DJSJCQ
- K2: MOV B,#1
- LCALL HEX2BCD1 ;調(diào)用數(shù)值轉(zhuǎn)換程序
- LCALL CONV300 ;調(diào)用LCD顯示程序
- MOV A,#3 ;延時
- LBB23: LCALL DELAY
- DEC A
- JNZ LBB23
- DEC DJSJCQ
- MOV A,DJSJCQ
- CJNE A,#00H,K2
- MOV YY_DAT,#4 ;報出“現(xiàn)在開始酒精檢測”
- JNB BUSY,$
- LCALL YUYIN ;開始語音播放
- ACALL MENU_6
- MOV A,#10 ;延時
- LBB33: LCALL DELAY
- DEC A
- JNZ LBB33
- MOV YY_DAT,#5 ;報出“請把嘴巴對準探頭輕輕吹氣”
- JNB BUSY,$
- LCALL YUYIN ;開始語音播放
- RET
- CONV300: MOV A,71H ;十位
- CJNE A,#00H,K3
- MOV A,#9CH ;調(diào)整顯示地址
- CALL WCOM ;寫入命令
- MOV A,#" " ;百位數(shù)等于0顯示空格
- CALL WDATA ;寫入數(shù)據(jù)
- SJMP K4
- K3: MOV A,#9CH ;調(diào)整顯示地址
- CALL WCOM ;寫入命令
- MOV A,71H
- ADD A,#30H ;加30H,轉(zhuǎn)換為ASCII碼
- CALL WDATA ;寫入數(shù)據(jù)
- K4: MOV A,#9DH ;調(diào)整顯示地址
- CALL WCOM ;寫入命令
- MOV A,70H
- ADD A,#30H ;加30H,轉(zhuǎn)換為ASCII碼
- CALL WDATA ;寫入數(shù)據(jù)
- RET
- ;-------------------------------------------------------
-
-
-
- ;以下程序通用
- ;=============================================
- ;在LCD的第二行顯示數(shù)據(jù)字符
- ;A=ASCII 數(shù)據(jù), B=位置變量
- ;==============================================
- LCDP2: PUSH ACC ;在LCD的第二行顯示字符
- MOV A,B ;設(shè)置顯示地址
- ADD A,#90H ;設(shè)置LCD的第二行地址
- CALL WCOM ;寫入命令
- POP ACC ;由堆棧取出A
- CALL WDATA ;寫入數(shù)據(jù)
- RET
- ;-------------------------------------------------------
- SHOW_DIG2: ;在 LCD 的第二行顯示數(shù)字
- ADD A,#30H ;加30H,轉(zhuǎn)換為ASCII碼
- MOV B,LCD_X ;確定顯示位置
- CALL LCDP2 ;送顯示
- RET
- ;=================================================
- ;對 LCD 做初始化設(shè)置
- ;=================================================
- 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 的地址計數(shù)器(AC)加1
- MOV A,#0CH ;開顯示,關(guān)光標,不閃爍
- 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
- ;===============================================
- ;數(shù)據(jù)寫入子程序
- ;RS=H,RW=L,D0-D7=指令碼,E=高脈沖
- ;以8位控制方式將數(shù)據(jù)寫至LCD
- ;===============================================
- WDATA: MOV LCD_SJ,A ;寫入數(shù)據(jù)
- SETB LCD_RS
- CLR LCD_RW
- SETB LCD_EN
- CALL DE
- CLR LCD_EN
- CALL DE
- RET
- ;===============================================
- ;測LCD忙碌子程序
- ;RS=0,RW=1,E=H,D0-D7=狀態(tài)字
- ;===============================================
- CHK_BUSY: MOV LCD_SJ,#0FFH ;測忙碌子程序
- CLR LCD_RS
- SETB LCD_RW
- SETB LCD_EN
- JB LCD_SJ.7,$
- CLR LCD_EN
- RET
- ;==================================================
- ;在LCD的顯示字符串
- ;DPTR = 放字符串的地址
- ;==================================================
- LCD_PRINT:CJNE A,#1,LINE2 ;判斷是否為第一行
- LINE1: MOV A,#80H ;設(shè)置 LCD 的第一行地址
- CALL WCOM ;寫入命令
- CALL CLR_LINE ;清除該行字符數(shù)據(jù)
- MOV A,#80H ;設(shè)置 LCD 的第一行地址
- CALL WCOM ;寫入命令
- JMP FILL
- LINE2: CJNE A,#2,LINE3 ;判斷是否為第二行
- MOV A,#90H ;設(shè)置 LCD 的第二行地址
- CALL WCOM ;寫入命令
- CALL CLR_LINE ;清除該行字符數(shù)據(jù)
- MOV A,#90H ;設(shè)置 LCD 的第二行地址
- CALL WCOM
- JMP FILL
- LINE3: CJNE A,#3,LINE4 ;判斷是否為第三行
- MOV A,#88H ;設(shè)置 LCD 的第三行地址
- CALL WCOM ;寫入命令
- CALL CLR_LINE ;清除該行字符數(shù)據(jù)
- MOV A,#88H ;設(shè)置 LCD 的第三行地址
- CALL WCOM
- JMP FILL
- LINE4: MOV A,#98H ;設(shè)置 LCD 的第四行地址
- CALL WCOM ;寫入命令
- CALL CLR_LINE ;清除該行字符數(shù)據(jù)
- MOV A,#98H ;設(shè)置 LCD 的第四行地址
- CALL WCOM
- FILL: CLR A ;填入字符
- MOVC A,@A+DPTR ;由信息區(qū)取出字符
- CJNE A,#0,LC1 ;判斷是否為結(jié)束碼
- RET
- LC1: CALL WDATA ;寫入數(shù)據(jù)
- INC DPTR ;指針加1
- JMP FILL ;繼續(xù)填入字符
- ;===============================================
- ;清除一行 LCD 的字符
- ;輸入一行空格,來替代原顯示字符
- ;===============================================
- CLR_LINE: MOV R0,#16 ;清除該行 LCD 的字符
- CL1: MOV A,#' '
- CALL WDATA
- DJNZ R0,CL1
- RET
- ;**********************************************************
- ;延時子程序
- ;**********************************************************
- DE: MOV R7,#229 ;延時 500 微秒,此條2個機器周期
- DJNZ R7,$
- RET ;此條2個機器周期,總延時(229*2+2+2)*(12/11.0592)≈500uS
- DELAY: MOV R5,#20 ;延時200MS
- DELAY1: MOV R6,#96 ;100
- DL1: MOV R7,#96 ;100
- DJNZ R7,$
- DJNZ R6,DL1
- DJNZ R5,DELAY1 ;96*2*48*(12/11.0592)+2*(12/11.0592)≈10000uS=10mS
- RET
- DELAY2: MOV R6,#10 ;延時5MS
- DL2: MOV R7,#229 ;100微秒
- DJNZ R7,$
- DJNZ R6,DL2
- DJNZ R5,DELAY2
- RET
- DELAY3: MOV R5,#20 ;延時200MS
- DELA: MOV R6,#96
- DL3: MOV R7,#96
- DJNZ R7,$
- DJNZ R6,DL3
- DJNZ R5,DELA
- RET
- ;**********************************************************
- ;語音驅(qū)動和播放程序
- ;**********************************************************
- ;50H為語音段地址暫存器,1到210段,實際用到40
- ;50H為E0H~E7H時分別代表自低往高的8級音量
- ;在語音播放過程中發(fā)送F2H至50H可循環(huán)播放當前地址語音
- ;發(fā)送FEH至50H停止播放語音
- ;****************************************************
- YUYIN: MOV A,TMOD ;設(shè)置T1工作方式為方式1、T0工作方式保持不變
- MOV FSJCQ,A
- ORL A,#00011111B
- MOV TMOD,A
- MOV R6,#08H ;發(fā)碼8位循環(huán)數(shù)據(jù)
- LCALL ONE_LINE ;調(diào)用一線發(fā)碼子程序
- MOV TMOD,FSJCQ ;恢復(fù)T1、T0原先的工作方式
- RET
- ONE_LINE: ;////一線發(fā)碼子程序
- SETB YYRST ;復(fù)位
- MOV R7,#2 ;延時2MS
- LCALL DELAY1MS
- CLR YYRST ;延時使系統(tǒng)穩(wěn)定
- MOV R7,#6 ;延時6MS
- LCALL DELAY1MS
- CLR YYSDA ;喚醒語音芯片
- MOV R7,#17 ;延時17MS
- LCALL DELAY1MS
- MOV A,YY_DAT
- LP1: SETB YYSDA
- RRC A ;分辨50H內(nèi)的數(shù)據(jù)各位是高電平還是低電平
- JNC DIDIANPIN ;高電平用高:低=2:1的脈寬表示
- LCALL DELAY200US
- LCALL DELAY200US
- LCALL DELAY200US
- CLR YYSDA
- LCALL DELAY200US
- LP2: DJNZ R6,LP1 ;查看數(shù)據(jù)是否發(fā)完,未發(fā)完繼續(xù)發(fā)
- 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 TH1,#0FFH
- MOV TL1,#47H
- SETB TR1
- LOP1: JBC TF1,NEXT1
- SJMP LOP1
- NEXT1: CLR TR1
- RET
- DELAY1MS:MOV TH1,#0FCH ;延時1ms子程序
- MOV TL1,#66H
- SETB TR1
- LOP2: JBC TF1,NEXT2
- SJMP LOP2
- NEXT2: DJNZ R7,DELAY1MS
- CLR TR1
- RET
- END
復(fù)制代碼
|
|