久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4454|回復: 3
打印 上一主題 下一主題
收起左側

51單片機匯編版本,關于工作寄存器R1在程序運行過程中無緣無故被修改的問題

[復制鏈接]
跳轉到指定樓層
樓主
ID:235079 發表于 2017-11-14 17:27 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
附上軟件代碼:TEMP EQU 07H        ;地址不要亂定 R7

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

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

  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初始狀態        
  10.                         MOV R5,#0FFH
  11. WHILE:                LCALL KEYSCAN        ;按鍵掃描
  12. S1:                        LCALL KEYPRO        ;按鍵處理
  13. S2:                    LCALL SHOW                ;顯示函數
  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                ;給端口置高電平,讀取端口狀態必須先置端口為高電平
  27.                         MOV A,P3                ;讀入P3的狀態也就是按鍵的狀態
  28.                         ORL A,#0FCH                ;0FCH = 1111 1100B
  29.                         CPL A                        ;取反
  30.                         JZ        S2                        ;如果A鍵態為00,則無按鍵填過直接做顯示部分        
  31.                         MOV TEMP,A                ;保存臨時鍵值
  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        ;如果鍵狀態為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. ;延時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初始狀態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. ;跳轉程序表;
  95. ;********;
  96. JMPTAB:                AJMP ONE
  97.                         AJMP TWO
  98.                         END
復制代碼
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:123289 發表于 2017-11-15 13:35 | 只看該作者
請教一下,堆棧存從哪里開始?堆棧里的數據何時會發生變化?
回復

使用道具 舉報

板凳
ID:235079 發表于 2017-11-15 21:43 | 只看該作者
yzwzfyz 發表于 2017-11-15 13:35
請教一下,堆棧存從哪里開始?堆棧里的數據何時會發生變化?

查閱一下51匯編的書籍,堆棧的一開始初始化的地址我忘記,堆棧地址可以改的,給sp賦值即可。MOV SP,060H。堆棧的數據,當你調用子程序了就會壓棧,返回的時候就出棧;蛘咧苯訉Χ褩_M行操作PUSH或者POP
回復

使用道具 舉報

地板
ID:235079 發表于 2017-11-15 21:56 | 只看該作者
問題已找到,謝謝老師和同學以及論壇的大佬們。這個代碼邏輯上應該對的,但是存在一個問題就是主程序明明調用了按鍵掃描子程序 LCALL KEYSCAN,但是在這個按鍵掃描的子程序里,我寫了一個判斷數據是否相等跳轉的命令 CJNE A,TEMP,S2,而這個跳轉的地址S2確實主程序里的,因此在按鍵子程序還沒有RET返回就已經跳轉到另外一個子程序里面了,此時堆棧就溢出,調用了卻沒有執行返回,調用的時候會壓棧的,那么返回就是出棧,如果沒有返回就會使得堆棧溢出,程序多跑幾次直接復位?偨Y就是:調用了子程序一定要返回,不能調用了子程序再跳轉到另外一個子程序,這樣返回那句命令就廢了。(如果調用了子程序,在自己的子程序里跳轉是可以的)哈哈開心解決了一個很不容易發現的問題。再一次感謝老師同學以及論壇的大佬們。

附上正確的代碼:

TEMP EQU 07H        ;地址不要亂定 R7
ORG 000H
                        AJMP MAIN
ORG 100H
;********;
;主程序;
;********;
MAIN:                MOV R0,#000H        ;初始化LED模式為0
                        MOV R1,#00AH        ;初始化LED的速度       
                        MOV R2,#0FEH        ;LED初始狀態       
                        MOV R5,#0FFH        ;初始化鍵代碼
                        MOV R6,#008H        ;初始化計數器
WHILE:                LCALL KEYSCAN        ;按鍵掃描
                        LCALL KEYPRO        ;按鍵處理
                             LCALL KEYAGIN        ;按鍵彈起
                        AJMP SHOW                ;顯示函數
JMPEND:                AJMP WHILE
;********;
;顯示子程序;
;********;
SHOW:                MOV A,R0
                        RL A
                        MOV DPTR,#JMPTAB
                        JMP @A+DPTR
;********;
;按鍵掃描子程序;
;********;                        ;03H = 0000 0011B
KEYSCAN:                MOV P3,#03H                ;給端口置高電平,讀取端口狀態必須先置端口為高電平
                        MOV A,P3                ;讀入P3的狀態也就是按鍵的狀態
                        ORL A,#0FCH                ;0FCH = 1111 1100B
                        CPL A                        ;取反
                        JZ        ONKEY                        ;如果A鍵態為00,則無按鍵填過直接做顯示部分       
                        MOV TEMP,A                ;保存臨時鍵值
                        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        ;如果鍵狀態為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
;********;
;延時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初始狀態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
;********;
;跳轉程序表;
;********;
JMPTAB:                AJMP ONE
                        AJMP TWO
                        AJMP THREE
                        AJMP FOUR
                        END

評分

參與人數 1黑幣 +60 收起 理由
admin + 60 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91av在线影院 | 视频一区二区在线观看 | 亚av在线| 日韩爱爱网 | 国产精品久久久久久二区 | 日韩成人免费视频 | 国产成人jvid在线播放 | 国产精品亚洲欧美日韩一区在线 | 天天爽天天操 | 中文字幕成人 | www国产亚洲精品久久网站 | 国产一区二区视频在线 | 91精品国产91久久久久久吃药 | 国产精品免费一区二区三区 | 久久这里只有精品首页 | 精品啪啪 | 毛片网在线观看 | 亚洲国产一区在线 | 国产精品成人一区二区三区 | 亚洲视频在线观看 | 日韩中文在线观看 | 亚洲国产成人精品一区二区 | 2021狠狠天天天 | 三级视频网站 | 色综合欧美| 午夜爱爱网 | 在线免费观看亚洲 | 一级毛片黄片 | 亚洲精品在线视频 | 午夜精品91 | 日韩二区| 国产精品福利视频 | 欧美视频第三页 | 欧美激情久久久 | 久久精品国产亚洲 | 国产精品一区在线 | 中文字幕国产一区 | 中文字幕在线看第二 | 成人久久视频 | 四虎影视1304t | 亚洲精彩视频在线观看 |