转:C8051F 进不了main函数问题解决办法
问题:
在做C8051F380的一个程序,但在硬件仿真的时候一直进不了main函数。使用的是Keil uV4开发环境,我在STARTUP.A51文件的198行设置断点,如下,可以run到该断点处,说明启动代码执行正常。正常情况下该调整到main()函数执行C程序了,然而我现在全速(F5)执行,过一会程序再次停到该处。并没有跳转到main()函数,(我在待字婚中main()里的第一条语句处设置了断点)。
进入Debug模式后,首先全速执行到198行,然后在187行设置断点,全速执行,执行后的结果如下:
这是为什么呢???这说明了什么???为什么又执行回去了呢?难道是看门狗导致的?对就是这条狗的问题。下面进行分析。
----------------------------------------------------------------------------------------------
由于程序稍微大了些:Program Size: data=35.4 xdata=1289 code=13929。使用的开发环境是Keil uV4,Keil Option-->Target下的设置如下:
由于程序中data比较大,所以在Memory Modelbabygirl下设置为Large模式。程序编译通过,无错误,警告很多如下。警告只要是两种类型,一种是 INCOMPATIBLE MEMORY MODEL型,估计是C8051Fxxx 的USB的库中选择Memory Model类型为SMALL格式,而我这里工程设置的为Large模式,所以Keil给出这个警告;另外一种是 UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS,这种警告是提醒定义了一些函数,因为整个程序就没有调用到,所以给了警告。
*** WARNING L14: INCOMPATIBLE MEMORY MODEL
MODULE: .\C8051F_USB\USBX_F38X.LIB (USB_API)
MODEL: SMALL
*** WARNING L14: INCOMPATIBLE MEMORY MODEL
MODULE: .\C8051F_USB\USBX_F38X.LIB (USB_CLOCK_START)
MODEL: SMALL
*** WARNING L14: INCOMPATIBLE MEMORY MODEL
MODULE: .\C8051F_USB\USBX_F38X.LIB (USB_SUSPEND)
MODEL: SMALL
*** WARNING L14: INCOMPATIBLE MEMORY MODEL
MODULE: .\C8051F_USB\USBX_F38X.LIB (GET_INTERRUPT_SOURCE)
MODEL: SMALL
......
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
SEGMENT: ?PR?KEY_SCAN?HS6200_TEST_SYS
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
SEGMENT: ?PR?TIMER_INIT?HS6200_TEST_SYS
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
SEGMENT: ?PR?DELAY_50US?C8051F_DELAY
......
从上面的分析可以看出,程序几乎没有问题。问题出在哪呢?
从Program Size(如上面红色部分所示)可以看出,原程序在xdata开辟了大量的数据(1289 Byte),在启动代码中会执行对xdata的初始化,由于C8051F380有看门狗,而看门狗默认是开启的。大部分程序员(一般)会在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
--------------------------------------------------------------------------------------------
解决方法:
修改大学生教室STARTUP.A51函数,在启动代码(STARTUP.A51愁眉不展的意思)中增加关闭看门狗的语句。下面
是修改后的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爱我却要离开我
;
; *** <<< U Configuration Wizard in Context Menu >>> ***
国学小名士;------------------------------------------------------------------------------
; STARTUP.A51: This code is executed after processor ret.
;
; To translate this file u A51 with the following invocation:
;
; A51 STARTUP.A51
;
; To link the modified STARTUP.OBJ file to your application u the following
; Lx51 invocation:
;
; Lx51 your object file list, STARTUP.OBJ controls
;
散步教案一等奖;------------------------------------------------------------------------------
;
; Ur-defined Power-On Initialization of Memory
;
; With the following EQU statements the initialization of memory
; at processor ret can be defined:
;
; IDATALEN: IDATA memory size <0x0-0x100>
; Note: The absolute start-address of IDATA memory is always 0
; The IDATA space overlaps physically the DATA and BIT areas.
IDATALEN EQU 80H
;
; XDATASTART: XDATA memory start address <0x0-0xFFFF>
; The absolute start address of XDATA memory
XDATASTART EQU 0
;
; XDATALEN: XDATA memory size <0x0-0xFFFF>
; The length of XDATA memory in bytes.
XDATALEN EQU 0
;
; PDATASTART: PDATA memory start address <0x0-0xFFFF>
; The absolute start address of PDATA memory
PDATASTART EQU 0H
;
; PDATALEN: PDATA memory size <0x0-0xFF>
; The length of PDATA memory in bytes.
PDATALEN EQU 0H
;
;
;------------------------------------------------------------------------------
;
; Reentrant Stack Initialization
;
; The following EQU statements define the stack pointer for reentrant
; functions and initialized it:
;
; Stack Space for reentrant functions in the SMALL model.
; IBPSTACK: Enable SMALL model reentrant stack