亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码
標題:
基于51單片機的有害氣體檢測程序(匯編)
[打印本頁]
作者:
daniu
時間:
2014-12-26 22:35
標題:
基于51單片機的有害氣體檢測程序(匯編)
LCD_X EQU 23H ;LCD 地址變量(決定文字的在LCD上的顯示位置)
FSJCQ EQU 33H ;TMOD工作方式暫存寄存器
BJZC EQU 34H ;需要比較數據暫存寄存器,用于報警顯示
BJWX EQU 35H ;超標設定值暫存寄存器
BJJG EQU 36H ;偏高設定值暫存寄存器
JJCQ EQU 37H ;酒精顯示0%暫存寄存器
YYBZ EQU 38H ;語音播放標志
DJSJCQ EQU 39H ;10S倒計時寄存器
JJCYCS EQU 4AH ;酒精檢測采樣次數寄存器
XSYSSJ DATA 5 ;正常時顯示延時時間
WXBJZ1 EQU 100 ;有害氣體危險報警設定值200PPM
;實際設定值=200(顯示設定值)/2(修正倍率)
JGBJZ1 EQU 60 ;有害氣體警告報警設定值120PPM
;實際設定值=120(顯示設定值)/2(修正倍率)
WXBJZ2 EQU 50 ;酒精危險報警設定值0.05% BAC
;實際設定值=0.05%(顯示設定值)*1000(顯示位修正)/1(修正倍率)
JGBJZ2 EQU 20 ;酒精警告報警設定值0.02% BAC
;實際設定值=0.02%(顯示設定值)*1000(顯示位修正)/1(修正倍率)
XIUZ1 EQU 10 ;有害氣體濃度顯示數據修正值,設置大時則顯示數值小,反之顯示大
XIUZ2 EQU 34 ;酒精濃度顯示數據修正值,設置大時則顯示數值小,反之顯示大
;-----------------------------------------------------------
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 數據
BITE EQU 9 ;串口發送9位數據
FSSZ EQU 40H ;主機發送的數據塊首址
JSSZ EQU 50H ;主機接收的數據塊首址
YY_DAT DATA 29H ;語音段地址存放單元
YYRST EQU P3.3 ;語音模塊復位信號引腳
BUSY EQU P1.0 ;語音忙控制端,0為正在播放1為沒有播放空閑時
YYSDA EQU P1.1 ;語音模塊數據線引腳
;===========================================================
ORG 0000H
AJMP MAIN
ORG 0003H ;外中斷0中斷程序入口
RETI ;中斷返回
ORG 000BH ;定時器T0中斷程序入口
RETI ;中斷返回
ORG 0013H ;外中斷1中斷入口
RETI ;中斷返回
ORG 001BH ;定時器T1中斷程序入口
RETI ;跳至INTT1中斷服務程序
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 ;主機要求從機發送數據塊
LCALL COM ;主機與多功能檢測板串口通信,要求其發送9個字節數據塊
MOV A,JSSZ+1 ;取出傳感器檢測到的電壓讀數(原始數據,16進制)
MOV B,#2 ;顯示修正倍率,原始數*倍率+修正值=LCD顯示值
SUBB A,#XIUZ1 ;顯示修正
JNC LBB1 ;軟件調整初值
MOV A,#0 ;使之正常時顯示0
LBB1: LCALL HEX2BCD1 ;調用數值轉換程序
LCALL CONV100 ;調用LCD顯示程序
MOV BJZC,JSSZ+1 ;取出傳感器檢測到的電壓讀數(原始數據),做報警比較
MOV BJWX,#WXBJZ1+XIUZ1 ;實際危險報警值=設定值/倍率+修正值
MOV BJJG,#JGBJZ1+XIUZ1 ;實際警告報警值=設定值/倍率+修正值
MOV YYBZ,#JSSZ+1 ;設有害氣體語音播放標志
LCALL BJBJ1 ;調用報警程序
JB P3.4,LBB5
LCALL DELAY2
JB P3.4,LBB5
LCALL JJJCCX
LBB5: LCALL DELAY3
SJMP YHJCCX
;以下為酒精濃度顯示和報警程序
JJJCCX: MOV JJCYCS,#5 ;設酒精檢測輪回采樣次數
LCALL JIUJJC ;顯示準備進入酒精檢測程序的畫面
JJJCCX1: MOV R2,#0AH ;與10號從機串口通信,多功能板地址為0AH
MOV R3,#01H ;主機要求從機發送數據塊
LCALL COM ;主機與多功能檢測板串口通信,要求其發送9個字節數據塊
LCALL MENU_4 ;顯示菜單1
MOV A,JSSZ+2 ;取出傳感器檢測到的電壓讀數(原始數據,16進制)
MOV B,#1 ;顯示修正倍率,原始數*倍率+修正值=LCD顯示值
SUBB A,#XIUZ2 ;顯示修正
JNC LBB2 ;軟件調整初值
MOV A,#0 ;使之正常時顯示0%
LBB2: LCALL HEX2BCD1 ;調用數值轉換程序
LCALL CONV200 ;調用LCD顯示程序
MOV BJZC,JSSZ+2 ;取出傳感器檢測到的電壓讀數(原始數據),做報警比較
MOV BJWX,#WXBJZ2+XIUZ2 ;實際危險報警值=設定值/倍率+修正值
MOV BJJG,#JGBJZ2+XIUZ2 ;實際警告報警值=設定值/倍率+修正值
LCALL DELAY3 ;延時,使其能看清楚看到檢測到的數值
DEC JJCYCS
MOV A,JJCYCS
JNZ JJJCCX1 ;連續采樣幾次(未到則返回)
JNB BUSY,$ ;如果語言正在播放,則等待
MOV YY_DAT,#6 ;報出“檢測完畢”
LCALL YUYIN ;開始語音播放
LCALL DELAY
LCALL DELAY
MOV YYBZ,#JSSZ+2 ;設酒精報警語音播放標志
LCALL BJBJ1 ;調用報警程序
LCALL DELAY3 ;延時
RET
;***************************************************
;=========================================
;以下為兩個單字節十六進制相乘
;入口:A*B
;出口:16位低字節放A中,高字節放B中
;=========================================
HEX2BCD1: MUL AB
MOV R6,B
MOV R7,A
MOV JJCQ,A ;為顯示0%作準備
;=========================================
;以下為雙字節十六進制整數轉換成雙字節BCD碼整數
;入口條件:待轉換的雙字節十六進制整數在R6、R7中。
;出口信息:轉換后的三字節BCD碼整數在R3、R4、R5中。
;影響資源:PSW、A、R2~R7,堆棧需求:2字節
;=========================================
CLR A ;BCD碼初始化
MOV R3,A
MOV R4,A
MOV R5,A
MOV R2,#10H ;轉換雙字節十六進制整數
HB3: MOV A,R7 ;從高端移出待轉換數的一位到CY中
RLC A
MOV R7,A
MOV A,R6
RLC A
MOV R6,A
MOV A,R5 ;BCD碼帶進位自身相加,相當于乘2
ADDC A,R5
DA A ;十進制調整
MOV R5,A
MOV A,R4
ADDC A,R4
DA A
MOV R4,A
MOV A,R3
ADDC A,R3
MOV R3,A ;雙字節十六進制數的萬位數不超過6,不用調整
DJNZ R2,HB3 ;處理完16bit
;=========================================
;以下為把BCD碼提取出并送顯示寄存器70H~73H
;入口:;三字節BCD碼整數在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 分別存放百位、十位、個位的數據
;==============================================
CONV100: MOV A,73H ;加載百位數據
MOV LCD_X,#1 ;設置顯示位置
CJNE A,#00H,CONV110
MOV A,#" " ;百位數等于0顯示空格
MOV B,LCD_X
CALL LCDP2
MOV A,72H ;十位
CJNE A,#00H,CONV120
INC LCD_X ;調整顯示地址
MOV A,#" " ;十位數等于0顯示空格
MOV B,LCD_X
CALL LCDP2
MOV A,71H ;十位
CJNE A,#00H,CONV130
INC LCD_X ;調整顯示地址
MOV A,#" " ;十位數等于0顯示空格
MOV B,LCD_X
CALL LCDP2
JMP CONV140
CONV110: CALL SHOW_DIG2 ;顯示數據
CONV120: INC LCD_X ;調整顯示地址
MOV A,72H ;十位
CALL SHOW_DIG2
CONV130: INC LCD_X ;調整顯示地址
MOV A,71H ;十位
CALL SHOW_DIG2
CONV140: INC LCD_X ;調整顯示地址
MOV A,70H ;個位
CALL SHOW_DIG2
RET
;=================================================
;以下為LCD顯示酒精濃度程序
;73H-70H 分別存放個位、小數后1位、后2位、后3位的數據
;=================================================
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 ;加載個位數據
MOV LCD_X,#0 ;設置顯示位置
CALL SHOW_DIG2 ;顯示數據
INC LCD_X ;調整顯示地址
MOV A,#'.'
MOV B,LCD_X
CALL LCDP2
SJMP CONV120
;=========================================
;LCD 顯示菜單1
;=========================================
MENU_3: MOV DPTR,#M_OK31 ;指針指到顯示信息區
MOV A,#1 ;顯示在第一行
CALL LCD_PRINT
MOV DPTR,#M_OK32 ;指針指到顯示信息區
MOV A,#2 ;顯示在第二行
CALL LCD_PRINT
MOV DPTR,#M_OK33 ;指針指到顯示信息區
MOV A,#3 ;顯示在第二行
CALL LCD_PRINT
MOV DPTR,#M_OK34 ;指針指到顯示信息區
MOV A,#4 ;顯示在第二行
CALL LCD_PRINT
RET
M_OK31: DB"有害氣體濃度: ",0
M_OK32: DB" PPM ",0
M_OK33: DB"檢測結果: ",0
M_OK34: DB" ",0
;=========================================
;LCD 顯示菜單2
;=========================================
MENU_4: MOV DPTR,#M_OK41 ;指針指到顯示信息區
MOV A,#1 ;顯示在第一行
CALL LCD_PRINT
MOV DPTR,#M_OK42 ;指針指到顯示信息區
MOV A,#2 ;顯示在第二行
CALL LCD_PRINT
MOV DPTR,#M_OK43 ;指針指到顯示信息區
MOV A,#3 ;顯示在第二行
CALL LCD_PRINT
MOV DPTR,#M_OK44 ;指針指到顯示信息區
MOV A,#4 ;顯示在第二行
CALL LCD_PRINT
RET
M_OK41: DB"酒精濃度: ",0
M_OK42: DB" % BAC ",0
M_OK43: DB"檢測結果: ",0
M_OK44: DB" ",0
;=========================================
;LCD 顯示菜單3
;=========================================
MENU_5: MOV DPTR,#M_OK51 ;指針指到顯示信息區
MOV A,#1 ;顯示在第一行
CALL LCD_PRINT
MOV DPTR,#M_OK52 ;指針指到顯示信息區
MOV A,#2 ;顯示在第二行
CALL LCD_PRINT
MOV DPTR,#M_OK53 ;指針指到顯示信息區
MOV A,#3 ;顯示在第二行
CALL LCD_PRINT
MOV DPTR,#M_OK54 ;指針指到顯示信息區
MOV A,#4 ;顯示在第二行
CALL LCD_PRINT
RET
M_OK51: DB"進入酒精檢測程序",0
M_OK52: DB"傳感器預熱請稍等",0
M_OK53: DB"... ... ",0
M_OK54: DB"倒計時: S ",0
;=========================================
;LCD 顯示菜單4
;=========================================
MENU_6: MOV DPTR,#M_OK61 ;指針指到顯示信息區
MOV A,#1 ;顯示在第一行
CALL LCD_PRINT
MOV DPTR,#M_OK62 ;指針指到顯示信息區
MOV A,#2 ;顯示在第二行
CALL LCD_PRINT
MOV DPTR,#M_OK63 ;指針指到顯示信息區
MOV A,#3 ;顯示在第二行
CALL LCD_PRINT
MOV DPTR,#M_OK64 ;指針指到顯示信息區
MOV A,#4 ;顯示在第二行
CALL LCD_PRINT
RET
M_OK61: DB"現在開始酒精檢測",0
M_OK62: DB"注意: ",0
M_OK63: DB"嘴巴要距離傳感器",0
M_OK64: DB"5---10cm輕輕吹氣",0
;=========================================
;以下為主機串行通信程序
;占用資源:R0~R4,A、40H、50H
;=========================================
COM: MOV A,TMOD ;設置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 ;調用一線發碼子程序
MOV TMOD,FSJCQ ;恢復T1、T0原先的工作方式
RET
COM1: MOV A,R2 ;發送地址幀
MOV SBUF,A
JNB TI,$
CLR TI
JNB RI,$ ;等待從機應答
CLR RI
MOV A,SBUF
XRL A,R2
JNZ MS104 ;判應答地址是否相符
CLR TB8 ;地址符合,準備發送命令
MOV SBUF,R3 ;發送發送或接收數據命令
JNB TI,$
CLR TI
JNB RI,$ ;等待從機應答
CLR RI
MOV A,SBUF ;取應答信息
JNB ACC.7,MS102 ;判斷是否出錯
MS101: SETB TB8
MOV SBUF,#0FFH ;不相符重新聯絡
JNB TI,$
CLR TI
SJMP COM1 ;轉重發地址
MS102: CJNE R3,#00H,MS103 ;判是否要求從機接收數據
JNB ACC.0,MS101 ;從機接收數據準備就緒否?
MOV R0,#FSSZ ;主機發送的數據塊首址
MOV R4,#BITE ;設數據塊長度(9字節)
LPTX: MOV SBUF,@R0 ;主機發送數據塊
JNB TI,$ ;等待發送完1幀
CLR TI
INC R0 ;修改地址指針
DJNZ R4,LPTX ;判數據塊是否傳完
SJMP MS104 ;返回主程序
MS103: JNB ACC.1,MS101 ;從機發送數據準備就緒否?
MOV R1,#JSSZ ;主機接收的數據塊首址
MOV R4,#BITE ;設數據塊長度(9字節)
LPRX: JNB RI,LPRX ;等待接收完1幀
CLR RI
MOV A,SBUF ;取出接收到的字符
MOV @R1,A
INC R1
DJNZ R4,LPRX ;未接收完則繼續
MS104: CLR TR1 ;關閉T1
RET
;=========================================
;報警比較和顯示程序
;有害氣體濃度:≥200PPM→語音報警并 顯示"濃度超標,危險!"
; ≥120PPM→語音報警并 顯示"濃度偏高,請注意!"
; <120PPM→語音不報警 顯示"濃度未超標"
;酒精濃度: ≥0.05% BCA→語音報警并 顯示"濃度超標,危險!"
; ≥0.02% BCA→語音報警并 顯示"濃度偏高,請注意!"
; <0.02% BCA→語音不報警 顯示"濃度未超標"
;=========================================
BJBJ1: MOV A,BJZC
SUBB A,BJWX ;與超標設定值進行比較
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 ;有害氣體檢測時報出“車內有害氣體濃度過高,請排除”
SJMP BL4
BL1: CJNE A,#JSSZ+2,BL6 ;語音段播放識別
MOV YY_DAT,#9 ;酒精檢測時報出“酒精濃度偏高,你是不是喝酒了,要小心開車哦”
SJMP BL4
BL2: MOV A,BJZC ;取ACC讀數值(存在45H里) ;
SUBB A,BJJG ;與偏高設定值進行比較
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 ;有害氣體檢測時報出“車內有害氣體濃度過高,請排除”
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 ;超標顯示的內容
SJMP BL7
WENZBJ2: MOV DPTR,#BJ20 ;偏高顯示的內容
SJMP BL7
WENZBJ3: MOV DPTR,#BJ30 ;未超標顯示的內容
SJMP BL7
WENZBJ4: MOV DPTR,#BJ40 ;未超標顯示的內容
BL7: MOV A,#98H ;設置 LCD 顯示的地址(第四行)
CALL WCOM ;寫入指令
BL8: CLR A ;填入字符
MOVC A,@A+DPTR ;由信息區取出字符
CJNE A,#0,BL9 ;判斷是否為結束碼
RET
BL9: CALL WDATA ;寫入數據
INC DPTR ;指針加1
JMP BL8 ;繼續填入字符
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 ;主機要求從機接收數據塊
LCALL COM ;主機與多功能檢測板串口通信,要求其接收9個字節數據塊
MOV YY_DAT,#3 ;報出“現在進入酒精檢測程序,請等待十秒鐘”
JNB BUSY,$
LCALL YUYIN ;開始語音播放
ACALL MENU_5
JNB BUSY,$
MOV DJSJCQ,#10
MOV A,DJSJCQ
K2: MOV B,#1
LCALL HEX2BCD1 ;調用數值轉換程序
LCALL CONV300 ;調用LCD顯示程序
MOV A,#3 ;延時
LBB23: LCALL DELAY
DEC A
JNZ LBB23
DEC DJSJCQ
MOV A,DJSJCQ
CJNE A,#00H,K2
MOV YY_DAT,#4 ;報出“現在開始酒精檢測”
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 ;調整顯示地址
CALL WCOM ;寫入命令
MOV A,#" " ;百位數等于0顯示空格
CALL WDATA ;寫入數據
SJMP K4
K3: MOV A,#9CH ;調整顯示地址
CALL WCOM ;寫入命令
MOV A,71H
ADD A,#30H ;加30H,轉換為ASCII碼
CALL WDATA ;寫入數據
K4: MOV A,#9DH ;調整顯示地址
CALL WCOM ;寫入命令
MOV A,70H
ADD A,#30H ;加30H,轉換為ASCII碼
CALL WDATA ;寫入數據
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 做初始化設置
;=================================================
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
;===============================================
;測LCD忙碌子程序
;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
;==================================================
;在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,#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
;**********************************************************
;語音驅動和播放程序
;**********************************************************
;50H為語音段地址暫存器,1到210段,實際用到40
;50H為E0H~E7H時分別代表自低往高的8級音量
;在語音播放過程中發送F2H至50H可循環播放當前地址語音
;發送FEH至50H停止播放語音
;****************************************************
YUYIN: MOV A,TMOD ;設置T1工作方式為方式1、T0工作方式保持不變
MOV FSJCQ,A
ORL A,#00011111B
MOV TMOD,A
MOV R6,#08H ;發碼8位循環數據
LCALL ONE_LINE ;調用一線發碼子程序
MOV TMOD,FSJCQ ;恢復T1、T0原先的工作方式
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 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
復制代碼
作者:
yzq123
時間:
2017-6-15 14:18
樓主有沒有c語言的,急求。。
作者:
chencf
時間:
2019-7-23 22:50
學習了,樓主真厲害!!!!!
歡迎光臨 (http://www.denmoz.com/bbs/)
Powered by Discuz! X3.1