DSP F28335 DELAY_US函数使用问题

 

前言

DSP F28335的DELAY_US函数用于产生微秒级的延时,仿真时如果设置在RAM中直接运行时不会产生任何问题。然而如果将程序烧入FLASH中运行时会直接导致程序异常,并跳转至interrupt void ILLEGAL_ISR(void)内。

产生问题的直接原因是DELAY_US函数在flash内的地址与ram地址并不相同。解决方法如下(开发环境为CCS V6):


 

一、

DELAY_US(A),在文件DSP281x_Examples.h中有如下宏定义:
#define DELAY_US(A) DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)

从定义很容易推算出,需要延时A微妙就把DELAY_US()的参数设置为A即可。

在仿真调试的情况下运行程序,延时是较准确的,但是当把程序烧写到flash里运行时,如果程序上不做修改,就会很容易发现延时的时间比你设置的要长(通过延时控制LED灯闪烁,很直观)。这是因为,DSP访问flash时需要等待时间的,而访问RAM时几乎是零等待,所以在使用DELAY_US(A)时要想延时时间准确必须使其在RAM里运行,在程序上需做如下修改:

1、在DSP2833x_usDelay.asm中,有如下代码:


      .def _DSP28x_usDelay
      .sect "ramfuncs"

       .global  __DSP28x_usDelay
_DSP28x_usDelay:
       SUB   ACC,#1
       BF    _DSP28x_usDelay,GEQ   ;; Loop if ACC >= 0
       LRETR

其中.sect "ramfuncs"语句的作用就是就把用汇编写的函数DSP28x_usDelay定位在ramfuncs段。

二、

在工程中添加源文件DSP2833x_MemCopy.c该文件中的函数void MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr),实现把你想复制的代码从装载地址RamfuncsLoadStart—RamfuncsLoadEnd拷贝到RamfuncsRunStart开始的SARAM空间中。

三、

在文件DSP2833x_SysCtrl.c开头,通过伪指令定义一个代码段,注意位置一定要放在函数前面:

 

#include "DSP2833x_Device.h"     // Headerfile Include File
#include "DSP2833x_Examples.h"   // Examples Include File

// Functions that will be run from RAM need to be assigned to
// a different section.  This section will then be mapped to a load and
// run address using the linker cmd file.

#pragma CODE_SECTION(InitFlash, "ramfuncs");

四、

在main函数中要调用MemCopy函数,注意该函数放置的位置。

void main(void) {

    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2833x_SysCtrl.c file.
    //初始化系统时钟
       InitSysCtrl();
       MemCopy(&RamfuncsLoadStart,&RamfuncsLoadEnd,&RamfuncsRunStart);
       InitFlash();

五、

修改用于烧写的CMD文件,我这里是在F28335.cmd文件内

SECTIONS
{
 
   /* Allocate program areas: */
   .cinit              : > FLASHA      PAGE = 0
   .pinit              : > FLASHA,     PAGE = 0
   .text               : > FLASHA      PAGE = 0
   codestart           : > BEGIN       PAGE = 0
   ramfuncs            : LOAD = FLASHD, 
                         RUN = RAML0, 
                         LOAD_START(_RamfuncsLoadStart),
                         LOAD_END(_RamfuncsLoadEnd),
                         RUN_START(_RamfuncsRunStart),
                         PAGE = 0

 

六、

注意在头文件DSP281x_GlobalPrototypes.h 别忘做如下声明:

 

//---------------------------------------------------------------------------
// External symbols created by the linker cmd file
// DSP28 examples will use these to relocate code from one LOAD location
// in either Flash or XINTF to a different RUN location in internal
// RAM
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;

extern Uint16 XintffuncsLoadStart;
extern Uint16 XintffuncsLoadEnd;
extern Uint16 XintffuncsRunStart;

你可能感兴趣的:(DSP,dsp,嵌入式)