找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 4515|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)匯編版本,關(guān)于工作寄存器R1在程序運(yùn)行過(guò)程中無(wú)緣無(wú)故被修改的問(wèn)題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:235079 發(fā)表于 2017-11-14 17:27 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
附上軟件代碼:TEMP EQU 07H        ;地址不要亂定 R7

硬件上:P3.0、P3.1口接了按鍵,P1口接了LED燈

問(wèn)題:程序當(dāng)中第一種模式ONE,里面的延時(shí)部分,有一個(gè)工作寄存器R1,在按鍵處理子程序KEYPRO中修改了之后,程序應(yīng)該是一直保持修改之后的值的,但是顯示的子程序循環(huán)執(zhí)行幾個(gè)來(lái)回后,R1發(fā)生了改變,好像恢復(fù)到初值了,顯示(流水燈)的速度又快了。請(qǐng)教大佬們,R1工作寄存器的值變化是什么原因造成的?小弟不才,希望是代碼錯(cuò)了,求大佬們指點(diǎn)迷津,感激不盡

  1. ORG 000H
  2.                         AJMP MAIN
  3. ORG 100H
  4. ;********;
  5. ;主程序;
  6. ;********;
  7. MAIN:                MOV R0,#000H        ;初始化LED模式為0
  8.                         MOV R1,#00AH        ;初始化LED的速度        
  9.                         MOV R2,#0FEH        ;LED初始狀態(tài)        
  10.                         MOV R5,#0FFH
  11. WHILE:                LCALL KEYSCAN        ;按鍵掃描
  12. S1:                        LCALL KEYPRO        ;按鍵處理
  13. S2:                    LCALL SHOW                ;顯示函數(shù)
  14. JMPEND:                AJMP WHILE
  15. ;********;
  16. ;顯示子程序;
  17. ;********;
  18. SHOW:                MOV A,R0
  19.                         RL A
  20.                         MOV DPTR,#JMPTAB
  21.                         JMP @A+DPTR
  22.                         RET
  23. ;********;
  24. ;按鍵掃描子程序;
  25. ;********;                        ;03H = 0000 0011B
  26. KEYSCAN:        MOV P3,#03H                ;給端口置高電平,讀取端口狀態(tài)必須先置端口為高電平
  27.                         MOV A,P3                ;讀入P3的狀態(tài)也就是按鍵的狀態(tài)
  28.                         ORL A,#0FCH                ;0FCH = 1111 1100B
  29.                         CPL A                        ;取反
  30.                         JZ        S2                        ;如果A鍵態(tài)為00,則無(wú)按鍵填過(guò)直接做顯示部分        
  31.                         MOV TEMP,A                ;保存臨時(shí)鍵值
  32.                         LCALL        DELAY10MS;消抖
  33.                         MOV A,P3
  34.                         ORL A,#0FCH
  35.                         CPL A
  36.                         CJNE A,TEMP,S2  ;判斷如果第二次讀取的按鍵值和第一次讀取的按鍵值不相等
  37.                         MOV R5,A                ;保存鍵值

  38.                         RET
  39. ;********;
  40. ;按鍵處理子程序;
  41. ;********;        
  42. KEYPRO:                MOV A,R5                        ;把按鍵值給A
  43.                         CJNE A,#001H,IFK2        ;如果鍵狀態(tài)為K1,則
  44.                         CJNE R0,#002H,K1PRO        ; R0 = 0000 0000B    #0000 0010B
  45.                         MOV R0,#000H
  46.                         SJMP KEYPROEND
  47. IFK2:                CJNE A,#002H,KEYPROEND
  48.                         CJNE R1,#0FAH,K2PRO
  49.                         MOV R1,#00AH
  50.                         SJMP KEYPROEND
  51. K1PRO:                INC R0
  52.                         SJMP KEYPROEND
  53. K2PRO:                MOV A,R1
  54.                         ADD A,#00AH
  55.                         MOV R1,A
  56.                         SJMP KEYPROEND
  57. KEYPROEND:        RET
  58. ;********;
  59. ;延時(shí)10ms子程序;
  60. ;********;
  61. DELAY10MS:                        ;@11.0592MHz
  62.                         PUSH 30H
  63.                         PUSH 31H
  64.                         MOV 30H,#18
  65.                         MOV 31H,#230
  66. NEXT:
  67.                         DJNZ 31H,NEXT
  68.                         DJNZ 30H,NEXT
  69.                         POP 31H
  70.                         POP 30H
  71.                         RET               
  72. ;********;
  73. ;分支1子程序;
  74. ;********;
  75. ONE:                        
  76.                         MOV A,R2                        ;R2是P1初始狀態(tài)LED 1111 1110B = 0FEH
  77.                         MOV P1,A
  78.                         MOV A,R1
  79.                         MOV R3,A
  80.                         ;MOV P1,A
  81. L1:                        LCALL DELAY10MS
  82.                         DJNZ R3,L1

  83.                         MOV A,R2
  84.                         RL A
  85.                         MOV R2,A
  86.                         AJMP JMPEND
  87. ;********;
  88. ;分支2子程序;
  89. ;********;
  90. TWO:                MOV P1,#00FH
  91.                         SJMP $
  92.                         AJMP JMPEND
  93. ;********;
  94. ;跳轉(zhuǎn)程序表;
  95. ;********;
  96. JMPTAB:                AJMP ONE
  97.                         AJMP TWO
  98.                         END
復(fù)制代碼
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:123289 發(fā)表于 2017-11-15 13:35 | 只看該作者
請(qǐng)教一下,堆棧存從哪里開(kāi)始?堆棧里的數(shù)據(jù)何時(shí)會(huì)發(fā)生變化?
回復(fù)

使用道具 舉報(bào)

板凳
ID:235079 發(fā)表于 2017-11-15 21:43 | 只看該作者
yzwzfyz 發(fā)表于 2017-11-15 13:35
請(qǐng)教一下,堆棧存從哪里開(kāi)始?堆棧里的數(shù)據(jù)何時(shí)會(huì)發(fā)生變化?

查閱一下51匯編的書(shū)籍,堆棧的一開(kāi)始初始化的地址我忘記,堆棧地址可以改的,給sp賦值即可。MOV SP,060H。堆棧的數(shù)據(jù),當(dāng)你調(diào)用子程序了就會(huì)壓棧,返回的時(shí)候就出棧;蛘咧苯訉(duì)堆棧進(jìn)行操作PUSH或者POP
回復(fù)

使用道具 舉報(bào)

地板
ID:235079 發(fā)表于 2017-11-15 21:56 | 只看該作者
問(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)分

參與人數(shù) 1黑幣 +60 收起 理由
admin + 60 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表