單片機源程序如下:
- 軟件設計源程序
- ;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
復制代碼 |