打印

【有奖征文活动】C8051F 进不了main函数问题解决办法

[复制链接]
12242|44
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
auzxj|  楼主 | 2009-8-21 22:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 auzxj 于 2009-8-21 22:36 编辑

这是以前我遇到的,在ednchina上发过,现重新整理了一下,我的目标是ARM9,谁都表跟我抢:lol
提出问题:
前一阵在做C8051F340的一个程序,用到USB,我在修改了他的Demo,加了一些数据在xdata里,程序编译通过,无错误无警告,但在仿真的时候一直进不了main函数
分析问题:
子曾经曰过:“知之为知之,不知google之,是知也”。于是遇到这问题,我首先google之,发现很多人遇到了和我一样的问题,还有很多人在百度知道上提出了,但一直没有解决,经过查阅大量的网页,借鉴别人的经验,站在前辈的肩上(没跟他们商量,我就自作主张站上去了:victory:),再加上自己的一点点思考,终于发现问题的存在
单片在进入main函数之前,会执行启动代码,由于我长时间用C,潜意识CPU上电就会跳到main的入口,我记得N年以前写汇编的时候,也是在0000H地址处加一个跳转指令直接跳到main函数的,从来没注意过启动代码,这次栽了跟头才好好的看了看
由于我原程序在xdata开辟了大量的数据,在启动代码中
IF XDATALEN <> 0
                MOV     DPTR,#XDATASTART
                MOV     R7,#LOW (XDATALEN)
  IF (LOW (XDATALEN)) <> 0
                MOV     R6,#(HIGH (XDATALEN)) +1
  ELSE
                MOV     R6,#HIGH (XDATALEN)
  ENDIF
                CLR     A
XDATALOOP:      MOVX    @DPTR,A
                INC     DPTR
                DJNZ    R7,XDATALOOP
                DJNZ    R6,XDATALOOP
ENDIF
会执行xdata的初始化,由于C8051F340有看门狗,而看门狗默认是开启的,我一般会在main函数的第一句话把看门狗关闭,由于定义的xdata很大,在启动代码中执行初始化时间远远超过了喂狗时间,所有导致执行启动代码的过程中看门狗复位,一直进不了主程序,关不了狗,够就一直复位,无限循环。。。。。
解决问题:
修改STARTUP.A51函数,在启动代码中关闭看门狗如下:
$NOMOD51
;------------------------------------------------------------------------------
;  This file is part of the C51 Compiler package
;  Copyright (c) 1988-2005 Keil Elektronik GmbH and Keil Software, Inc.
;  Version 8.01
;
;  *** <<< Use Configuration Wizard in Context Menu >>> ***
;------------------------------------------------------------------------------
;  STARTUP.A51:  This code is executed after processor reset.
;
;  To translate this file use A51 with the following invocation:
;
;     A51 STARTUP.A51
;
;  To link the modified STARTUP.OBJ file to your application use the following
;  Lx51 invocation:
;
;     Lx51 your object file list, STARTUP.OBJ  controls
;
;------------------------------------------------------------------------------
;
;  User-defined <h> Power-On Initialization of Memory
;
;  With the following EQU statements the initialization of memory
;  at processor reset can be defined:
;
; <o> IDATALEN: IDATA memory size <0x0-0x100>
;     <i> Note: The absolute start-address of IDATA memory is always 0
;     <i>       The IDATA space overlaps physically the DATA and BIT areas.

IDATALEN        EQU     80H
;
; <o> XDATASTART: XDATA memory start address <0x0-0xFFFF>
;     <i> The absolute start address of XDATA memory
XDATASTART      EQU     0   
;
; <o> XDATALEN: XDATA memory size <0x0-0xFFFF>
;     <i> The length of XDATA memory in bytes.
XDATALEN        EQU     0     
;
; <o> PDATASTART: PDATA memory start address <0x0-0xFFFF>
;     <i> The absolute start address of PDATA memory
PDATASTART      EQU     0H
;
; <o> PDATALEN: PDATA memory size <0x0-0xFF>
;     <i> The length of PDATA memory in bytes.
PDATALEN        EQU     0H
;
;</h>
;------------------------------------------------------------------------------
;
;<h> Reentrant Stack Initialization
;
;  The following EQU statements define the stack pointer for reentrant
;  functions and initialized it:
;
; <h> Stack Space for reentrant functions in the SMALL model.
;  <q> IBPSTACK: Enable SMALL model reentrant stack
;     <i> Stack space for reentrant functions in the SMALL model.
IBPSTACK        EQU     0       ; set to 1 if small reentrant is used.
;  <o> IBPSTACKTOP: End address of SMALL model stack <0x0-0xFF>
;     <i> Set the top of the stack to the highest location.
IBPSTACKTOP     EQU     0xFF +1     ; default 0FFH+1
; </h>
;
; <h> Stack Space for reentrant functions in the LARGE model.     
;  <q> XBPSTACK: Enable LARGE model reentrant stack
;     <i> Stack space for reentrant functions in the LARGE model.
XBPSTACK        EQU     0       ; set to 1 if large reentrant is used.
;  <o> XBPSTACKTOP: End address of LARGE model stack <0x0-0xFFFF>
;     <i> Set the top of the stack to the highest location.
XBPSTACKTOP     EQU     0xFFFF +1   ; default 0FFFFH+1
; </h>
;
; <h> Stack Space for reentrant functions in the COMPACT model.   
;  <q> PBPSTACK: Enable COMPACT model reentrant stack
;     <i> Stack space for reentrant functions in the COMPACT model.
PBPSTACK        EQU     0       ; set to 1 if compact reentrant is used.
;
;   <o> PBPSTACKTOP: End address of COMPACT model stack <0x0-0xFFFF>
;     <i> Set the top of the stack to the highest location.
PBPSTACKTOP     EQU     0xFF +1     ; default 0FFH+1
; </h>
;</h>
;------------------------------------------------------------------------------
;
;  Memory Page for Using the Compact Model with 64 KByte xdata RAM
;  <e>Compact Model Page Definition
;
;  <i>Define the XDATA page used for PDATA variables.
;  <i>;PPAGE must conform with the PPAGE set in the linker invocation.
;
; Enable pdata memory page initalization
PPAGEENABLE     EQU     0       ; set to 1 if pdata object are used.
;
; <o> PPAGE number <0x0-0xFF>
; <i> uppermost 256-byte address of the page used for PDATA variables.
PPAGE           EQU     0
;
; <o> SFR address which supplies uppermost address byte <0x0-0xFF>
; <i> most 8051 variants use P2 as uppermost address byte
PPAGE_SFR       DATA    0A0H
;
; </e>
;------------------------------------------------------------------------------

; Standard SFR Symbols
ACC     DATA    0E0H
B       DATA    0F0H
SP      DATA    81H
DPL     DATA    82H
DPH     DATA    83H
PCA0MD    DATA  0D9H //Added by auzxj,2009年6月22日

                NAME    ?C_STARTUP


?C_C51STARTUP   SEGMENT   CODE
?STACK          SEGMENT   IDATA

                RSEG    ?STACK
                DS      1

                EXTRN CODE (?C_START)
                PUBLIC  ?C_STARTUP

                CSEG    AT      0
?C_STARTUP:     LJMP    STARTUP1

                RSEG    ?C_C51STARTUP

STARTUP1:

IF IDATALEN <> 0
    ANL   PCA0MD, #NOT(040h)//Added by auzxj,2009年6月22日
                MOV     R0,#IDATALEN - 1
                CLR     A
IDATALOOP:      MOV     @R0,A
                DJNZ    R0,IDATALOOP
ENDIF

IF XDATALEN <> 0
                MOV     DPTR,#XDATASTART
                MOV     R7,#LOW (XDATALEN)
  IF (LOW (XDATALEN)) <> 0
                MOV     R6,#(HIGH (XDATALEN)) +1
  ELSE
                MOV     R6,#HIGH (XDATALEN)
  ENDIF
                CLR     A
XDATALOOP:      MOVX    @DPTR,A
                INC     DPTR
                DJNZ    R7,XDATALOOP
                DJNZ    R6,XDATALOOP
ENDIF

IF PPAGEENABLE <> 0
                MOV     PPAGE_SFR,#PPAGE
ENDIF

IF PDATALEN <> 0
                MOV     R0,#LOW (PDATASTART)
                MOV     R7,#LOW (PDATALEN)
                CLR     A
PDATALOOP:      MOVX    @R0,A
                INC     R0
                DJNZ    R7,PDATALOOP
ENDIF

IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)

                MOV     ?C_IBP,#LOW IBPSTACKTOP
ENDIF

IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)

                MOV     ?C_XBP,#HIGH XBPSTACKTOP
                MOV     ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF

IF PBPSTACK <> 0
EXTRN DATA (?C_PBP)
                MOV     ?C_PBP,#LOW PBPSTACKTOP
ENDIF

                MOV     SP,#?STACK-1

; This code is required if you use L51_BANK.A51 with Banking Mode 4
;<h> Code Banking
; <q> Select Bank 0 for L51_BANK.A51 Mode 4
#if 0  
;     <i> Initialize bank mechanism to code bank 0 when using L51_BANK.A51 with Banking Mode 4.
EXTRN CODE (?B_SWITCH0)
                CALL    ?B_SWITCH0      ; init bank mechanism to code bank 0
#endif
;</h>
                LJMP    ?C_START

                END

//修改保存,并把它添加进你的工程

相关帖子

沙发
auzxj|  楼主 | 2009-8-21 22:32 | 只看该作者
第一次发贴竟然没成功,说我超出字数限制,并删了我将近一半的文字,幸亏我有个好习惯,发帖之前保存在记事本里了,否则后果不堪设想。。。。。

使用特权

评论回复
板凳
程序匠人| | 2009-8-21 22:36 | 只看该作者
哈哈,这两天真是丰收啊。

使用特权

评论回复
地板
victech| | 2009-8-22 00:08 | 只看该作者
我也遇到过
问新华龙或益登的FAE最快!

使用特权

评论回复
5
auzxj|  楼主 | 2009-8-22 01:04 | 只看该作者
4# victech 我主要是懒得打电话,呵呵

使用特权

评论回复
6
古道热肠| | 2009-8-22 10:58 | 只看该作者
哈哈,您这解决问题的思路很对.
发现问题,首先去找找看,别人是否也遇到过,如何解决的,不可全信,不可不信,然后结合自己的经验,推断出其可能病因,最后对症下药,方能药到病除.
C语言编程,有些东西您看不到摸不着,首先定位BUG点,然后设法去除BUG,最后反证测试解决的方法是否用效,如果有效,说明方法可行.

使用特权

评论回复
7
ayb_ice| | 2009-8-22 12:14 | 只看该作者
都是狗在咬人,C8051F复位后狗就被放出来了,所以复位后尽快把它关起来了.

使用特权

评论回复
8
auzxj|  楼主 | 2009-8-22 13:23 | 只看该作者
本帖最后由 auzxj 于 2009-8-22 13:30 编辑
哈哈,您这解决问题的思路很对.
发现问题,首先去找找看,别人是否也遇到过,如何解决的,不可全信,不可不信,然后结合自己的经验,推断出其可能病因,最后对症下药,方能药到病除.
C语言编程,有些东西您看不到摸不着,首先定 ...
古道热肠 发表于 2009-8-22 10:58

感谢古哥的支持:lol

使用特权

评论回复
9
auzxj|  楼主 | 2009-8-22 13:26 | 只看该作者
都是狗在咬人,C8051F复位后狗就被放出来了,所以复位后尽快把它关起来了.
ayb_ice 发表于 2009-8-22 12:14

这狗确实挺讨厌的,别看这问题描述起来简单,当时我查问题,优化程序,在网上搜索资料,又由于自己比较菜,搞了差不多一周才发现问题所在,那个启动代码也算是有BUG

使用特权

评论回复
10
georgekin203| | 2009-8-23 09:19 | 只看该作者
楼主的xdata超过多少字节导致时间过长啊?

使用特权

评论回复
11
yewuyi| | 2009-8-23 10:36 | 只看该作者
出这样的问题只能说明要么是芯片设计的思想太差,要么是编译器设计的思想太差。

