单片机源程序如下:
- 软件设计源程序
- ;30H:存放旧浓度地址 31H:现在浓度值(A/D转换后换算取得的新浓度)
- ;40H:初始调零值=0 32H:A/D转换后的值 33H:A/D转换完成(中断完成)标志
- ;50H:初始预警值=50 55H:存放BCD转换中的百位数
- ;56H:存放BCD转换中的十位数 60H:转换完的个位存放地址
- ;61H:转换完的十位存放地址 62H:转换完的百位存放地址
- ;63H:存放转换完的压缩BCD码供显示用 R1:BCD转换中存放的百位数(可做百位报警)
- ;R2:BCD转换中存放十位数>60H R3:当前浓度值保存
- ;R4:设置改变模式延时时间 R5,R6:延时程序中用到
- ;SP:堆栈->#70H
- ;* * * * * * * * * * * * * * * * *
- ; 可燃气体探测报警器
- ; 2008.5.20
- ;* * * * * * * * * * * * * * * * *
- ;* * * * * * * * * * * * * * * * *
- ; 各引脚用途及系统功能说明
- ;P1.4 接绿灯,指示正常
- ;P1.5 接黄灯,指示故障
- ;P1.6 接红灯,灯光报警
- ;P1.7 接喇叭,音乐报警
- ;P2.0 接ADC0809
- ;P2.2 接调零开关
- ;P2.3 接继电器,控制排气阀门
- ;* * * * * * * * * * * * * * * * *
- ; 主 程 序
- ;* * * * * * * * * * * * * * * * *
- ORG 00H
- JMP START ;主程序入口地址
- ORG 03H
- JMP INTO ;外中断INTO入口
- ORG 0BH
- JMP ITOP ; 定时器0中断入口
- ORG 0100H
- START: MOVIE,#10000001B ;INT0中断使能
- MOVIP,#00000001B ;INT0中断优先
- MOVTCON,#00000000B ;设置INT0为电平触发
- MOVSCON,#00000000B ;串行口发送,接收标志位请0
- MOV SP,#60H ;设堆栈指针
- MOV TMOD,#01H ;设置T0为方式1
- CALL PT0M0
- HERE: AJMP HERE ;自身跳转
- PT0M0: MOV TL0,#0CH ;T0中断服务程序,T0重新置初值
- MOV TH0,#0FEH
- SETB TR0 ;启动T0
- SETB ET0 ;允许T0中断
- SETB EA ;CPU开中断
- RET
- ITOP: MOV TL0,#0CH ;T0中断服务程序,T0置初值
- MOV TH0,0FEH
- CPL P1.0 ;P1.0状态取反
- RETI
- ACALL LED ;调用LED自检子程序
- MOV 33H,#00H ;设置中断完成标志为0
- MOV DPTR,#0FEFFH ;ADC0809的端口地址
- MOVX @DPTR,A ;使BUS为高阻抗,令ADC0809开始转换
- WAIT:MOV A,33H ;等待A/D转换完成信号
- JNZ INTOK
- JMP WAIT ;未完成则跳回等待
- INTOK: MOV A,32H ;将最新的浓度值存入累加器中,(若A/D未工作,则A=0)
- JNZ L1
- MOV A,30H
- JMP L2
- L1: MOV 30H,31H
- MOV A,31H ;将新浓度载入累加器
- L2: CALL BCD ;调用BCD码调整程序
- CALL DISP ;显示当前浓度
- CALL ADZERO ;调用零点调整子程序
- CALL ALARM ;调用判断报警程序
- CALL BCD
- CALL DISP ;调用显示子程序
- CLR A ;清除累加器值
- JMP START ;返回
- ; 在主程序通过对33H中数值的判断断定A/D是否转换完成
- ; 当33H中为1时,转换完成,程序调用调零、报警、显示模块对输入数据进行处理。
- ;* * * * * * * * * * * * * * * * *
- ; LED自检子程序
- ;* * * * * * * * * * * * * * * * *
- LED: CLR P1.4 ;绿灯
- CLR P1.5 ;黄灯
- CLR P1.6 ;红灯
- CALL DELAY2s
- DELAY2s: MOV R5,#100
- DLY1: MOV R6,#100
- DLY2: MOV R7,#100
- DJNZ R7,$
- DJNZ R6,DLY2
- DJNZ R5,DLY1
- RET
- SETB P1.4
- SETB P1.5
- SETB P2.6
- RET
- ;* * * * * * * * * * * * * * * * *
- ; 调零子程序
- ; (初始报警值为50)
- ;* * * * * * * * * * * * * * * * *
- ADZERO : CALL DELAY20ms
- JB P2.2,JMP1 ;判断调零按纽是否按下,没有则跳JMP1
- LOOP1: CALL DELAY20ms
- JNB P2.2,$ ;消除抖动延时
- MOV A,40H ;将调零预设值40H送入
- CLR C ;清除进位标志
- SUBB A,#01H ;调零值减1
- JNC LOOP2 ;未借位则跳LOOP2
- MOV A,#05H ;有借位则重设调零值为5
- LOOP2: MOV 40H,A ;将调零值送回40H保存
- MOV A,R3 ;将当前浓度值送入A
- JZ XEND
- DEC A ;当前浓度值减1(响应调整变化)
- XEND1: MOV 30H,A ;送回30H保存
- MOV 31H,A ;送回31H保存
- CALL BCD
- CALL DISP
- JMP LOOP1
- XEND: MOV A,#63H
- JMP XEND1
- JMP1: RET
- ;* * * * * * * * * * * * * * * * *
- ; 3位串行静态显示子程序
- ;* * * * * * * * * * * * * * * * *
- BCD: MOV 55H,#00H ;存放BCD转换中的百位数
- MOV 56H,#00H ;存放BCD转换中的十位数
- CLR C ;清楚进位标志为下面的SUBB准备
- MOV R2,#00H ;清楚R2
- CHAN: SUBB A,#64H ;减100
- JC CHAN1 ;不能减,转
- INC R1 ;百位值
- JMP CHAN ;循环判断百位
- CHAN1: ADD A,#64H ;还原百位数
- CLR C ;清楚进位标志为下面的SUBB准备
- CHAN2: SUBB A,#0AH ;减10
- JC CHAN3 ;不够减,跳
- INC R2 ;够减十位加1
- JMP CHAN2 ;重复减10
- CHAN3: ADD A,#0AH ;还原十位数
- MOV 61H,R2 ;把十位数放61H
- MOV 60H,A ;把个位数放60H
- MOV 62H,R1 ;把百位数放62H
- RET
- DISP: MOV R7,#03H
- MOV R0,#60H
- LED1: MOV A,@R0
- MOV DPTR,#TABLE
- LED2: MOVC A,@A+DPTR
- MOV SBUF,A
- JNB TI,$
- CLR TI
- INC R0
- DJNZ R7,LED1
- RET
- DELAY20ms: MOV R5,#40 ;设定20毫秒
- D1: MOV R6,#248
- DJNZ R6,$
- DJNZ R5,D1
- RET
- ;* * * * * * * * * * * * * * * * *
- ; 报警子程序
- ;* * * * * * * * * * * * * * * * *
- ALARM: MOV A,30H ;将当前浓度值送如累加器
- CLR C ;清除进位标志
- SUBB A,50H ;与预警值进行判断
- JNC GOOD1 ;若无借位,则当前浓度值高于或者等于预警值,跳GOOD1报警
- SETB P1.6 ;关闭声光报警
- SETB P1.7
- CLR P2.3 ;关闭排气阀门
- SETB P1.5 ;关闭黄色LED
- CLR P1.4 ;打开绿色LED(显示正常)
- RET
- GOOD1: CLR P1.6 ;打开声光报警(危险报警)
- CLR P1.7
- CLR P2.3 ;打开排气阀门
- SETB P1.5 ;关闭黄色LED
- SETB P1.4 ;关闭绿色LED(显示不正常?
- RET
- ;* * * * * * * * * * * * * * * * *
- ; 中断取值子程序
- ;* * * * * * * * * * * * * * * * *
- INTO: PUSH ACC ;将累加器值压入堆栈保存
- PUSH PSW ;将PSW值压入堆栈保存
- MOVX A,@DPTR ;将A/D转换好的值送入累加器
- MOV 32H,A ;将A/D读得的值存入32H保存
- CLR C
- SUBB A,51H ;判断获得的电压是否小于1V(50)
- JNC OK1
- MOV 32H,#00H ;当前A/D转换的电压小于1V,则A/D转换得的示数为00
- JMP EMP1
- OK1: MOV A,32H
- CALL ADJUST ;调用ADJUST将其调整为浓度对应的16进制
- CALL ADDD ;调用ADDD将其与调零预设值相加,得到调整后的16进制
- MOV 31H,A ;将调整后的值送入31H保存
- EMP1: MOVIE,#10000000B ;关闭INT0中断使能,关闭中断
- POP PSW ;至堆栈取回PSW值
- POP ACC ;至堆栈取回ACC值
- MOV 33H,#01H ;中断完成,设置完成标记33H为1
- RETI
- ;* * * * * * * * * * * * * * * * *
- ; 调整相加子程序
- ;* * * * * * * * * * * * * * * * *
- ADJUST: CLR C
- SUBB A,#32H ;将A/D转换的值减50再除10乘5可得当前浓度的16进制值
- MOV B,#0AH
- DIV AB
- MOV B,#05H
- MUL AB
- RET
- ADDD: ADD A,40H
- TABLE:
- DB 0C0H,0F9H,0A4H,0B0H,99H
- DB 92H, 82H, 0F8H,80H, 90H
- END
复制代码 |