准备材料
新建空的工程
- 点击"Project"->"New CCS Project"。
- 在New CCS Project窗口中,按需要填写以下内容后按"Finish"完成新建空的工程。
新建完成后的工程,结构如下: - 点击左上方的编译按钮,应该能够顺利的编译通过,但是会出现一个警告。
工程配置
添加系统的头文件
- 在工程名上右击,添加两个文件夹,分别名为source和include。
- 打开"tidcs\c28\DSP281x\v120"文件夹,将"DSP281x_headers\include"中的所有头文件复制到刚刚新建的include目录。
- 打开"tidcs\c28\DSP281x\v120"文件夹,将"DSP281x_common\include"中的所有头文件复制到刚刚新建的include目录(会提示文件已存在,覆盖即可)。
此时,工程文件夹的结构如图所示:
配置工程
右击工程文件名,选择"Properties"
可板上执行的工程配置
根据上文的配置过程,虽然代码能够正常的通过编译,但是却没有任何的实际功能。这里,以点亮运行灯(即主循环执行过程中,固定间隔点亮的灯)为例,介绍可用的代码的配置过程。
添加必须的头文件代码
在main函数中,添加以下的头文件: #include "DSP281x_Device.h" #include "DSP281x_Examples.h" 其中,DSP281x_Device.h提供了对应的CPU寄存器的结构体信息,DSP281x_Examples.h主要提供了一个纳秒级的延时函数DELAY_US(A)。不过,为了使用此函数,还需要将一个汇编代码文件添加到工程中: 在项目文件名称上右击,选择"Add Files",打开的窗口中选择"DSP281x_common\source"文件夹中的"DSP281x_usDelay.asm"。然后手动将asm文件拖动到source目录下。 此时,项目文件夹的组织结构如图。
添加必要的源文件
一个能够正常在开发板上运行的工程,应该具备一下的必要的源文件。 - 添加"DSP281x_headers\source"目录下的"DSP281x_GlobalVariableDefs.c"以指定所有系统结构体的存储位置。
- 添加"DSP281x_common\source"目录下的"DSP281x_SysCtrl.c"以初始化系统的控制选项,包括PLL,看门狗,预分频。
- 添加"DSP281x_common\source"目录下的"DSP281x_Gpio.c"以初始化系统的GPIO口。
- 添加"DSP281x_common\source"目录下的"DSP281x_PieCtrl.c以初始化PIE控制器。
- 添加"DSP281x_common\source"目录下的 "DSP281x_PieVect.c"以初始化PIE向量表。
- 添加"DSP281x_common\source"目录下的"DSP281x_InitPeripherals.c"以初始化其他外设。
- 添加"DSP281x_common\source"目录下的"DSP281x_DefaultIsr.c"以使用默认的中断函数。
添加cmd文件
本程序非TI的BIOS系统应用,所以需要添加"DSP281x_headers\cmd"目录下的"DSP281x_Headers_nonBIOS.cmd"。
到此,可以尝试编译工程,应该能够正常的编译通过,且没有任何的警告。目录结构应该如下所示(分别是头文件,源文件和链接文件):
第一个可执行程序——点亮LED灯
- 编辑main函数,将main函数修改成如下的内容:
#include "DSP281x_Device.h" // 添加必要的头文件 #include "DSP281x_Examples.h" // 添加必要的头文件
int main(void) { // 1. 初始化系统控制,PLL,看门狗,预分频 InitSysCtrl(); // 2. 初始化GPIO InitGpio(); // 3. 关闭中断,然后初始化PIE向量表 DINT; // INTM 置一,关中断 InitPieCtrl(); // 初始化 PIE 控制寄存器到默认状态 //(所有PIE中断禁用,标志清空) // 在 DSP281x_PieCtrl.c 中定义 IER = 0x0000; // 禁用 CPU 中断 IFR = 0x0000; // 清空 CPU 中断标志 InitPieVectTable(); // 初始化 PIE 向量表 // 在 DSP281x_PieVect.c 中定义
// 4. 初始化所有的外设 // InitPeripherals(); // 在 DSP281x_InitPeripherals.c 中定义 // 需要启用哪些硬件,在此函数中设置
// 5. 用户指定的代码后启用中断 // 用户指定的其他函数 EINT; ERTM; for(;;) { } } main函数虽然是int类型的,但是这里不需要结尾的"return 0;",否则在编译时会提示一个警告。 - 编辑"DSP281x_Gpio.c",修改InitGpio()函数:
void InitGpio(void) { // GpioMuxRegs 受到保护,需要EALLOW后才能配置 EALLOW; // 设置为GPIO口 GpioMuxRegs.GPAMUX.bit.T1PWM_GPIOA6 = 0; // 配置为输出引脚 GpioMuxRegs.GPADIR.bit.GPIOA6 = 1; EDIS; } - 在main函数中定义一个变量(Uint32)main_counter,然后修改for循环,添加如下语句:
for(;;) { main_counter++; if(main_counter > 5000000) { main_counter = 0; GpioDataRegs.GPATOGGLE.bit.GPIOA6 = 1; } }
到此,编译后点击Debug,可以观察到开发板上对应于102引脚上的LED灯能够规律性的闪烁。
将程序固化到Flash中
将程序固化到flash中非常的"简单"。
让程序跑在RAM中
Ti官方提供了2种让程序固化在Flash中而能够运行于RAM中的方法。 第一种方案,需要设置cmd文件的同时,还需要兼顾代码本身,稍显麻烦。
方法一:部分代码加载到RAM
再议……
方法二:所有代码加载到RAM
不过,示例代码中的cmd文件对内存结构相比于ti提供的默认头文件,有较大的更改,假如不想使用示例代码中的cmd,那就看看都做了哪些更改吧。
spraau8的cmd文件中的主要变化
对比spraau8提供的cmd文件,可以看到,最大的变化是,诸如下图所示的初始化方法: 其中标注1的地方,表示将".text"存储在"FLASH_AB"区;标注2的地方,表示此存储区的代码将会在"RAM_L0L1"中运行;标注3的地方,表示此部分代码的起始位置为"_text_loadstart";标注4的地方,表示此部分代码的结束位置为"_text_runstart";最后一行也即第5行,表示此部分代码的长度为"_text_size"。那么,值得好奇的是,这些最前面是下划线的字段都是哪里来的呢。其实,它们都在文件"DSP28xxx_SectionCopy_BIOS.asm"中定义了。 其次,就是初始化的段中多了一个".cinit"。这个东西又是哪里来的呢。它的定义,在"DSP28xxx_SectionCopy_nonBIOS.asm"中,具体的含义,可以看spraau8的pdf文档。 最后,示例代码中,将需要移动的段都放在了FLASHAB中,而启动后复制到的位置,都在"RAM_H0"和"RAML0L1"中。 到这里我们差不多就可以自己修改cmd文件了。 - 将上面工程中的"DSP281x_CodeStartBranch.asm"替换为代码示例中的"DSP281x_CodeStartBranch"。
- 将代码示例中的"DSP28xxx_SectionCopy_nonBIOS.asm"添加到source中。
- 修改"DSP281x_Headers_nonBIOS.cmd"
- 修改"F2812.cmd"
|