完全有如下两种方法解决:
1、芯片复位为,WATCHDOG的复位时间即恢复到最大时间,直到用户的应用程序对其进行了更新后才按照新的更短的复位时间执行。
2、如果芯片未做如此设计,那么编译器就应该在引导程序开始时,软件切换到最大,在引导结束后再切换到默认值。
3、除了C8051,我还是第一次听说有谁家的MCU有这样的问题的,呵呵,鄙视一下C8051。。。

使用特权

评论回复
12
ayb_ice| | 2009-8-23 12:19 | 只看该作者
自己修改启动文件,在清零RAM前就关闭WDT不就完了,还这个有问题,那个有问题,都是自己水平问题,不了解芯片所致.
我们这些应用级别的人根本没有资格评论编译器,设计MCU的人.

使用特权

评论回复
13
auzxj|  楼主 | 2009-8-23 12:27 | 只看该作者
10# georgekin203
貌似是128,具体的我周一回公司看看程序

使用特权

评论回复
14
auzxj|  楼主 | 2009-8-23 12:34 | 只看该作者
自己修改启动文件,在清零RAM前就关闭WDT不就完了,还这个有问题,那个有问题,都是自己水平问题,不了解芯片所致.
我们这些应用级别的人根本没有资格评论编译器,设计MCU的人. ...
ayb_ice 发表于 2009-8-23 12:19

一个MCU的设计就应该考虑各个层次的应用人员的水平,像这样的问题,初学者遇到了很难定位问题的所在,你可以搜一下看看,有多少论坛里有这个问题没有解决,我也是找了很长时间,才在一个不起眼的位置找到了提示。。。
我虽然水平一般,但比我菜的也大有人在,要是他们遇到这类问题,不见的能花一周时间就完美的解决。。。。

使用特权

评论回复
15
auzxj|  楼主 | 2009-8-23 12:36 | 只看该作者
出这样的问题只能说明要么是芯片设计的思想太差,要么是编译器设计的思想太差。

完全有如下两种方法解决:
1、芯片复位为,WATCHDOG的复位时间即恢复到最大时间,直到用户的应用程序对其进行了更新后才按照新的更短 ...
yewuyi 发表于 2009-8-23 10:36

他的启动代码貌似直接调用keil里51的启动代码,他们自己没有做。。。。。。

使用特权

评论回复
16
yewuyi| | 2009-8-23 13:16 | 只看该作者
自己修改启动文件,在清零RAM前就关闭WDT不就完了,还这个有问题,那个有问题,都是自己水平问题,不了解芯片所致.
我们这些应用级别的人根本没有资格评论编译器,设计MCU的人. ...
ayb_ice 发表于 2009-8-23 12:19


极不同意ayb_ice的观点,我们是他们产品的用户,也就是他们的客户,如果客户都没资格善意的评论的话,那就真的是很悲哀拉。。。

从C编译器的角度看,启动引导文件本来就应该是无故障的,这本来就是它应该尽到的产品最基本的功能,如果包含有故障还不如提示不能编译或编译出错提示呢。。。

呵呵,是不是要求太高了呢,个人认为:这个属于合理要求。

使用特权

评论回复
17
georgekin203| | 2009-8-23 15:23 | 只看该作者
128byte 的xdata就不行了?不会吧?是不是还有别的原因?
我用的是040,用了3k的xdata,也没有出现楼主位说的问题啊?

使用特权

评论回复
18
ayb_ice| | 2009-8-23 18:48 | 只看该作者
C8051F最低都是256,这是没有任何问题的,只是几K的XRAM时有问题.
LZ一周才找出问题,只能说明你水平太差,难道你不会用调试吗,C8051F的优势你都不用...

使用特权

评论回复
19
auzxj|  楼主 | 2009-8-23 19:02 | 只看该作者
17# georgekin203
具体多大我忘了,好几个月前的了,明我回公司看一下程序。。。。

使用特权

评论回复
20
auzxj|  楼主 | 2009-8-23 19:03 | 只看该作者
18# ayb_ice
请看我的签名。。。。。。

使用特权

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

本版积分规则

个人签名:當我不如意時.我掏出小JJ.凝視靜思他所蘊涵的精神-能長能短.能粗能細.能曲能伸.能軟能硬.那困難還算個鳥?

629

主题

1625

帖子

1

粉丝