使用sprc097的DSP281x_usDelay.asm

在ti sprc097的example中,提供了一个us延时函数,其使用很简单,它的声明放在了DSP281x_Examples.h里面:

#define CPU_RATE    6.667L   // for a 150MHz CPU clock speed (SYSCLKOUT)
//
DO NOT MODIFY THIS LINE. #define DELAY_US(A) DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)

ps:上面的CPU_RATE的值要与DSP281x_SysCtrl.c里面的InitPll(0xA);的参数相对应。

使用时候,调用即可,单位为us(microseconds)。但是为了确保延时准确,还要注意两个事情:

1、在 0 waitstate ram中执行此函数,我们知道读flash会有一个waitstate的延时,这个会影响此函数计时的准确性,F2812各个存储区的waitstate如下:

from:TMS320F281x Data Sheet (Rev. L).pdf

所以,如上表,我们可以放在M0,M1,L0&L1,H0来运行此函数。

2、为确保准确性,在运行此函数之前关中断。如果不能关中断,那么这个延时可能比预想的要长。

 

  实际使用中,如何将此函数放在0 waitstate ram中运行呢?

情景一、Ram调试(即程序段(page0)和数据段(page1)都在ram中),那么不用过多的管,因为本来就载入(Load)在ram中,运行肯定也是。

情景二、写入到Flash,在Flash中运行。注意到在DSP281x_usDelay.asm中是将此函数定义到了段“ramfuncs”中:

       .def _DSP28x_usDelay
       .sect "ramfuncs"

而“ramfuncs”在cmd中是这么定义的:

MEMORY
{
PAGE 0:    /* Program Memory */
           /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */

... ...
   RAML0       : origin = 0x008000, length = 0x001000     /* on-chip RAM block L0 */ FLASHD : origin = 0x3EC000, length = 0x004000 /* on-chip FLASH */ ... ... PAGE
1 : /* Data Memory */ /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE0 for program allocation */ /* Registers remain on PAGE1 */ ... ... RAML1 : origin = 0x009000, length = 0x001000 /* on-chip RAM block L1 */ ... ... } /* Allocate sections to memory blocks. Note: codestart user defined section in DSP28_CodeStartBranch.asm used to redirect code execution when booting to flash ramfuncs user defined section to store functions that will be copied from Flash into RAM */ SECTIONS { ... ... ramfuncs : LOAD = FLASHD, RUN = RAML0, LOAD_START(_RamfuncsLoadStart), LOAD_END(_RamfuncsLoadEnd), RUN_START(_RamfuncsRunStart), PAGE = 0 ... ... }

可以看到,这个段加载在FLASHD,运行在RAML0,完全ok,这样,只要再运行DSP28x_usDelay之前,手动copy一下就行了:

// Copy time critical code and Flash setup code to RAM
// This includes the following ISR functions: EvaTimer1(), EvaTimer2()
// EvbTimer3 and and InitFlash();
// The  RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
// symbols are created by the linker. Refer to the F2812.cmd file. 
   MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);

运行一下这个MemCopy函数即可,RamfuncsLoadStart, RamfuncsLoadEnd, 和RamfuncsRunStart是在上面的cmd文件中定义的,连接器在分配空间之后,把段ramfuncs 的几个地址幅值到这几个变量中了。LOAD_START等几个的定义可见

spru513b :TMS320C28x Assembly Language Tools User’s Guide

 

而当你决定在Flash中运行,其实上面MemCopy的工作本来就是必须做的,因为在Flash中运行的话,InitFlash(); 本来就必须在Ram中运行,而InitFlash()也刚好定义在ramfuncs里面,在运行InitFlash()之前就必须运行一次MemCopy了,所以,对于使用DSP28x_usDelay,相当于不用任何附加的操作,添加其源文件直接使用即可(当然,要自己考虑中断的影响)。

 

posted @ 2012-11-27 18:51  果壳中的宇宙  阅读(2536)  评论(2编辑  收藏  举报