?? timer.asm
字號:
ORG 0000H
LJMP START
ORG 000BH
LJMP TIMER0
ORG 0100H
KEY_TAB:DB 0AH,09H,06H,05H ;矩陣鍵盤鍵值表,表中分別對應K1,K2,K3,K4的鍵值
; READ READ WRITE WRITE
; P2.1 P2.0 P1.1 P1.0
;K1 1 0 1 0 0AH
;K2 1 0 0 1 09H
;K3 0 1 1 0 06H
;K4 0 1 0 1 05H
ORG 0110H
START:
TIME_05 EQU 30H ;0.5S的定時記數器
TIME_10 EQU 31H ;1S 的定時記數器
TIME_15 EQU 32H ;1.5S的定時記數器
TIME_100 EQU 33H ;10S的定時記數器
LED_STATE EQU 34H ;LED顯示狀態變量
LED_TIME_SEL EQU 35H ;LED顯示狀態變化時間選擇變量
;LED_TIME_SEL=1 LED的刷新時間為0.5S
;LED_TIME_SEL=2 LED的刷新時間為1S
;LED_TIME_SEL=3 LED的刷新時間為1.5S
LED_MODE_SEL EQU 36H ;LED顯示模式選擇變量
;LED_MODE_SEL=1 LED的顯示方式為拉屏顯示,即LED_DISPLAY1
;LED_MODE_SEL=2 LED的顯示方式為正向流水燈,即LED_DISPLAY2,且FOLLOW_BACK=0
;LED_MODE_SEL=3 LED的顯示方式為反向流水燈,即LED_DISPLAY2,且FOLLOW_BACK=1
KEY_VALUE EQU 37H ;鍵盤鍵值寄存器
KEY_PUSH_TIME EQU 38H ;鍵盤被按下的次數,即按鍵碼時間=10ms*次數
KEY_STATE EQU 39H ;鍵盤狀態寄存器
KEY_NAME EQU 40H ;鍵盤鍵名寄存器
KEY_NAME_OUT EQU 41H ;鍵盤鍵名輸出寄存器
T05flag BIT 00H ;0.5S的定時時標位
T10flag BIT 01H ;1S 的定時時標位
T15flag BIT 02H ;1.5S的定時時標位
T100flag BIT 03H ;10S的定時時標位
FOLLOW_BACK BIT 04H ;流水燈正反顯示標志位,0為正向顯示/即P1.0-P1.7
; 1為反向顯示/即P1.7-P1.0
T10MSflag BIT 05H ;10mS的定時時標位
PLUS BIT P2.2 ;脈沖輸出口
MOV SP,#60H
MOV TIME_05,#10 ;初始化 50mS*10=0.5S
MOV TIME_10,#20 ;初始化 50mS*20=1.0S
MOV TIME_15,#30 ;初始化 50mS*30=1.5S
MOV TIME_100,#200 ;初始化 50mS*20=10.0S
MOV LED_STATE,#02 ;初始化 LED顯示狀態變量
MOV LED_TIME_SEL,#1 ;初始化 LED顯示時間選擇變量
MOV LED_MODE_SEL,#1 ;初始化 LED顯示模式選擇變量
MOV KEY_VALUE,#00H ;初始化 鍵盤鍵值寄存器
MOV KEY_PUSH_TIME,#00H ;初始化 按鍵次數寄存器
MOV KEY_STATE,#00H ;初始化 按鍵狀態寄存器
MOV KEY_NAME,#00H ;初始化 鍵盤鍵名寄存器
MOV KEY_NAME_OUT,#00H ;初始化 鍵盤鍵名輸出寄存器
CLR T05flag
CLR T10flag
CLR T15flag
CLR T100flag
CLR T10MSflag
CLR FOLLOW_BACK ;初始化 將流水燈顯示設定為正向
MOV TH0,#0D8H ;設計數初值,定時時間為10mS
MOV TL0,#0F0H
MOV TMOD,#01H ;定時器0工作于方式2,為16位的定時器
SETB ET0
SETB TR0
SETB EA
MOV PSW,#00H
MOV A,#127
INC A
MAIN_LOOP: ;主程序入口
TEST_POINT1:
JNB T10MSflag,MAIN2 ;判斷10MS是否時間到
CLR T10MSflag ;清10MS時標標志位
LCALL KEY_MATRIX ;調鍵盤掃描程序
MAIN2:
LJMP MAIN_LOOP ;主程式序循環掃描
;***************************************************************
;定時10S到執行輸出程序
;***************************************************************
JNB T100flag,T100_DO_OUT
CLR T100flag ;復位10S的定時時標位
CPL PLUS ;輸出脈沖取反,構成脈寬為10S的方波
T100_DO_OUT:
;***************************************************************
;***************************************************************
;LED顯示輸出程序
;***************************************************************
TIME_MODE_SEL:
TIME_SEL:
MOV A,LED_TIME_SEL ;時間選擇
CJNE A,#1,TIME_SEL_T10 ;判斷LED_TIME=0.5S
JNB T05flag,SEL_OUT ;判斷TIME=0.5的時間標志位,是否時間到
CLR T05flag ;清時標
SJMP MODE_SEL ;跳轉至模式選擇
TIME_SEL_T10:
CJNE A,#2,TIME_SEL_T15 ;判斷LED_TIME=1.0S
JNB T10flag,SEL_OUT ;判斷TIME=1.0的時間標志位,是否時間到
CLR T10flag ;清時標
SJMP MODE_SEL ;跳轉至模式選擇
TIME_SEL_T15:
CJNE A,#3,SEL_OUT ;判斷LED_TIME=1.5S
JNB T15flag,SEL_OUT ;判斷TIME=1.5的時間標志位,是否時間到
CLR T15flag ;清時標
SJMP MODE_SEL ;跳轉至模式選擇
MODE_SEL:
MOV A,LED_MODE_SEL ;模式選擇
CJNE A,#1,MODE_SEL_M2 ;判斷是否為拉屏顯示
LCALL LED_DISPLAY1 ;調用拉屏顯示子程序
SJMP SEL_OUT
MODE_SEL_M2:
CJNE A,#2,MODE_SEL_M3 ;判斷是否為正向流水燈顯示
CLR FOLLOW_BACK ;將流水燈正反向顯示標志設為正向
LCALL LED_DISPLAY2 ;調用流水燈顯示子程序
SJMP SEL_OUT
MODE_SEL_M3:
CJNE A,#3,SEL_OUT ;判斷是否為反向流水燈顯示
SETB FOLLOW_BACK ;將流水燈正反向顯示標志設為反向
LCALL LED_DISPLAY2 ;調用流水燈顯示子程序
SJMP SEL_OUT
SEL_OUT:
RET
;***************************************************************
;***************************************************************
;流水燈狀態寄存器改變子程序
;***************************************************************
LED_STATE_CHANGE:
CLR C
MOV A,LED_STATE
RLC A
CJNE A,#00H,LED_STATE_OUT
MOV A,#01H
LED_STATE_OUT:
MOV LED_STATE,A
RET
;***************************************************************
;***************************************************************
;流水燈執行子程序1---拉屏程序
;P1.0-P1.7以一定的時間間隔TIME_LED來逐個點亮
;***************************************************************
LED_DISPLAY1:
LCALL LED_STATE_CHANGE ;調用流水燈狀態寄存器改變子程序
MOV A,LED_STATE
MOV R2,A
CLR C
LED_DISP1_LOOP:
RRC A
MOV R3,A
ADD A,R2
MOV R2,A
MOV A,R3
CJNE A,#00H,LED_DISP1_LOOP
MOV P1,R2
RET
;***************************************************************
;***************************************************************
;流水燈執行子程序2
;P1.0-P1.7以一定的時間間隔TIME_LED來流水點亮
;入口參數
;流水燈正反流動顯示標志位:FOLLOW_BACK
;LED狀態:LED_STATE
;***************************************************************
LED_DISPLAY2:
LCALL LED_STATE_CHANGE ;調用流水燈狀態寄存器改變子程序
JB FOLLOW_BACK,LED_RUN_WATER_BACK
MOV P1,LED_STATE ;流水燈正向顯示輸出
LJMP LED_DISP2_OUT
LED_RUN_WATER_BACK: ;流水燈反向顯示輸出
MOV R2,#08H ;移位次數8次
MOV R3,LED_STATE
SHIFT_LOOP:
MOV A,R3
RLC A
MOV R3,A
MOV A,R4 ;結果中間暫存
RRC A
MOV R4,A
MOV P1,R4
DJNZ R2,SHIFT_LOOP
MOV P1,R4
LED_DISP2_OUT:
RET
;***************************************************************
;***************************************************************
;中斷定時器0的中斷子程序
;***************************************************************
TIMER0:
PUSH ACC
MOV TH0,#0D8H ;重裝記數初數,定時時間為10mS
MOV TL0,#0F0H
SETB T10MSflag ;置位10MS的定時時標位
DEC TIME_05 ;0.5S記數器減1
DEC TIME_10 ;1.0S記數器減1
DEC TIME_15 ;1.5S記數器減1
DEC TIME_100 ;10S 記數器減1
MOV A,#00H ;定時0.5S記數器記數程序
CJNE A,TIME_05,T05_OUT
MOV TIME_05,#10 ;0.5S記數器重裝記數值
SETB T05flag ;置位0.5S的定時時標位
T05_OUT:
;定時1.0S記數器記數程序
CJNE A,TIME_10,T10_OUT
MOV TIME_10,#20 ;1.0S記數器重裝記數值
SETB T10flag ;置位1.0S的定時時標位
T10_OUT:
;定時1.5S記數器記數程序
CJNE A,TIME_15,T15_OUT
MOV TIME_15,#30 ;1.0S記數器重裝記數值
SETB T15flag ;置位1.0S的定時時標位
T15_OUT:
;定時10S記數器記數程序
CJNE A,TIME_100,T100_OUT
MOV TIME_100,#200 ;10S記數器重裝記數值
SETB T100flag ;置位10S的定時時標位
T100_OUT:
POP ACC
RETI
;***************************************************************
;***************************************************************
;獨立鍵盤處理程序
;P1.0輸入
;***************************************************************
KEY:
MOV P1,#0FFH
MOV A,P1
JNB ACC.0,KEY0
MOV KEY_PUSH_TIME,#00H ;沒鍵按下時,則將次數寄存清零
MOV KEY_VALUE,#00H ;沒有鍵按下,則送鍵值為00H
MOV KEY_STATE,#00H ;沒有鍵按下,則按鍵狀態寄存器清零
RET
KEY0:
LCALL KEY_WENDING;
RET
;***************************************************************
;***************************************************************
;矩陣鍵盤處理程序
; READ READ WRITE WRITE
; P2.1 P2.0 P1.1 P1.0
;K1 1 0 1 0 0AH
;K2 1 0 0 1 09H
;K3 0 1 1 0 06H
;K4 0 1 0 1 05H
;***************************************************************
KEY_MATRIX:
MOV P2,#0FFH ;讀準備
MOV A,P1
ANL A,#0FCH ;屏蔽不用位#1111 1100
MOV P1,A ;寫P1
MOV A,P2 ;讀鍵盤
ORL A,#0FCH ;屏蔽不用位#1111 1100
CJNE A,#0FFH,GET_KEY_VALUE ;判斷是否有鍵按,沒有退出,有進入其應的程序
MOV KEY_PUSH_TIME,#00H ;沒鍵按下時,則將次數寄存清零
MOV KEY_VALUE,#00H ;沒有鍵按下,則送鍵值為00H
MOV KEY_STATE,#00H ;沒有鍵按下,則按鍵狀態寄存器清零
RET
GET_KEY_VALUE:
MOV A,P1 ;
ANL A,#0FEH ;屏蔽不用位#1111 1110
MOV P1,A ;寫P1.0置0,判K1,K3
NOP
MOV A,P2
ORL A,#0FCH
CJNE A,#0FFH,GET_KEY_NAME ;判到有鍵按下,則跳轉至取鍵名
MOV A,P1 ;
ANL A,#0FDH ;屏蔽不用位#1111 1101
ORL A,#01H ;將P1。0置1
MOV P1,A ;寫P1.1置0,判K2,K4
NOP
MOV A,P2
ORL A,#0FCH
CJNE A,#0FFH,GET_KEY_NAME ;判到有鍵按下,則跳轉至取鍵名
MOV KEY_PUSH_TIME,#00H ;沒鍵按下時,則將次數寄存清零
MOV KEY_VALUE,#00H ;沒有鍵按下,則送鍵值為00H
MOV KEY_STATE,#00H ;沒有鍵按下,則按鍵狀態寄存器清零
RET
GET_KEY_NAME:
RL A
RL A
ANL A,#0CH
MOV R2,A
MOV A,P1
ANL A,#03H
ORL A,R2
MOV KEY_VALUE,A
MOV R0,#01H
MOV DPTR,#KEY_TAB ;取鍵值表的首地址
KEY_GET_LOOP:
MOV A,#00H
MOVC A,@A+DPTR
CJNE A,KEY_VALUE,KEY_NEXT
MOV KEY_NAME,R0 ;送鍵名
LCALL KEY_WENDING ;
RET
KEY_NEXT:
INC DPTR
INC R0
CJNE R0,#05H,KEY_GET_LOOP
MOV KEY_NAME,#00H
RET
;***************************************************************
;***************************************************************
;按鍵穩定程序:去抖動,并且確認有鍵按下
;***************************************************************
KEY_WENDING:
MOV A,KEY_STATE
KSR0:
CJNE A,#00H,KSR1
MOV KEY_STATE,#01H ;將按鍵狀態寄存器轉為1
RET
KSR1:
CJNE A,#01H,KSR2
MOV KEY_STATE,#02H ;將按鍵狀態寄存器轉為2
RET
KSR2:
CJNE A,#02H,KSR3
INC KEY_PUSH_TIME
MOV A,KEY_PUSH_TIME
CJNE A,#35,KSR_OUT ;鍵按下未到350MS,則跳出
MOV KEY_NAME_OUT,KEY_NAME ;檢測時間到,將鍵值輸出
MOV KEY_PUSH_TIME,#00H ;將按鍵次數記數器清
MOV KEY_STATE,#00H ;將按鍵狀態寄存器設為0
KSR3:
KSR_OUT:
RET
;***************************************************************
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -