DSP

28xx 系列dsp c/c++编程入门

2019-07-13 10:42发布

第一章:建立一个工程

1.1      步骤1:准备工作

  从TI公司提供的C2833xC2823x CC++ Header Files and Peripheral Examples中将有用的文件复制到工程目录下“Sources_DSP”文件夹内。   图 1 安装“C2833xC2823x CC++ Header Files and Peripheral Examples图 2 例如将“C2833xC2823x CC++ Header Files and Peripheral Examples”安装在盘根目录下, 进入目录“D: idcsc28DSP2833xv120”可以看到如下图所示内容: 注:D: idcsc28DSP2833xv120 其中v120是T I定义的版本号1.2版,它可能有更新的版本。  图 3 其中文件夹“doc”中有头文件使用说明相关文档; 其中文件夹“DSP2833x_examples”中有大量的实例程序,可以供我们参考; 其中文件夹“DSP2833x_common”和文件夹“DSP2833x_headers”我们可以直接复制到我们的工程目录下,也可以选择一部分文件复制到我们工程目录下的一个单独的文件夹内。习惯上我们是在工程目录下单独建一个文件夹命名为“Sources_DSP”。然后把DSP芯片有关的“.C”“.h .lib” “.cmd”文件都放到“Sources_DSP”文件夹内。  主要包括以下文件: 表格 1 目录 文件名 备注 D: idcsc28DSP2833xv120DSP2833x_headerssource DSP2833x_GlobalVariableDefs.c   D: idcsc28DSP2833xv120DSP2833x_headersinclude 该目录下的全部文件   D: idcsc28DSP2833xv120DSP2833x_headerscmd DSP2833x_Headers_nonBIOS.cmd 根据需要选择 D: idcsc28DSP2833xv120DSP2833x_commonsource 该目录下的全部文件   D: idcsc28DSP2833xv120DSP2833x_commonlib IQmath_fpu32.lib 可以选择其他文件 D: idcsc28DSP2833xv120DSP2833x_commoninclude DSP28x_Project.h DSP2833x_Examples.h DSP2833x_GlobalPrototypes.h DSP2833x_DefaultIsr.h 可以选择更多其他文件 D: idcsc28DSP2833xv120DSP2833x_commoncmd 28335_RAM_lnk.cmd  

1.2      步骤2:打开CCS软件,新建工程,如下图所示:

图 4 例如:在目录D:DTS2000Prj下新建一个工程命名为DTS2000,如下图所示: 图 5

1.3      步骤3:进入D:DTS2000PrjDTS2000 目录下,新建一个文件夹假设命名为“Sources_DSP”。

将与DSP芯片有关的 “h”,“clib”,“cmd”文件复制到Sources_DSP”文件夹内如表格1介绍。

1.4      步骤4:修改工程的编译选项

图 6
选择支持浮点处理器 图 7          
在 Include Search Path 输入头文件路径(相对于.prj文件的路径)。也可以将“DSP2833x_common”和文件夹“DSP2833x_headers”直接复制到我们的工程目录下,Include Search Path输入:DSP2833x_headersinclude; DSP2833x_commoninclude 两个包含路径,中间用“;”隔开。 图 8

1.5      步骤4:编辑主程序代码

主程序代码示例: #define  APP_MAIN_GLOBALS #i nclude "Sources_DSPDSP2833x_Device.h"     // Device Headerfile and Examples Include File #i nclude "Sources_DSPDSP2833x_Examples.h" void main(void) {        // Step 1. Initialize System Control:        // PLL, WatchDog, enable Peripheral Clocks        // This example is found in the DSP2833x_SysCtrl.c file.        InitSysCtrl();          // Step 2. Initalize GPIO:        InitGpio();        InitXintf();          // Step 3. Clear all interrupts and initialize PIE vector table:        // Disable CPU interrupts        DINT;        MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);        InitFlash();  //必须在RAM内完成该操作        // Initialize the PIE control registers to their default state.        InitPieCtrl();        // Disable CPU interrupts and clear all CPU interrupt flags:        IER = 0x0000;        IFR = 0x0000;        InitPieVectTable();        EALLOW;      // This is needed to write to EALLOW protected registers        PieVectTable.TINT0     = (PINT)&s_Timer0ISR;//定时器0中断        EDIS;         PieCtrlRegs.PIEIER1.bit.INTx7 = 1;     //定时器0中断使能        IER = M_INT1|M_INT8|M_INT9;        EINT;            s_InitMAX3100_IRQ();        s_InitMAX3100(0xe40b);        //进入应用程序        //s_App();        for(;;); } 对于主程序笔者发现了以下几个问题: 注1:头文件包含要正确地指出相对路径,否则编译器找不到该头文件 #i nclude "Sources_DSPDSP2833x_Device.h"     // Device Headerfile and Examples Include File #i nclude "Sources_DSPDSP2833x_Examples.h" 注2:如果要初始化FLASH        MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);        InitFlash();  //初始化FLASH必须在RAM内完成该操作 可以在“DSP2833x_MemCopy.cpp”文件头上补充:#i nclude "DSP2833x_Examples.h" 因为MemCopy函数是在DSP2833x_Examples.h文件里声明的所以要包含它。否则编译器会报  _MemCopy( )  is undefined symbo”。不过还有很多其他解决方法。 注3:如果使用外部接口 InitGpio();        InitXintf(); 顺序不能对调了,因为28335的外部接口可以配置为通用I/O,函数InitGpio()就是把它配置为通用IO,如果没有调用InitXintf(),你会发现访问不了外部SRAM!! 如果先调用InitXintf();再调用InitGpio();仍然是把外部接口配置为通用I/O,所以顺序不能对调,也不能不调用InitXintf() 注4:如果C ++编写代码笔者曾遇到以下几个问题: 1.函数 void InitPieVectTable(void)实体内有一条语句是: Uint32 *Source = (void *) &PieVectTableInit;        Uint32 *Dest = (void *) &PieVectTable; 要改为: Uint32 *Source = (Uint32*) &PieVectTableInit;        Uint32 *Dest = (Uint32*) &PieVectTable; C允许把任意类型的指针赋值给void值针,也可以把void值针赋值给任意类型的指针,因为C++语法更严谨,不允许这种操作。 2.分配中断向量时要注意: PieVectTable.TINT0     = (PINT)&s_Timer0ISR;//定时器0中断(这是刘刚发现的) 要把中断服务子程序入口地址强制转换成 PINT 型,究其原因和上一个问题是一样的。 3.一个工程里不允许出现既有 .c”又有“.cpp”,这样会出现诡异的编译报错,编译器会按照c语言来编译,凡是不符合c语法的编译器都会认为是错误的,如果不注意这点,看到一堆error会让人摸不着头。 4.要用Inline 函数时 不是在函数声明前面加关键字Inline,而是在函数实体前面加关键字Inline。例如: inline void s_SysRealySetUp(void) {        INT16U i;        INT8U uch_RelayBordNum;        for(i=0;i        {            guch_RelayComTransBuf[15+i] = e_guch_RelaySet[i];        } }

1.6      步骤5:必须加入的C/C++源文件

如下表格2所示 表格 2 文件名 备注 DSP2833x_CodeStartBranch.asm 必须有(如果没有该文件,程序无法固化到flash内) DSP2833x_ADC_cal.asm 必须有(配置ADC的工作模式,详见:spru812a.pdfDSP2833x_DefaultIsr.cpp 必须有 DSP2833x_GlobalVariableDefs.cpp 必须有 DSP2833x_PieVect.cpp 必须有 DSP2833x_PieCtrl.cpp 必须有 DSP2833x_SysCtrl.cpp 必须有 DSP2833x_Xintf.cpp 如果没有用到外部接口可以没有 DSP2833x_Gpio.cpp 如果没有用到GPIO可以没有 DSP2833x_MemCopy.cpp 如果没有开启flash流水线,初始化flash就可以没有 F228335_FLASH_UPDATE.cmdFPI程序升级(高平波提供,如果有疑问可以问高平波) 如果写的是测试程序不需要固化,可以用以下两个cmd文件:28335_RAM_lnk.cmd 和 DSP2833x_Headers_nonBIOS.cmd,(见表格1)仅仅把程序载入DSP内部RAM,调试很方便。 图 9 对于一个测试程序的工程建立过程到此可以告以段落了。当然对于一个真正的应用工程,我们还要把我们部门内部公共的代码文件(如:CRC校验)加进来编译,这里就不详细讨论了。接下去我们讨论在写代码过程中遇到的一些问题。