找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5144|回复: 2
打印 上一主题 下一主题
收起左侧

基于51单片机的有害气体检测程序(汇编)

[复制链接]
跳转到指定楼层
楼主
ID:70976 发表于 2014-12-26 22:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


  1.           LCD_X  EQU   23H        ;LCD 地址变量(决定文字的在LCD上的显示位置)
  2.           FSJCQ  EQU   33H        ;TMOD工作方式暂存寄存器
  3.           BJZC   EQU   34H        ;需要比较数据暂存寄存器,用于报警显示
  4.           BJWX   EQU   35H        ;超标设定值暂存寄存器
  5.           BJJG   EQU   36H        ;偏高设定值暂存寄存器
  6.           JJCQ   EQU   37H        ;酒精显示0%暂存寄存器
  7.           YYBZ   EQU   38H        ;语音播放标志
  8.           DJSJCQ EQU   39H        ;10S倒计时寄存器
  9.           JJCYCS EQU   4AH        ;酒精检测采样次数寄存器

  10.           XSYSSJ    DATA   5      ;正常时显示延时时间

  11.           WXBJZ1  EQU   100       ;有害气体危险报警设定值200PPM
  12.                                   ;实际设定值=200(显示设定值)/2(修正倍率)
  13.           JGBJZ1  EQU   60        ;有害气体警告报警设定值120PPM
  14.                                   ;实际设定值=120(显示设定值)/2(修正倍率)
  15.           WXBJZ2  EQU   50        ;酒精危险报警设定值0.05% BAC
  16.                                   ;实际设定值=0.05%(显示设定值)*1000(显示位修正)/1(修正倍率)
  17.           JGBJZ2  EQU   20        ;酒精警告报警设定值0.02% BAC
  18.                                   ;实际设定值=0.02%(显示设定值)*1000(显示位修正)/1(修正倍率)
  19.           XIUZ1   EQU   10        ;有害气体浓度显示数据修正值,设置大时则显示数值小,反之显示大
  20.           XIUZ2   EQU   34        ;酒精浓度显示数据修正值,设置大时则显示数值小,反之显示大

  21. ;-----------------------------------------------------------
  22.           LCD_RS    EQU   P4.0    ;LCD 数据/命令选择端
  23.           LCD_RW    EQU   P4.1    ;LCD 读/写选择端
  24.           LCD_EN    EQU   P4.2    ;LCD 使能信号
  25.           LCD_BG    EQU   P4.3    ;LCD 背光控制端
  26.           LCD_SJ    EQU   P0      ;LCD 数据

  27.           BITE      EQU   9       ;串口发送9位数据
  28.           FSSZ      EQU   40H     ;主机发送的数据块首址
  29.           JSSZ      EQU   50H     ;主机接收的数据块首址

  30.           YY_DAT    DATA  29H     ;语音段地址存放单元
  31.           YYRST     EQU   P3.3    ;语音模块复位信号引脚
  32.           BUSY      EQU   P1.0    ;语音忙控制端,0为正在播放1为没有播放空闲时
  33.           YYSDA     EQU   P1.1    ;语音模块数据线引脚

  34. ;===========================================================
  35.           ORG  0000H
  36.           AJMP  MAIN
  37.           ORG  0003H       ;外中断0中断程序入口
  38.           RETI                ;中断返回
  39.           ORG  000BH          ;定时器T0中断程序入口
  40.           RETI                ;中断返回
  41.           ORG  0013H       ;外中断1中断入口
  42.           RETI               ;中断返回
  43.           ORG  001BH       ;定时器T1中断程序入口
  44.           RETI             ;跳至INTT1中断服务程序
  45.           ORG  0023H       ;串口中断入口地址
  46.           RETI               ;中断返回

  47.           ORG  0100H
  48. ;=========================================
  49. ;以下初始化程序
  50. ;=========================================
  51. MAIN:     MOV  SP,#60H
  52.           CLR  LCD_BG         ;打开LCD背光
  53.           LCALL  SET_LCD      ;初始化 LCD
  54.           MOV  R0,#20H        ;将20H-7FH 单元清零
  55.           MOV  R1,#95
  56. CLEAR:    MOV  @R0,A
  57.           INC  R0
  58.           DJNZ  R1,CLEAR

  59. ;=========================================
  60. ;以下为主程序
  61. ;=========================================
  62. ;以下为有害气体浓度显示和报警程序
  63. YHJCCX:   LCALL  MENU_3       ;显示菜单1
  64.           MOV R2,#0AH         ;与10号从机串口通信,多功能板地址为0AH
  65.           MOV R3,#01H         ;主机要求从机发送数据块
  66.           LCALL COM           ;主机与多功能检测板串口通信,要求其发送9个字节数据块

  67.           MOV A,JSSZ+1        ;取出传感器检测到的电压读数(原始数据,16进制)
  68.           MOV B,#2            ;显示修正倍率,原始数*倍率+修正值=LCD显示值
  69.           SUBB A,#XIUZ1       ;显示修正
  70.           JNC LBB1            ;软件调整初值
  71.           MOV A,#0            ;使之正常时显示0
  72. LBB1:     LCALL HEX2BCD1      ;调用数值转换程序
  73.           LCALL CONV100       ;调用LCD显示程序
  74.           MOV BJZC,JSSZ+1     ;取出传感器检测到的电压读数(原始数据),做报警比较
  75.           MOV BJWX,#WXBJZ1+XIUZ1 ;实际危险报警值=设定值/倍率+修正值
  76.           MOV BJJG,#JGBJZ1+XIUZ1 ;实际警告报警值=设定值/倍率+修正值
  77.           MOV YYBZ,#JSSZ+1    ;设有害气体语音播放标志
  78.           LCALL BJBJ1         ;调用报警程序

  79.           JB P3.4,LBB5
  80.           LCALL DELAY2
  81.           JB P3.4,LBB5
  82.           LCALL JJJCCX

  83. LBB5:     LCALL DELAY3

  84.           SJMP YHJCCX

  85. ;以下为酒精浓度显示和报警程序
  86. JJJCCX:   MOV JJCYCS,#5       ;设酒精检测轮回采样次数
  87.           LCALL JIUJJC        ;显示准备进入酒精检测程序的画面
  88. JJJCCX1:  MOV R2,#0AH         ;与10号从机串口通信,多功能板地址为0AH
  89.           MOV R3,#01H         ;主机要求从机发送数据块
  90.           LCALL COM           ;主机与多功能检测板串口通信,要求其发送9个字节数据块
  91.           LCALL  MENU_4       ;显示菜单1
  92.           MOV A,JSSZ+2        ;取出传感器检测到的电压读数(原始数据,16进制)
  93.           MOV B,#1            ;显示修正倍率,原始数*倍率+修正值=LCD显示值
  94.           SUBB A,#XIUZ2       ;显示修正
  95.           JNC LBB2            ;软件调整初值
  96.           MOV A,#0            ;使之正常时显示0%
  97. LBB2:     LCALL HEX2BCD1      ;调用数值转换程序
  98.           LCALL CONV200       ;调用LCD显示程序
  99.           MOV BJZC,JSSZ+2     ;取出传感器检测到的电压读数(原始数据),做报警比较
  100.           MOV BJWX,#WXBJZ2+XIUZ2 ;实际危险报警值=设定值/倍率+修正值
  101.           MOV BJJG,#JGBJZ2+XIUZ2 ;实际警告报警值=设定值/倍率+修正值

  102.           LCALL DELAY3        ;延时,使其能看清楚看到检测到的数值

  103.           DEC JJCYCS
  104.           MOV A,JJCYCS
  105.           JNZ JJJCCX1         ;连续采样几次(未到则返回)

  106.           JNB BUSY,$          ;如果语言正在播放,则等待
  107.           MOV YY_DAT,#6       ;报出“检测完毕”
  108.           LCALL YUYIN         ;开始语音播放
  109.           LCALL DELAY
  110.           LCALL DELAY
  111.           MOV YYBZ,#JSSZ+2    ;设酒精报警语音播放标志
  112.           LCALL BJBJ1         ;调用报警程序
  113.           LCALL DELAY3        ;延时
  114.           RET

  115. ;***************************************************
  116. ;=========================================
  117. ;以下为两个单字节十六进制相乘
  118. ;入口:A*B
  119. ;出口:16位低字节放A中,高字节放B中
  120. ;=========================================
  121. HEX2BCD1: MUL AB
  122.           MOV R6,B
  123.           MOV R7,A
  124.           MOV JJCQ,A        ;为显示0%作准备
  125. ;=========================================
  126. ;以下为双字节十六进制整数转换成双字节BCD码整数
  127. ;入口条件:待转换的双字节十六进制整数在R6、R7中。
  128. ;出口信息:转换后的三字节BCD码整数在R3、R4、R5中。
  129. ;影响资源:PSW、A、R2~R7,堆栈需求:2字节
  130. ;=========================================         
  131.           CLR A             ;BCD码初始化
  132.           MOV R3,A
  133.           MOV R4,A
  134.           MOV R5,A
  135.           MOV R2,#10H       ;转换双字节十六进制整数
  136. HB3:      MOV A,R7          ;从高端移出待转换数的一位到CY中
  137.           RLC A
  138.           MOV R7,A
  139.           MOV A,R6
  140.           RLC A
  141.           MOV R6,A
  142.           MOV A,R5          ;BCD码带进位自身相加,相当于乘2
  143.           ADDC A,R5
  144.           DA A              ;十进制调整
  145.           MOV R5,A
  146.           MOV A,R4
  147.           ADDC A,R4
  148.           DA A
  149.           MOV R4,A
  150.           MOV A,R3
  151.           ADDC A,R3
  152.           MOV R3,A          ;双字节十六进制数的万位数不超过6,不用调整
  153.           DJNZ R2,HB3       ;处理完16bit

  154. ;=========================================
  155. ;以下为把BCD码提取出并送显示寄存器70H~73H
  156. ;入口:;三字节BCD码整数在R3(高位为十万低位为万)、
  157. ;R4(高位为千低位为百)、R5(高位为十低位为个)中。
  158. ;出口:73H-70H(舍去十万、万位)
  159. ;=========================================
  160.           MOV A,R4
  161.           ANL A,#11110000B
  162.           SWAP A
  163.           MOV 73H,A
  164.           MOV A,R4
  165.           ANL A,#00001111B
  166.           MOV 72H,A
  167.           MOV A,R5
  168.           ANL A,#11110000B
  169.           SWAP A
  170.           MOV 71H,A
  171.           MOV A,R5
  172.           ANL A,#00001111B
  173.           MOV 70H,A

  174.           RET

  175. ;==============================================
  176. ;以下为LCD显示有害气体程序
  177. ;72H-70H 分别存放百位、十位、个位的数据
  178. ;==============================================
  179. CONV100:  MOV  A,73H         ;加载百位数据
  180.           MOV  LCD_X,#1      ;设置显示位置
  181.           CJNE A,#00H,CONV110
  182.           MOV  A,#" "        ;百位数等于0显示空格
  183.           MOV  B,LCD_X
  184.           CALL  LCDP2
  185.           MOV  A,72H         ;十位
  186.           CJNE A,#00H,CONV120
  187.           INC  LCD_X         ;调整显示地址
  188.           MOV  A,#" "        ;十位数等于0显示空格
  189.           MOV  B,LCD_X
  190.           CALL  LCDP2
  191.           MOV  A,71H         ;十位
  192.           CJNE A,#00H,CONV130
  193.           INC  LCD_X         ;调整显示地址
  194.           MOV  A,#" "        ;十位数等于0显示空格
  195.           MOV  B,LCD_X
  196.           CALL  LCDP2
  197.           JMP  CONV140

  198. CONV110:  CALL  SHOW_DIG2    ;显示数据

  199. CONV120:  INC  LCD_X         ;调整显示地址
  200.           MOV  A,72H         ;十位
  201.           CALL  SHOW_DIG2

  202. CONV130:  INC  LCD_X         ;调整显示地址
  203.           MOV  A,71H         ;十位
  204.           CALL  SHOW_DIG2

  205. CONV140:  INC  LCD_X         ;调整显示地址
  206.           MOV  A,70H         ;个位
  207.           CALL  SHOW_DIG2

  208.           RET
  209. ;=================================================
  210. ;以下为LCD显示酒精浓度程序
  211. ;73H-70H 分别存放个位、小数后1位、后2位、后3位的数据
  212. ;=================================================
  213. CONV200:  MOV A,JJCQ
  214.           JNZ BBL1
  215.           MOV LCD_X,#0       ;当个位、十、百、千分位均为零时显示0%
  216.           MOV R0,#00H
  217. BBL2:     MOV A,#' '
  218.           MOV B,LCD_X
  219.           CALL LCDP2
  220.           INC LCD_X
  221.           INC R0
  222.           CJNE R0,#4,BBL2
  223.           MOV R0,#00H
  224.           CLR A              ;个位
  225.           CALL SHOW_DIG2
  226.           RET

  227. BBL1:     MOV  A,73H         ;加载个位数据
  228.           MOV  LCD_X,#0      ;设置显示位置
  229.           CALL  SHOW_DIG2    ;显示数据

  230.           INC  LCD_X         ;调整显示地址
  231.           MOV  A,#'.'
  232.           MOV  B,LCD_X
  233.           CALL  LCDP2

  234.           SJMP CONV120

  235. ;=========================================
  236. ;LCD 显示菜单1
  237. ;=========================================
  238. MENU_3:   MOV  DPTR,#M_OK31  ;指针指到显示信息区
  239.           MOV  A,#1          ;显示在第一行
  240.           CALL  LCD_PRINT
  241.           MOV  DPTR,#M_OK32  ;指针指到显示信息区
  242.           MOV  A,#2          ;显示在第二行
  243.           CALL  LCD_PRINT
  244.           MOV  DPTR,#M_OK33  ;指针指到显示信息区
  245.           MOV  A,#3          ;显示在第二行
  246.           CALL  LCD_PRINT
  247.           MOV  DPTR,#M_OK34  ;指针指到显示信息区
  248.           MOV  A,#4          ;显示在第二行
  249.           CALL  LCD_PRINT
  250.           RET
  251. M_OK31:   DB"有害气体浓度:  ",0
  252. M_OK32:   DB"           PPM  ",0
  253. M_OK33:   DB"检测结果:      ",0
  254. M_OK34:   DB"                ",0

  255. ;=========================================
  256. ;LCD 显示菜单2
  257. ;=========================================
  258. MENU_4:   MOV  DPTR,#M_OK41  ;指针指到显示信息区
  259.           MOV  A,#1          ;显示在第一行
  260.           CALL  LCD_PRINT
  261.           MOV  DPTR,#M_OK42  ;指针指到显示信息区
  262.           MOV  A,#2          ;显示在第二行
  263.           CALL  LCD_PRINT
  264.           MOV  DPTR,#M_OK43  ;指针指到显示信息区
  265.           MOV  A,#3          ;显示在第二行
  266.           CALL  LCD_PRINT
  267.           MOV  DPTR,#M_OK44  ;指针指到显示信息区
  268.           MOV  A,#4          ;显示在第二行
  269.           CALL  LCD_PRINT
  270.           RET
  271. M_OK41:   DB"酒精浓度:    ",0
  272. M_OK42:   DB"          % BAC ",0
  273. M_OK43:   DB"检测结果:      ",0
  274. M_OK44:   DB"                ",0

  275. ;=========================================
  276. ;LCD 显示菜单3
  277. ;=========================================
  278. MENU_5:   MOV  DPTR,#M_OK51  ;指针指到显示信息区
  279.           MOV  A,#1          ;显示在第一行
  280.           CALL  LCD_PRINT
  281.           MOV  DPTR,#M_OK52  ;指针指到显示信息区
  282.           MOV  A,#2          ;显示在第二行
  283.           CALL  LCD_PRINT
  284.           MOV  DPTR,#M_OK53  ;指针指到显示信息区
  285.           MOV  A,#3          ;显示在第二行
  286.           CALL  LCD_PRINT
  287.           MOV  DPTR,#M_OK54  ;指针指到显示信息区
  288.           MOV  A,#4          ;显示在第二行
  289.           CALL  LCD_PRINT
  290.           RET
  291. M_OK51:   DB"进入酒精检测程序",0
  292. M_OK52:   DB"传感器预热请稍等",0
  293. M_OK53:   DB"...  ... ",0
  294. M_OK54:   DB"倒计时:    S  ",0

  295. ;=========================================
  296. ;LCD 显示菜单4
  297. ;=========================================
  298. MENU_6:   MOV  DPTR,#M_OK61  ;指针指到显示信息区
  299.           MOV  A,#1          ;显示在第一行
  300.           CALL  LCD_PRINT
  301.           MOV  DPTR,#M_OK62  ;指针指到显示信息区
  302.           MOV  A,#2          ;显示在第二行
  303.           CALL  LCD_PRINT
  304.           MOV  DPTR,#M_OK63  ;指针指到显示信息区
  305.           MOV  A,#3          ;显示在第二行
  306.           CALL  LCD_PRINT
  307.           MOV  DPTR,#M_OK64  ;指针指到显示信息区
  308.           MOV  A,#4          ;显示在第二行
  309.           CALL  LCD_PRINT
  310.           RET
  311. M_OK61:   DB"现在开始酒精检测",0
  312. M_OK62:   DB"注意:          ",0
  313. M_OK63:   DB"嘴巴要距离传感器",0
  314. M_OK64:   DB"5---10cm轻轻吹气",0
  315. ;=========================================
  316. ;以下为主机串行通信程序
  317. ;占用资源:R0~R4,A、40H、50H
  318. ;=========================================
  319. COM:   MOV A,TMOD           ;设置T1工作方式为方式2、T0工作方式保持不变
  320.        MOV FSJCQ,A
  321.        ORL A,#00101111B
  322.        MOV TMOD,A
  323.        MOV TH1,#0FDH        ;11.0592MHz 晶振,波特率=9600,时长0.6695
  324.        MOV TL1,#0FDH
  325.        MOV SCON,#0D8H       ;置串行模式3,SM2=1,允许接收
  326.        SETB TR1             ;启动T1
  327.        LCALL COM1           ;调用一线发码子程序
  328.        MOV TMOD,FSJCQ       ;恢复T1、T0原先的工作方式
  329.        RET

  330. COM1:   MOV A,R2            ;发送地址帧
  331.         MOV SBUF,A
  332.         JNB TI,$
  333.         CLR TI
  334.         JNB RI,$            ;等待从机应答
  335.         CLR RI
  336.         MOV A,SBUF
  337.         XRL A,R2
  338.         JNZ MS104           ;判应答地址是否相符
  339.         CLR TB8             ;地址符合,准备发送命令
  340.         MOV SBUF,R3         ;发送发送或接收数据命令
  341.         JNB TI,$
  342.         CLR TI
  343.         JNB RI,$            ;等待从机应答
  344.         CLR RI
  345.         MOV A,SBUF          ;取应答信息
  346.         JNB ACC.7,MS102     ;判断是否出错
  347. MS101:  SETB TB8
  348.         MOV SBUF,#0FFH      ;不相符重新联络
  349.         JNB TI,$
  350.         CLR TI
  351.         SJMP COM1           ;转重发地址

  352. MS102:  CJNE R3,#00H,MS103  ;判是否要求从机接收数据
  353.         JNB ACC.0,MS101     ;从机接收数据准备就绪否?
  354.         MOV R0,#FSSZ        ;主机发送的数据块首址
  355.         MOV R4,#BITE        ;设数据块长度(9字节)
  356. LPTX:   MOV SBUF,@R0        ;主机发送数据块
  357.         JNB TI,$            ;等待发送完1帧
  358.         CLR TI
  359.         INC R0              ;修改地址指针
  360.         DJNZ R4,LPTX        ;判数据块是否传完
  361.         SJMP MS104          ;返回主程序

  362. MS103:  JNB ACC.1,MS101     ;从机发送数据准备就绪否?
  363.         MOV R1,#JSSZ        ;主机接收的数据块首址
  364.         MOV R4,#BITE        ;设数据块长度(9字节)
  365. LPRX:   JNB RI,LPRX         ;等待接收完1帧
  366.         CLR RI
  367.         MOV A,SBUF          ;取出接收到的字符
  368.         MOV @R1,A
  369.         INC R1
  370.         DJNZ R4,LPRX        ;未接收完则继续

  371. MS104:  CLR TR1             ;关闭T1
  372.         RET


  373. ;=========================================
  374. ;报警比较和显示程序
  375. ;有害气体浓度:≥200PPM→语音报警并 显示"浓度超标,危险!"
  376. ;             ≥120PPM→语音报警并 显示"浓度偏高,请注意!"
  377. ;             <120PPM→语音不报警 显示"浓度未超标"
  378. ;酒精浓度:   ≥0.05% BCA→语音报警并 显示"浓度超标,危险!"
  379. ;            ≥0.02% BCA→语音报警并 显示"浓度偏高,请注意!"
  380. ;            <0.02% BCA→语音不报警 显示"浓度未超标"
  381. ;=========================================
  382. BJBJ1:    MOV A,BJZC
  383.           SUBB A,BJWX          ;与超标设定值进行比较
  384.           JC BL2

  385.           LCALL WENZBJ1        ;显示菜单1
  386.           LCALL DELAY          ;延时
  387.           LCALL DELAY          ;延时
  388.           LCALL WENZBJ4        ;显示菜单1-4,形成闪烁效果
  389.           LCALL DELAY          ;延时
  390.           LCALL DELAY          ;延时
  391.           LCALL WENZBJ1        ;显示菜单1

  392.           MOV A,YYBZ
  393.           CJNE A,#JSSZ+1,BL1   ;语音段播放识别
  394.           MOV YY_DAT,#2        ;有害气体检测时报出“车内有害气体浓度过高,请排除”
  395.           SJMP BL4
  396. BL1:      CJNE A,#JSSZ+2,BL6   ;语音段播放识别
  397.           MOV YY_DAT,#9        ;酒精检测时报出“酒精浓度偏高,你是不是喝酒了,要小心开车哦”
  398.           SJMP BL4

  399. BL2:      MOV A,BJZC           ;取ACC读数值(存在45H里)               ;
  400.           SUBB A,BJJG          ;与偏高设定值进行比较
  401.           JC BL5               ;
  402.           LCALL WENZBJ2        ;显示菜单2

  403.           LCALL DELAY          ;延时
  404.           LCALL DELAY          ;延时
  405.           LCALL WENZBJ4        ;显示菜单4,形成闪烁效果
  406.           LCALL DELAY          ;延时
  407.           LCALL DELAY          ;延时
  408.           LCALL WENZBJ2        ;显示菜单2

  409.           MOV A,YYBZ
  410.           CJNE A,#JSSZ+1,BL3   ;语音段播放识别
  411.           JNB BUSY,$
  412.           MOV YY_DAT,#2        ;有害气体检测时报出“车内有害气体浓度过高,请排除”
  413.           SJMP BL4
  414. BL3:      CJNE A,#JSSZ+2,BL6   ;语音段播放识别
  415.           JNB BUSY,$
  416.           MOV YY_DAT,#8        ;酒精检测时报出“酒精浓度过高,你喝多了,为了您的安全,请不要开车”
  417. BL4:      LCALL YUYIN          ;开始语音播放
  418.           SJMP BL6

  419. BL5:      LCALL WENZBJ3        ;显示菜单1-3
  420.           MOV A,YYBZ
  421.           CJNE A,#JSSZ+2,BL6   ;语音段播放识别
  422.           JNB BUSY,$
  423.           MOV YY_DAT,#7        ;酒精检测时报出“酒精浓度没有超标”
  424.           LCALL YUYIN          ;开始语音播放

  425. BL6:      RET

  426. WENZBJ1:  MOV  DPTR,#BJ10      ;超标显示的内容
  427.           SJMP BL7
  428. WENZBJ2:  MOV  DPTR,#BJ20      ;偏高显示的内容
  429.           SJMP BL7
  430. WENZBJ3:  MOV  DPTR,#BJ30      ;未超标显示的内容
  431.           SJMP BL7
  432. WENZBJ4:  MOV  DPTR,#BJ40      ;未超标显示的内容
  433. BL7:      MOV  A,#98H          ;设置 LCD 显示的地址(第四行)
  434.           CALL  WCOM           ;写入指令
  435. BL8:      CLR  A               ;填入字符
  436.           MOVC  A,@A+DPTR      ;由信息区取出字符
  437.           CJNE  A,#0,BL9       ;判断是否为结束码
  438.           RET
  439. BL9:      CALL  WDATA          ;写入数据
  440.           INC  DPTR            ;指针加1
  441.           JMP  BL8             ;继续填入字符

  442. BJ10:     DB "浓度超标,危险!",0
  443. BJ20:     DB "浓度偏高,请注意",0
  444. BJ30:     DB "  浓度没有超标  ",0
  445. BJ40:     DB "                ",0

  446. ;***********************************************************
  447. JIUJJC:   MOV FSSZ+1,#01H     ;命令10号从机打开有害气体传感器
  448.           MOV R2,#0AH         ;与10号从机串口通信,多功能板地址为0AH
  449.           MOV R3,#00H         ;主机要求从机接收数据块
  450.           LCALL COM           ;主机与多功能检测板串口通信,要求其接收9个字节数据块
  451.           MOV YY_DAT,#3       ;报出“现在进入酒精检测程序,请等待十秒钟”
  452.           JNB BUSY,$
  453.           LCALL YUYIN         ;开始语音播放
  454.           ACALL MENU_5
  455.           JNB BUSY,$
  456.           MOV DJSJCQ,#10
  457.           MOV A,DJSJCQ
  458. K2:       MOV B,#1
  459.           LCALL HEX2BCD1      ;调用数值转换程序
  460.           LCALL CONV300       ;调用LCD显示程序
  461.           MOV A,#3            ;延时
  462. LBB23:    LCALL DELAY
  463.           DEC A
  464.           JNZ LBB23
  465.           DEC DJSJCQ
  466.           MOV A,DJSJCQ
  467.           CJNE A,#00H,K2
  468.           MOV YY_DAT,#4       ;报出“现在开始酒精检测”
  469.           JNB BUSY,$
  470.           LCALL YUYIN         ;开始语音播放
  471.           ACALL MENU_6
  472.           MOV A,#10           ;延时
  473. LBB33:    LCALL DELAY
  474.           DEC A
  475.           JNZ LBB33
  476.           MOV YY_DAT,#5       ;报出“请把嘴巴对准探头轻轻吹气”
  477.           JNB BUSY,$
  478.           LCALL YUYIN         ;开始语音播放
  479.           RET

  480. CONV300:  MOV  A,71H          ;十位
  481.           CJNE A,#00H,K3
  482.           MOV A,#9CH          ;调整显示地址
  483.           CALL  WCOM          ;写入命令
  484.           MOV  A,#" "         ;百位数等于0显示空格
  485.           CALL  WDATA         ;写入数据
  486.           SJMP K4
  487. K3:       MOV A,#9CH          ;调整显示地址
  488.           CALL  WCOM          ;写入命令
  489.           MOV  A,71H
  490.           ADD  A,#30H         ;加30H,转换为ASCII码
  491.           CALL  WDATA         ;写入数据

  492. K4:       MOV A,#9DH          ;调整显示地址
  493.           CALL  WCOM          ;写入命令
  494.           MOV  A,70H
  495.           ADD  A,#30H         ;加30H,转换为ASCII码
  496.           CALL  WDATA         ;写入数据
  497.           RET
  498. ;-------------------------------------------------------







  499. ;以下程序通用

  500. ;=============================================
  501. ;在LCD的第二行显示数据字符
  502. ;A=ASCII 数据, B=位置变量
  503. ;==============================================
  504. LCDP2:    PUSH  ACC           ;在LCD的第二行显示字符
  505.           MOV  A,B            ;设置显示地址
  506.           ADD  A,#90H         ;设置LCD的第二行地址
  507.           CALL  WCOM          ;写入命令
  508.           POP  ACC            ;由堆栈取出A
  509.           CALL  WDATA         ;写入数据
  510.           RET
  511. ;-------------------------------------------------------
  512. SHOW_DIG2:                   ;在 LCD 的第二行显示数字
  513.           ADD  A,#30H        ;加30H,转换为ASCII码
  514.           MOV  B,LCD_X       ;确定显示位置
  515.           CALL  LCDP2        ;送显示
  516.           RET

  517. ;=================================================
  518. ;对 LCD 做初始化设置
  519. ;=================================================
  520. SET_LCD:  MOV A,#34H      ;34H--扩充指令操作
  521.           CALL  WCOM         ;写入命令
  522.    MOV A,#30H      ;30H--基本指令操作
  523.           CALL  WCOM         ;写入命令
  524.    MOV A,#01H      ;清除显示
  525.           CALL  WCOM         ;写入命令
  526.           MOV A,#06H      ;指定在资料写入或读取时,光标的移动方向
  527.           CALL  WCOM         ;DDRAM 的地址计数器(AC)加1
  528.    MOV A,#0CH      ;开显示,关光标,不闪烁
  529.           CALL  WCOM         ;写入命令
  530.           RET

  531. ;===============================================
  532. ;命令写入子程序
  533. ;RS=L,RW=L,D0-D7=指令码,E=高脉冲
  534. ;以8位控制方式将命令写至LCD
  535. ;===============================================
  536. WCOM:    LCALL CHK_BUSY       ;写入指令
  537.   CLR LCD_RS
  538.   CLR LCD_RW
  539.   MOV LCD_SJ,A
  540.   SETB LCD_EN
  541.   NOP
  542.   NOP
  543.   CLR LCD_EN
  544.   RET
  545. ;===============================================
  546. ;数据写入子程序
  547. ;RS=H,RW=L,D0-D7=指令码,E=高脉冲
  548. ;以8位控制方式将数据写至LCD
  549. ;===============================================
  550. WDATA:    MOV  LCD_SJ,A       ;写入数据
  551.           SETB  LCD_RS
  552.           CLR  LCD_RW
  553.           SETB  LCD_EN
  554.           CALL  DE
  555.           CLR  LCD_EN
  556.           CALL  DE
  557.           RET
  558. ;===============================================
  559. ;测LCD忙碌子程序
  560. ;RS=0,RW=1,E=H,D0-D7=状态字
  561. ;===============================================
  562. CHK_BUSY: MOV LCD_SJ,#0FFH   ;测忙碌子程序
  563.    CLR LCD_RS
  564.    SETB LCD_RW
  565.    SETB LCD_EN
  566.    JB LCD_SJ.7,$
  567.    CLR LCD_EN
  568.    RET

  569. ;==================================================
  570. ;在LCD的显示字符串
  571. ;DPTR = 放字符串的地址
  572. ;==================================================
  573. LCD_PRINT:CJNE  A,#1,LINE2  ;判断是否为第一行
  574. LINE1:    MOV  A,#80H       ;设置 LCD 的第一行地址
  575.           CALL  WCOM        ;写入命令
  576.           CALL  CLR_LINE    ;清除该行字符数据
  577.           MOV  A,#80H       ;设置 LCD 的第一行地址
  578.           CALL  WCOM        ;写入命令
  579.           JMP  FILL

  580. LINE2:    CJNE  A,#2,LINE3  ;判断是否为第二行
  581.           MOV  A,#90H       ;设置 LCD 的第二行地址
  582.           CALL  WCOM        ;写入命令
  583.           CALL  CLR_LINE    ;清除该行字符数据
  584.           MOV  A,#90H       ;设置 LCD 的第二行地址
  585.           CALL  WCOM
  586.           JMP  FILL

  587. LINE3:    CJNE  A,#3,LINE4  ;判断是否为第三行
  588.           MOV  A,#88H       ;设置 LCD 的第三行地址
  589.           CALL  WCOM        ;写入命令
  590.           CALL  CLR_LINE    ;清除该行字符数据
  591.           MOV  A,#88H       ;设置 LCD 的第三行地址
  592.           CALL  WCOM
  593.           JMP  FILL

  594. LINE4:    MOV  A,#98H       ;设置 LCD 的第四行地址
  595.           CALL  WCOM        ;写入命令
  596.           CALL  CLR_LINE    ;清除该行字符数据
  597.           MOV  A,#98H       ;设置 LCD 的第四行地址
  598.           CALL  WCOM

  599. FILL:     CLR  A            ;填入字符
  600.           MOVC  A,@A+DPTR   ;由信息区取出字符
  601.           CJNE  A,#0,LC1    ;判断是否为结束码
  602.           RET

  603. LC1:      CALL  WDATA       ;写入数据
  604.           INC  DPTR         ;指针加1
  605.           JMP  FILL         ;继续填入字符
  606. ;===============================================
  607. ;清除一行 LCD 的字符
  608. ;输入一行空格,来替代原显示字符
  609. ;===============================================
  610. CLR_LINE: MOV  R0,#16       ;清除该行 LCD 的字符
  611. CL1:      MOV  A,#' '
  612.           CALL  WDATA
  613.           DJNZ  R0,CL1
  614.           RET
  615. ;**********************************************************
  616. ;延时子程序
  617. ;**********************************************************
  618. DE:      MOV  R7,#229        ;延时 500 微秒,此条2个机器周期
  619.          DJNZ  R7,$
  620.          RET    ;此条2个机器周期,总延时(229*2+2+2)*(12/11.0592)≈500uS

  621. DELAY:   MOV  R5,#20         ;延时200MS
  622. DELAY1:  MOV  R6,#96         ;100
  623. DL1:     MOV  R7,#96         ;100
  624.          DJNZ  R7,$
  625.          DJNZ  R6,DL1
  626.          DJNZ  R5,DELAY1     ;96*2*48*(12/11.0592)+2*(12/11.0592)≈10000uS=10mS
  627.          RET        

  628. DELAY2:  MOV  R6,#10         ;延时5MS
  629. DL2:     MOV  R7,#229        ;100微秒
  630.          DJNZ  R7,$
  631.          DJNZ  R6,DL2
  632.          DJNZ  R5,DELAY2
  633.          RET

  634. DELAY3:  MOV  R5,#20         ;延时200MS
  635. DELA:    MOV  R6,#96
  636. DL3:     MOV  R7,#96
  637.          DJNZ  R7,$
  638.          DJNZ  R6,DL3
  639.          DJNZ  R5,DELA
  640.          RET   
  641. ;**********************************************************
  642. ;语音驱动和播放程序
  643. ;**********************************************************
  644. ;50H为语音段地址暂存器,1到210段,实际用到40
  645. ;50H为E0H~E7H时分别代表自低往高的8级音量
  646. ;在语音播放过程中发送F2H至50H可循环播放当前地址语音
  647. ;发送FEH至50H停止播放语音
  648. ;****************************************************
  649. YUYIN: MOV A,TMOD          ;设置T1工作方式为方式1、T0工作方式保持不变
  650.        MOV FSJCQ,A
  651.        ORL A,#00011111B
  652.        MOV TMOD,A
  653.        MOV R6,#08H         ;发码8位循环数据
  654.        LCALL ONE_LINE      ;调用一线发码子程序
  655.        MOV TMOD,FSJCQ          ;恢复T1、T0原先的工作方式
  656.        RET

  657. ONE_LINE:                  ;////一线发码子程序
  658.        SETB YYRST          ;复位
  659.        MOV R7,#2           ;延时2MS
  660.        LCALL DELAY1MS
  661.        CLR YYRST           ;延时使系统稳定
  662.        MOV R7,#6           ;延时6MS
  663.        LCALL DELAY1MS
  664.        CLR YYSDA           ;唤醒语音芯片
  665.        MOV R7,#17          ;延时17MS
  666.        LCALL DELAY1MS
  667.        MOV A,YY_DAT

  668. LP1:   SETB YYSDA
  669.        RRC A               ;分辨50H内的数据各位是高电平还是低电平
  670.        JNC DIDIANPIN       ;高电平用高:低=2:1的脉宽表示
  671.        LCALL DELAY200US
  672.        LCALL DELAY200US
  673.        LCALL DELAY200US
  674.        CLR YYSDA
  675.        LCALL DELAY200US
  676. LP2:   DJNZ R6,LP1         ;查看数据是否发完,未发完继续发
  677.        MOV R6,#08H
  678.        SETB YYSDA
  679.        RET

  680. DIDIANPIN:                 ;低电平用高:低=1:2的脉宽表示
  681.        LCALL DELAY200US
  682.        CLR YYSDA
  683.        LCALL DELAY200US
  684.        LCALL DELAY200US
  685.        LCALL DELAY200US
  686.        SJMP LP2

  687. ;以下为延时子程序
  688. DELAY200US:                ;延时200US子程序,晶振11.0592MHz,方式1
  689.        MOV  TH1,#0FFH
  690.        MOV  TL1,#47H
  691.        SETB TR1
  692. LOP1:  JBC  TF1,NEXT1
  693.        SJMP LOP1
  694. NEXT1: CLR TR1
  695.        RET

  696. DELAY1MS:MOV  TH1,#0FCH    ;延时1ms子程序
  697.        MOV  TL1,#66H
  698.        SETB TR1
  699. LOP2:  JBC  TF1,NEXT2
  700.        SJMP LOP2
  701. NEXT2: DJNZ R7,DELAY1MS
  702.        CLR TR1
  703.        RET


  704. END
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:199787 发表于 2017-6-15 14:18 | 只看该作者
楼主有没有c语言的,急求。。
回复

使用道具 举报

板凳
ID:587868 发表于 2019-7-23 22:50 | 只看该作者
学习了,楼主真厉害!!!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表