|
問(wèn)題已找到,謝謝老師和同學(xué)以及論壇的大佬們。這個(gè)代碼邏輯上應(yīng)該對(duì)的,但是存在一個(gè)問(wèn)題就是主程序明明調(diào)用了按鍵掃描子程序 LCALL KEYSCAN,但是在這個(gè)按鍵掃描的子程序里,我寫(xiě)了一個(gè)判斷數(shù)據(jù)是否相等跳轉(zhuǎn)的命令 CJNE A,TEMP,S2,而這個(gè)跳轉(zhuǎn)的地址S2確實(shí)主程序里的,因此在按鍵子程序還沒(méi)有RET返回就已經(jīng)跳轉(zhuǎn)到另外一個(gè)子程序里面了,此時(shí)堆棧就溢出,調(diào)用了卻沒(méi)有執(zhí)行返回,調(diào)用的時(shí)候會(huì)壓棧的,那么返回就是出棧,如果沒(méi)有返回就會(huì)使得堆棧溢出,程序多跑幾次直接復(fù)位?偨Y(jié)就是:調(diào)用了子程序一定要返回,不能調(diào)用了子程序再跳轉(zhuǎn)到另外一個(gè)子程序,這樣返回那句命令就廢了。(如果調(diào)用了子程序,在自己的子程序里跳轉(zhuǎn)是可以的)哈哈開(kāi)心解決了一個(gè)很不容易發(fā)現(xiàn)的問(wèn)題。再一次感謝老師同學(xué)以及論壇的大佬們。
附上正確的代碼:
TEMP EQU 07H ;地址不要亂定 R7
ORG 000H
AJMP MAIN
ORG 100H
;********;
;主程序;
;********;
MAIN: MOV R0,#000H ;初始化LED模式為0
MOV R1,#00AH ;初始化LED的速度
MOV R2,#0FEH ;LED初始狀態(tài)
MOV R5,#0FFH ;初始化鍵代碼
MOV R6,#008H ;初始化計(jì)數(shù)器
WHILE: LCALL KEYSCAN ;按鍵掃描
LCALL KEYPRO ;按鍵處理
LCALL KEYAGIN ;按鍵彈起
AJMP SHOW ;顯示函數(shù)
JMPEND: AJMP WHILE
;********;
;顯示子程序;
;********;
SHOW: MOV A,R0
RL A
MOV DPTR,#JMPTAB
JMP @A+DPTR
;********;
;按鍵掃描子程序;
;********; ;03H = 0000 0011B
KEYSCAN: MOV P3,#03H ;給端口置高電平,讀取端口狀態(tài)必須先置端口為高電平
MOV A,P3 ;讀入P3的狀態(tài)也就是按鍵的狀態(tài)
ORL A,#0FCH ;0FCH = 1111 1100B
CPL A ;取反
JZ ONKEY ;如果A鍵態(tài)為00,則無(wú)按鍵填過(guò)直接做顯示部分
MOV TEMP,A ;保存臨時(shí)鍵值
LCALL DELAY10MS;消抖
MOV A,P3
ORL A,#0FCH
CPL A
CJNE A,TEMP,ONKEY ;判斷如果第二次讀取的按鍵值和第一次讀取的按鍵值不相等
MOV R5,A ;保存鍵值
AJMP KSEND
ONKEY: MOV R5,#000H
KSEND: RET
;********;
;按鍵處理子程序;
;********;
KEYPRO: MOV A,R5 ;把按鍵值給A
CJNE A,#000H,DOWNKEY
AJMP KEYPROEND
DOWNKEY: CJNE A,#001H,IFK2 ;如果鍵狀態(tài)為K1,則
CJNE R0,#003H,K1PRO ;
MOV R0,#000H
MOV R2,#0FEH
SJMP KEYPROEND
IFK2: CJNE A,#002H,KEYPROEND
CJNE R1,#0FAH,K2PRO
MOV R1,#00AH
SJMP KEYPROEND
K1PRO: INC R0
MOV R2,#0FEH
SJMP KEYPROEND
K2PRO: MOV A,R1
ADD A,#00AH
MOV R1,A
SJMP KEYPROEND
KEYPROEND: RET
;********;
;按鍵彈起子程序;
;********;
KEYAGIN: MOV A,R5
CJNE A,#000H,KEYTQ
AJMP NOKEYTQ
KEYTQ: MOV P3,#03H
KEYTA: MOV A,P3
ORL A,#0FCH
CPL A
CJNE A,TEMP,KEYCH
SJMP KEYTA
KEYCH: NOP
NOKEYTQ: RET
;********;
;延時(shí)10ms子程序;
;********;
DELAY10MS: ;@11.0592MHz
PUSH 30H
PUSH 31H
MOV 30H,#18
MOV 31H,#230
NEXT:
DJNZ 31H,NEXT
DJNZ 30H,NEXT
POP 31H
POP 30H
RET
;********;
;分支1子程序;
;********;
ONE:
MOV A,R2 ;R2是P1初始狀態(tài)LED 1111 1110B = 0FEH
MOV P1,A
MOV A,R1
MOV R3,A
L1: LCALL DELAY10MS
DJNZ R3,L1
MOV A,R2
RL A
MOV R2,A
AJMP JMPEND
;********;
;分支2子程序;
;********;
TWO: MOV A,R2
CLR C
MOV P1,A
MOV A,R1
MOV R3,A
L2: LCALL DELAY10MS
DJNZ R3,L2
MOV A,R2
RLC A
MOV R2,A
DJNZ R6,TWOEND
MOV R6,#009H
MOV R2,#0FFH
TWOEND: AJMP JMPEND
;********;
;分支3子程序;
;********;
THREE: MOV P1,#00FH
MOV A,R1
MOV R3,A
L3: LCALL DELAY10MS
DJNZ R3,L3
MOV P1,#0F0H
MOV A,R1
MOV R3,A
L4: LCALL DELAY10MS
DJNZ R3,L4
AJMP JMPEND
;********;
;分支4子程序;
;********;
FOUR: MOV P1,#0C3H
MOV A,R1
MOV R3,A
L5: LCALL DELAY10MS
DJNZ R3,L5
MOV P1,#03CH
MOV A,R1
MOV R3,A
L6: LCALL DELAY10MS
DJNZ R3,L6
AJMP JMPEND
;********;
;跳轉(zhuǎn)程序表;
;********;
JMPTAB: AJMP ONE
AJMP TWO
AJMP THREE
AJMP FOUR
END |
評(píng)分
-
查看全部評(píng)分
|