发新帖我要提问
12
返回列表
打印

请教:51程序调试—奇怪问题,变量内容被莫名其妙改变

[复制链接]
楼主: gdmgb520
手机看帖
扫描二维码
随时随地手机跟帖
21
ejack| | 2009-11-12 17:34 | 只看该作者 回帖奖励 |倒序浏览
那么如何让串口中断后跳转回C:0x0000?LZ的串口中断程序没有死循环,不是复位。
串口中断后PC会等于0x0000

使用特权

评论回复
22
冷漠| | 2009-11-12 19:07 | 只看该作者
请LZ给咱们解惑一下:他的异常串口中断程序是如何能够返回到PC:0x0000的?

我就没这两下子。

使用特权

评论回复
23
gdmgb520|  楼主 | 2009-11-13 10:51 | 只看该作者
回复16楼ejack
我程序里面是dat=(P2 & dat【i】),因为老是打不出来[]中间有个i的文字来,你可能没看我附件里面的代码,而且我前面已经说过了。
另外,我还说了问题不在这里,问题是开了串口中断,没有写中断子函数。

关于串口中断后PC=0x0000的问题:
串口中断以后程序应该跳到中断向量入口地址0x0023(串口),然后开始执行串口中断子函数,这是正常的情况。我现在的情况是我开了串口中断,但是没有写串口中断子函数。当串口中断响应以后,本应跳到中断入口地址,但是我在KEIL的debug模式下调试,每当串口中断产生以后,程序会跳到main函数的开始去执行,并且此时PC=0x0000,这是从编译器里看到的。如果大家觉得不可能可以再Keil里面试一下。我保证是这样。原因就是因为程序没有找到中断子函数就做了PC=0x0000。这是其他高人告诉我的,我自己没有在书上找到。


虽然我的问题早已经解决,但是我看前面我提问时没有人找到问题,所以我又回来反馈一下我是这么解决的、问题到底在哪里。以便像我一样的新手遇到这个问题时能有个参考。
平时看帖子见很多人光提问,问题解决了也不说一说问题到底是怎么解决的。我觉得有热心人帮我,我也应该吧最后的结果和大家分享,也做一个热心人去帮助别人。

使用特权

评论回复
24
冷漠| | 2009-11-13 13:24 | 只看该作者
同意楼上“问题解决了也说一说怎么解决的。应该把最后的结果和大家分享。”。

例如仍然质疑LZ,继续讨论(讨论解惑即学习):即使没有写串口中断程序,串口中断时程序从0x0023执行,有可能异常运行到main( ),这一点没问题;但是怎么可能main( )主函数的位置在PC:0x0000?!分明在C:0188 呀?

C:0x001A    020188   LJMP     main(C:0188)
C:0x001D    E4       CLR      A
C:0x001E    93       MOVC     A,@A+DPTR
C:0x001F    A3       INC      DPTR
C:0x0020    F8       MOV      R0,A
C:0x0021    E4       CLR      A
C:0x0022    93       MOVC     A,@A+DPTR
C:0x0023    A3       INC      DPTR               ;串口中断入口
C:0x0024    4003     JC       C:0029
C:0x0026    F6       MOV      @R0,A
C:0x0027    8001     SJMP     C:002A
C:0x0029    F2       MOVX     @R0,A
C:0x002A    08       INC      R0
C:0x002B    DFF4     DJNZ     R7,C:0021
C:0x002D    8029     SJMP     C:0058          ;从这里跳走到0x0058
C:0x002F    E4       CLR      A
.................
..................

C:0x0057    F2       MOVX     @R0,A
C:0x0058    E4       CLR      A
C:0x0059    7E01     MOV      R6,#0x01
C:0x005B    93       MOVC     A,@A+DPTR
C:0x005C    60BC     JZ       C:001A        ;从这里跳到main( ),并看不出哪里置PC:0x0000?
C:0x005E    A3       INC      DPTR

使用特权

评论回复
25
desert_hawk| | 2009-11-13 13:38 | 只看该作者
楼主说的串口中断服务没有写但是却发生了串口中断,然后PC的值会是0000是很有可能的。51单片机我没试验过,但以前用别的MCU的确出现过这种情况。我分析原因是,虽然没写中断服务,但CPU仍然会去0x0023这个位置取指令,而这个指令很有可能会是编译器生成的0xffff或其它,CPU根本无法识别这个指令,接着就异常复位了,结果就出现了楼主所说的PC=0000的情况。

使用特权

评论回复
26
ejack| | 2009-11-13 22:27 | 只看该作者
同意,应当是从C:0x0023开始执行出现异常(未对齐或根本就不是指令代码),程序跑飞而复位。
具体LZ可以在编译器的反汇编窗口中直接调试验证。

使用特权

评论回复
27
gdmgb520|  楼主 | 2009-11-17 09:47 | 只看该作者
哦,为什么PC会等于0x0000我确实不是很清楚,但是我在debug模式下串口中断以后程序就跳到了main函数里的第一条语句,这个时候PC确实等于0x0000.
虽然学过汇编,可是没怎么用过,都忘得差不多了,应该捡起来啊。
很高兴能和大家讨论。

使用特权

评论回复
28
冷漠| | 2009-11-17 13:46 | 只看该作者
LZ应该像24楼那样把你的CS_11.C 最终编译执行码贴出来给大家看看:为什么你的main()主函数编译代码跑到了PC:0X0000. ——你的项目窗口里分明是加入了STARTUP.A51文件的!也就是说,你的程序代码肯定是从STARTUP.A51(PC:0X0000)开始执行的,而不是从main()开始执行的。

