|
- ;**************************************************
- ;平凡單片機(jī)工作室 作者:周堅(jiān)
- ;(c) Copyright 2003 Pingfan's McuStudio
- ;All rights Reserved
- ;cntrl.asm
- ;實(shí)驗(yàn):姬家寨電子科技實(shí)驗(yàn)室:姬學(xué)瑞
- ;功能描述:汽車傳感器控制儀程序,具體內(nèi)容請參考書
- ;**************************************************
- ;鍵盤緩沖區(qū)
- FIFO1 DATA 30H
- FIFO2 DATA 31H
- FIFO3 DATA 32H
- ;以下顯示緩沖區(qū)
- DISP1 DATA 40H
- DISP2 DATA 41H
- DISP3 DATA 42H
- DISPCTRL DATA 43H
- ;顯示控制字
- DISP_CTRL BIT 42H ;顯示控制字,如果為1顯示,為0不顯示
- ;鍵盤有鍵按下標(biāo)志
- K_MARK BIT 41H
- ;控制字堆棧
- STAC DATA 50H
- ;由FIFO得到的控制字
- CTRL DATA 33H
- ORG 0000H
- AJMP START
- ORG 40H
- START:
- MOV SP,#5FH ; 設(shè)置堆棧
- MOV P1,#0FFH
- MOV P2,#00H
- MOV P0,#0FFH
- SETB DISP_CTRL ;調(diào)用顯示程序前設(shè)置該位,要求顯示出來
- MOV DISP3,#8
- MOV DISP2,#8
- MOV DISP1,#8
- ACALL DISP ;顯示888
- ACALL D1S ;延時(shí)1S
- MOV DISP3,#16 ;H字符的代碼
- MOV DISP2,#17 ;消隱代碼
- MOV DISP1,#17
- ACALL DISP
- CLR A
- MOV DISPCTRL,A ;
- MOV R0,#20H
- MOV R7,#10H
- INIT:
- MOV @R0,A
- INC R0
- DJNZ R7,INIT ;清除20H到2FH單元的內(nèi)容
- SETB DISP_CTRL
- MOV DISPCTRL,#10
- MOV FIFO1,#0
- MOV FIFO2,#0
- MOV FIFO3,#0
- MAIN:
- INC DISPCTRL
- MOV A,DISPCTRL
- JZ RDISP
- AJMP MKEY
- RDISP:
- MOV DISPCTRL,#10
- ACALL DISP ;如果計(jì)數(shù)到255次,則刷新一次顯示
- MKEY:
- ACALL KEY ;調(diào)用鍵盤處理程序
- JB K_MARK,KEY_PROC ;如果有鍵被按下,則轉(zhuǎn)去鍵盤處理
- ;***************************以下將內(nèi)存對應(yīng)內(nèi)容輸出
- MOV A,20H
- NOP
- MOV 20H,A ;取出20H內(nèi)容,再轉(zhuǎn)入20H
- MOV P0,A
- SETB P2.3
- ACALL DOUT
- CLR P2.3 ;延時(shí)形成下降沿脈沖
- ;*******************************
- MOV A,21H
- NOP
- MOV 21H,A
- MOV P0,A
- SETB P2.4
- ACALL DOUT
- CLR P2.4
- ;*******************************
- MOV A,22H
- NOP
- MOV 22H,A
- MOV P0,A
- SETB P2.5
- ACALL DOUT
- CLR P2.5
- ;*********************************
- MOV A,23H
- NOP
- MOV 23H,A
- MOV P0,A
- SETB P2.6
- ACALL DOUT
- CLR P2.6
- MOV A,24H
- ;********************************
- MOV A,24H
- NOP
- MOV 24H,A
- MOV P0,A
- SETB P2.7
- ACALL DOUT
- CLR P2.7
- AJMP MAIN
- ;用于輸出的延時(shí)程序
- DOUT:
- PUSH PSW
- SETB RS1
- MOV R6,#3
- DJNZ R6,$
- POP PSW
- RET
- ;*****************************鍵盤處理
- ;數(shù)字鍵直接進(jìn)入鍵值FIFO
- ;功能鍵分別處理
- ;A:判斷待顯示的是否是合法的代碼,是則接受,并根據(jù)代碼作相應(yīng)動(dòng)作,顯示閃爍
- ;一次,如果不是合法的代碼,則不接受,并不閃爍
- ;合法的代碼為: 001-032,使各相位置1,使各繼電器吸合,斷路
- ; 033-040,使相應(yīng)位置1,串入電阻
- ; 101-132,使相應(yīng)位清0,各繼電器觸點(diǎn)吸合
- ;注意:
- ; 033-040代碼將相應(yīng)的0-7位清0,以防止繼電器觸點(diǎn)斷路.
- ; 101-108代碼在除將相應(yīng)的0-7位清0外,還要將32-39相應(yīng)位清0,防止串入電阻
- ;B鍵:顯示和消隱的切換開關(guān)
- ;C鍵:復(fù)位開關(guān),按下此鍵,將所有位(00-40)全部清0,使所有繼電器斷電(即全部觸點(diǎn)處
- ;于吸合狀態(tài)).
- KEY_PROC:
- CLR K_MARK ;清除有鍵按下標(biāo)志
- CLR C ;清進(jìn)位位
- MOV A,B ;取鍵值
- CJNE A,#10,KEY_NEXT1
- AJMP FUN_PROC ;如果鍵值等于10轉(zhuǎn)功能鍵處理
- KEY_NEXT1:
- JC DATA_PROC ;如果小于10,則到數(shù)字鍵處理
- AJMP FUN_PROC ;如果鍵值大于10則轉(zhuǎn)功能鍵處理
- DATA_PROC: ;數(shù)字鍵處理
- MOV FIFO3,FIFO2
- MOV FIFO2,FIFO1
- MOV FIFO1,B ;如果是數(shù)字鍵,則將數(shù)字進(jìn)入FIFO
- MOV DISP3,FIFO3
- MOV DISP2,FIFO2
- MOV DISP1,FIFO1
- ACALL DISP ;調(diào)用顯示程序
- AJMP MAIN ;數(shù)字程序處理完畢,重新開始循環(huán)
- ;***************************以下各功能鍵處理部份
- A_PROC: ;A鍵處理
- MOV A,FIFO3 ;取FIFO的首字節(jié)
- CLR C
- CJNE A,#2,A_1
- A_ERR:
- AJMP MAIN
- A_1:
- JC A_2
- AJMP MAIN
- A_2:
- MOV A,FIFO3 ;取首字節(jié)
- MOV B,#100
- MUL AB
- MOV R0,A
- MOV A,FIFO2
- MOV B,#10
- MUL AB
- ADD A,R0
- ADD A,FIFO1
- MOV R0,A
- CJNE A,#141,A_3
- AJMP MAIN
- A_3:
- JC A_4
- AJMP MAIN
- A_4:
- MOV A,R0
- CJNE A,#100,A_5
- AJMP MAIN
- A_5:
- JC A_6
- AJMP A_ACTION1
- A_6:
- MOV A,R0
- CJNE A,#41,A_7
- AJMP MAIN
- A_7:
- JC A_8
- AJMP MAIN
- A_ACTION1:
- DEC R0
- MOV CTRL,R0
- ACALL CLR_OUT
- CLR DISP_CTRL
- ACALL DISP
- ACALL D1S
- SETB DISP_CTRL
- ACALL DISP ;開顯示并閃爍一次
- AJMP MAIN
- A_8:
- MOV A,R0
- JNZ A_ACTION2
- AJMP MAIN
- A_ACTION2:
- DEC R0
- MOV CTRL,R0
- ACALL SET_OUT
- CLR DISP_CTRL
- ACALL DISP ;關(guān)顯示
- ACALL D1S
- SETB DISP_CTRL
- ACALL DISP ;閃爍一次
- AJMP MAIN
- FUN_PROC:
- MOV A,B
- SUBB A,#10
- JZ A_PROC
- DEC A
- JZ B_PROC ;B鍵處理
- DEC A
- JZ C_PROC ;C 鍵處理
- DEC A
- JZ D_PROC ;D鍵處理
- DEC A
- JZ E_PROC ;E 鍵處理
- DEC A
- JZ F_PROC ;F鍵處理
- KEY_ERR: ;如果不是以上鍵(可能雙鍵同時(shí)按下之類)
- NOP ;錯(cuò)誤處理,在此直接返回即可。
- AJMP MAIN
- B_PROC:
- CPL DISP_CTRL ;取反顯示控制
- ACALL DISP
- LJMP MAIN
- C_PROC:
- MOV 20H,#00H
- MOV 21H,#00H
- MOV 22H,#00H
- MOV 23H,#00H
- MOV 24H,#00H ;C鍵是開關(guān)重置鍵,將所有位清零
- MOV DISP3,#16 ;'H'
- MOV DISP2,#17 ;消隱
- MOV DISP1,#17 ;消隱
- ACALL DISP
- LJMP MAIN
- D_PROC:
- LJMP MAIN
- E_PROC:
- LJMP MAIN
- F_PROC:
- LJMP MAIN ;這四個(gè)鍵暫不使用
- ;**************************************置位
- SET_OUT:
- CLR C
- MOV A,CTRL ;CTRL是要設(shè)置的位
- CJNE A,#32,SET1
- AJMP SETPROC ;等于32要特殊處理
- SET1:
- JNC SETPROC ;大于32要特殊處理
- SET2: ;是1-32中的一個(gè)值
- MOV A,CTRL
- ACALL SETOUT1
- SETPROC: ;如果大于等于32,則作兩個(gè)動(dòng)作:
- MOV A,CTRL ;1.將相應(yīng)位置1,以串入電位器
- ACALL SETOUT1 ;將相應(yīng)的1-8位清0,以接通電路
- MOV A,CTRL
- SUBB A,#31
- ADD A,#100
- ACALL CLROUT1
- RET
- SETOUT1:
- MOV B,#8 ;先將哪個(gè)字節(jié)要設(shè)置求出
- DIV AB
- PUSH PSW
- SETB RS0 ;選第二工作區(qū)
- MOV R0,#1FH ;用R0作間址尋址
- INC A
- MOV R7,A
- LP:
- INC R0
- DJNZ R7,LP ;確定是哪個(gè)字節(jié)
- ;**************************************
- MOV A,B ;將除得的結(jié)果送A(哪一位)
- JZ LP3 ;如果是0,直接轉(zhuǎn),否則會(huì)有錯(cuò)
- MOV A,@R0 ;取這個(gè)字節(jié)
- MOV R7,#8 ;將這個(gè)字節(jié)循環(huán)右移8次
- MOV R6,B ;分兩段,一段由R6控制,正好將該位移到ACC.0的位置
- LP1:
- DEC R7 ;R7中減去R6已移的次數(shù)
- RR A
- DJNZ R6,LP1
- SETB ACC.0 ;由R6控制的移動(dòng)結(jié)束,該位處于ACC.0位置,置該位
- LP2:
- RR A
- DJNZ R7,LP2 ;剩下來該移動(dòng)的次數(shù)由R7中的值決定
- AJMP LP4
- LP3: ;這個(gè)是用來處理一種特殊情況,即某一字節(jié)的最低位
- MOV A,@R0 ;此時(shí)B中是0,如果仍用上法處理,會(huì)出錯(cuò),只要直接將
- SETB ACC.0 ;該位置1即可
- LP4:
- MOV @R0,A
- POP PSW
- RET
- CLR_OUT:
- CLR C
- MOV A,CTRL ;CTRL是要清的位
- CJNE A,#107,CLR1
- AJMP CLRPROC ;等于107,轉(zhuǎn)
- CLR1:
- JC CLRPROC ;小于107,轉(zhuǎn)
- MOV A,CTRL
- ACALL CLROUT1
- CLRPROC: ;如果輸入的代碼是101-108,則作如下2個(gè)動(dòng)作:
- MOV A,CTRL ;1.將相應(yīng)位清0,使繼電器觸點(diǎn)吸合
- ACALL CLROUT1 ;2.將133-140相應(yīng)位清0,使繼電器觸點(diǎn)吸合
- MOV A,CTRL ;防止串入電阻
- ADD A,#32
- ACALL CLROUT1
- RET
- CLROUT1:
- CLR C
- SUBB A,#100 ;先減去100 (因?yàn)樵撐粸槲粩?shù)加上100構(gòu)成)
- MOV B,#8 ;先將要清零的字節(jié)求出
- DIV AB
- PUSH PSW
- SETB RS0 ;選第二工作區(qū)
- MOV R0,#1FH ;用R0作間址尋址
- INC A
- MOV R7,A
- CLP:
- INC R0
- DJNZ R7,CLP ;確定是哪個(gè)字節(jié)
- ;**************************************
- MOV A,B ;將除得的結(jié)果送A(哪一位)
- JZ CLP3 ;如果是0,直接轉(zhuǎn),否則會(huì)有錯(cuò)
- MOV A,@R0 ;取這個(gè)字節(jié)
- MOV R7,#8 ;將這個(gè)字節(jié)循環(huán)右移8次
- MOV R6,B ;分兩段,一段由R6控制,正好將該位移到ACC.0的位置
- CLP1:
- DEC R7 ;R7中減去R6已移的次數(shù)
- RR A
- DJNZ R6,CLP1
- CLR ACC.0 ;由R6控制的移動(dòng)結(jié)束,該位處于ACC.0位置,清該位
- CLP2:
- RR A
- DJNZ R7,CLP2 ;剩下來該移動(dòng)的次數(shù)由R7中的值決定
- AJMP CLP4
- CLP3: ;這個(gè)是用來處理一種特殊情況,即某一字節(jié)的最低位
- MOV A,@R0 ;此時(shí)B中是0,如果仍用上法處理,會(huì)出錯(cuò),只要直接將
- CLR ACC.0 ;該位清0即可
- CLP4:
- MOV @R0,A
- POP PSW
- RET
- ;顯示子程序
- DISP:
- PUSH DPH
- PUSH DPL
- MOV SCON,#00H ;置串行口工作方式0
- JNB DISP_CTRL,HIDDEN ;如果DISP_CTRL位為0,則消隱處理
- AJMP DISP_NEXT ;要求消隱,則消隱處理
- HIDDEN:
- MOV A,#0FFH ;消隱代碼
- ACALL DISP_LED
- ACALL DISP_LED
- ACALL DISP_LED ;三次調(diào)用顯示子程序,發(fā)出3位
- POP DPL
- POP DPH
- RET ;消隱處理完畢,直接返回
- DISP_NEXT:
- MOV DPTR,#DISP_TAB
- MOV A,DISP3 ;顯示緩沖區(qū)的最高位
- MOVC A,@A+DPTR
- LCALL DISP_LED ;顯示最高位
- MOV A,DISP2
- MOVC A,@A+DPTR
- LCALL DISP_LED ;顯示中間位
- MOV A,DISP1
- MOV DPTR,#DISP_TAB
- MOVC A,@A+DPTR
- LCALL DISP_LED ;顯示低位
- POP DPL
- POP DPH
- RET
- ;以下顯示子程序
- DISP_LED:
- MOV SBUF,A
- DISP_L1:
- JNB TI,DISP_L1 ;發(fā)送第一位
- CLR TI
- RET
- DISP_TAB:
- DB 88H, 0BEH, 0C4H, 94H, 0B2H, 91H
- ; 0 1 2 3 4 5
- DB 81H, 0BCH, 80H, 090H, 0A0H, 83H
- ; 6 7 8 9 A B
- DB 0C9H, 86H, 0C1H, 0E1H, 0A2H, 0FFH
- ; C D E F H 消隱
- ;鍵盤程序
- ;返回的鍵值在B中
- KEY:
- CLR K_MARK
- MOV B,#0
- MOV R0,#0
- MOV R1,#0F7H
- MOV R7,#4
- MOV A,R1
- K_LOOP:
- MOV P1,A ;輸出到P1口
- MOV A,P1
- ORL A,#0FH ;高4位為1
- CPL A ;如果低4位也為1,取反后為0,無鍵按下
- JZ K_NEXT
- AJMP K_NEXT1
- K_NEXT:
- INC R0
- MOV A,R1
- RR A
- MOV R1,A
- DJNZ R7,K_LOOP
- AJMP NO_KEY
- K_NEXT1:
- JB ACC.4,K_RET ;0鍵被按下
- INC B
- INC B
- INC B
- INC B
- JB ACC.5,K_RET ;4鍵被按下
- INC B
- INC B
- INC B
- INC B
- JB ACC.6,K_RET ;8
- INC B
- INC B
- INC B
- INC B
- JB ACC.7,K_RET
- K_ERR:
- AJMP NO_KEY
- MOV A,R1
- RR A ;右移(F7--FB)
- MOV R1,A ;回存
- INC R0
- DJNZ R7,K_LOOP
- K_RET:
- MOV P1,#0F0H
- NOP
- MOV A,P1
- ORL A,#0FH
- CPL A
- JNZ K_RET ;循環(huán)直到所有按鍵被釋放
- SETB K_MARK ;置有鍵按下標(biāo)志
- MOV A,B
- ADD A,R0
- MOV B,A
- RET
- NO_KEY:
- RET
- ;1秒延時(shí)子程序
- D1S:
- PUSH PSW
- SETB RS1
- MOV R7,#7FH
- DLP1:
- MOV R6,#8FH
- DLP2:
- MOV R5,#3
- DJNZ R5,$
- DJNZ R6,DLP2
- DJNZ R7,DLP1
- POP PSW
- RET
- ;10毫秒延時(shí)子程序
- D10MS:
- PUSH PSW
- MOV R7,#20
- D1:
- MOV R6,#250
- DJNZ R6,$
- DJNZ R7,D1
- POP PSW
- RET
- END
復(fù)制代碼
|
|