zoukankan      html  css  js  c++  java
  • DSP中的DELAY_US ( )函数存放在FLASH下执行在RAM中的方法

    DSP程序为了实现精确的定时,通常使用汇编语言编写的延时函数DSP28x_usDelay(),该函数位于文件DSP281x_usDelay.asm。

    为了调用该函数,在Main.c中做了如下声明:

    1 extern void DSP28x_usDelay(Uint32 time);

    在文件DSP281x_Examples.h中做了如下的宏定义:

    1 #define DELAY_US(A) DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)

    从定义很容易推算出,需要延时A微妙就把DELAY_US()的参数设置为A即可。(A*1000/CPU_RATE-9≈A*1000/CPU_RATE,一个函数周期有五个CPU指令时间,每个CPU指令时间为CPURATE)

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

    首先,在DSP281x_usDelay.asm中使用

    1 .sect "ramfuncs"  //最好对应CMD文件进行配置

    将该段代码定义到段“ramfuncs”中,段“ramfuncs”的位置在编译时指定,实际上由CMD文件中的如下语句来指定:

    1 ramfuncs    LOAD = FLASHD, PAGE = 0,
    2 
    3             RUN = RAML0, PAGE = 1,
    4 
    5             LOAD_START(_RamfuncsLoadStart),
    6 
    7             LOAD_END(_RamfuncsLoadEnd),
    8 
    9             RUN_START(_RamfuncsRunStart)

    第1行表示该段的装载在PAGA0的FLASHD中(PAGA0和FLASHD的分段请见F2812.cmd文件,后文将有详解);

    第2行表示该段的运行地址在PAGE1的RAML0中(PAGA1和RAML0的分段请见F2812.cmd文件,后文将有详解);

    LOAD_ START(_RamfuncsLoadStart)令编译器创建了一个变量RamfuncsLoadStart,该变量指向段ramfuncs的装载地址的首地址(LOAD_ START为编译伪指令,请见CCS的帮助文档);

    LOAD_ START(_RamfuncsLoadEnd)令编译器创建了一个变量RamfuncsLoadEnd,该变量指向段ramfuncs的装载地址的末地址(LOAD_ END为编译伪指令,请见CCS的帮助文档);

    LOAD_ START(_RamfuncsRunStart)令编译器创建了一个变量RamfuncsRunStart,该变量指向段ramfuncs的运行地址的首地址(LOAD_ START为编译伪指令,请见CCS的帮助文档);

    从第1和2行可以看出,段“ramfuncs”中的函数DSP28x_usDelay()的装载地址和运行地址是不同的,本程序中装载在Flash的块FLASHD中,而在SARAM L0中运行,这只是目标,实际运行时DSP并会自动将Flash中的代码拷贝到SARAM中,因此需要手动添加代码来完成。

    在C函数中,为了使用变量RamfuncsLoadStart、RamfuncsLoadEnd和RamfuncsRunStart,必须先声明,本工程在文件DSP281x_GlobalPrototypes.h中做了如下声明:

    1 extern Uint16 RamfuncsLoadStart;
    2 
    3 extern Uint16 RamfuncsLoadEnd;
    4 
    5 extern Uint16 RamfuncsRunStart;

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

    然后就可以使用了。在Main.c中,使用MemCopy()函数将段ramfuncs中的函数DSP28x_usDelay()的代码从装载地址RamfuncsLoadStart—RamfuncsLoadEnd拷贝到RamfuncsRunStart开始的SARAM空间中。之后在程序运行时,只要调用DSP28x_usDelay()函数,都会自动地指向SARAM中相应的函数入口地址,这一点是自动完成的。MemCopy()函数原型在MemCopy.c中,在DSP281x_GlobalPrototypes.h声明。

    注意:即使这样,定时仍然可能不精确,因为可能有中断打断DSP28x_usDelay()的运行,所以在调用之前要关中断。

    为了精确测量程序所用时间,可以调用Debug模式下的RUN--CLOCK功能,乘以CPU指令运行周期即可计算对应代码运行周期。

  • 相关阅读:
    使用字体图标完整步骤
    用position:absolute定位小窗口位于版面正中心
    MySql 技术内幕 (第7章 游标)
    MySql 技术内幕 (第5章 联接与集合操作)
    赋值语句作为判断的条件
    发布订阅模式和观察者模式
    关系代数
    数据库关系代数表达式学习
    软考通过分数
    哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度
  • 原文地址:https://www.cnblogs.com/Fangjq2020/p/13263796.html
Copyright © 2011-2022 走看看