这是C51编译器应用基础,如果不了解,那大概连我说的是什么都不知道......
LS几位大侠一直在论证从0X0023中断向量跑飞到0X0000是可能的,南辕北辙了。LZ说的是他的程序跑到了main(),PC:0X0000处。

哪位大侠能像24楼那样显示一下它的C程序是从PC:0X0000——main:处开始的,他就算是把C51玩透了。

使用特权

评论回复
29
冷漠| | 2009-11-17 14:01 | 只看该作者
126: ?C_STARTUP:     LJMP    STARTUP1
   127:  
   128:                 RSEG    ?C_C51STARTUP
   129:  
   130: STARTUP1:
   131:  
   132: IF IDATALEN <> 0
C:0x0000    02000E   LJMP     STARTUP1(C:000E)               //  0x0000如若是main,下面的0X003中断向量怎么办?
    75: void Send_Char_Com(uint ch)
    76: {
    77:         SBUF=ch;
C:0x0003    8F99     MOV      SBUF(0x99),R7
    78:         while(TI==0);            //TI=1
C:0x0005    3099FD   JNB      TI(0x98.1),C:0005
    79:        
C:0x0008    C299     CLR      TI(0x98.1)
    80: }
    81:  
    82:  /***************************************************/
    83: /*
    84: /*
    85: /
    86: /***************************************************/
C:0x000A    22       RET      
C:0x000B    020169   LJMP     Timer0(C:0169)
   133:                 MOV     R0,#IDATALEN - 1
C:0x000E    787F     MOV      R0,#0x7F
   134:                 CLR     A
C:0x0010    E4       CLR      A
   135: IDATALOOP:      MOV     @R0,A
C:0x0011    F6       MOV      @R0,A
   136:                 DJNZ    R0,IDATALOOP
C:0x0012    D8FD     DJNZ     R0,IDATALOOP(C:0011)
   185:                 MOV     SP,#?STACK-1
   186:  
   187: ; This code is required if you use L51_BANK.A51 with Banking Mode 4
   188: ;<h> Code Banking
   189: ; <q> Select Bank 0 for L51_BANK.A51 Mode 4
   190: #if 0   
   191: ;     <i> Initialize bank mechanism to code bank 0 when using L51_BANK.A51 with Banking Mode 4.
   192: EXTRN CODE (?B_SWITCH0)
   193:                 CALL    ?B_SWITCH0      ; init bank mechanism to code bank 0
   194: #endif
   195: ;</h>
C:0x0014    758131   MOV      SP(0x81),#0x31
   196:                 LJMP    ?C_START
C:0x0017    020055   LJMP     C:0055
C:0x001A    020188   LJMP     main(C:0188)          //     这里确定main主函数位置。
C:0x001D    E4       CLR      A
C:0x001E    93       MOVC     A,@A+DPTR

使用特权

评论回复
30
冷漠| | 2009-11-17 14:11 | 只看该作者
本帖最后由 冷漠 于 2009-11-17 14:12 编辑

31: }
C:0x0187    22       RET      
   166: void main ()                // main()在PC:0X0188,和0X0000有何关系?除非你是高手。
   167: {
   168:         InitSystem();                  //  初始化定时器0
C:0x0188    120150   LCALL    InitSystem(C:0150)
   169:         while(1)
   170:         {
   171:                 DataProcessing();
C:0x018B    120122   LCALL    DataProcessing(C:0122)
   172:                 s_led1=~s_led1;
C:0x018E    B286     CPL      s_led1(0x80.6)
   173:                 Delay5Ms();
C:0x0190    120179   LCALL    Delay5Ms(C:0179)
   174:         }
C:0x0193    80F6     SJMP     C:018B
C:0x0195    00       NOP      
C:0x0196    00       NOP

使用特权

评论回复
31
desert_hawk| | 2009-11-18 08:53 | 只看该作者
PC从0000 main()开始执行?
把楼主的工程下载了运行了一下,串口中断后的确会从main开始运行,但此时PC并不是0000,而是main的地址,我是用simulator仿真的,因为手上没有51的电路板。
烦请高人指导下,程序是怎么从0000 main处运行的,PC为0000,却在main处运行?

使用特权

评论回复
32
冷漠| | 2009-11-18 13:24 | 只看该作者
本帖最后由 冷漠 于 2009-11-18 13:25 编辑

烦请高人指导下,程序是怎么从0000 main处运行的,PC为0000,却在main处运行?



高人可以。代表中国单片机水平的堂堂21IC论坛,有高人吗?

使用特权

评论回复
33
冷漠| | 2009-11-18 13:43 | 只看该作者
本帖最后由 冷漠 于 2009-11-18 13:44 编辑
哦,为什么PC会等于0x0000我确实不是很清楚,但是我在debug模式下串口中断以后程序就跳到了main函数里的第一条语句,这个时候PC确实等于0x0000.


LZ一不小心,在确实不清楚的情况下做了“高人”都做不到的事。——机会来了。一般成功的人就是这样产生的:“打破砂锅问到底”——好不容易看到了一个令人不解的现象。“问题即课题”,天赐良机。

使用特权

评论回复
34
gdmgb520|  楼主 | 2009-11-18 16:56 | 只看该作者
呵呵,谢谢大家指点。我还要把汇编好好看看,上课的时候学了一直没用过都忘光了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则