目录:
1 简介
1.1 DSP281x C/C++头文件和外设例程程序包安装
1.2 目录结构
2 外设位域结构编程方法
2.1 传统#define 方法
2.2 位域和结构方法
2.2.1 外设寄存器结构
2.3 增加位域
2.3.1 使用Bits-Fields编程时的Read-Modify-Write 考虑
2.3.2 使用Bits-Fields编程时的代码大小考虑
3 外设范例
3.1 开始
3.2 例程结构
3.2.1 包含文件
3.2.2 源代码
3.2.3 连接命令文件
3.3 例子编程流程
3.4 包含的例子
3.5 从FLASH开始执行例子
4 逐步使用头文件和范例代码
4.1 准备
4.2 包含DSP281X外设头文件
4.3 包含通用范例代码
5 常见问题和处理
5.1 read-modify-wriye的影响
5.1.1 多标志位寄存器写1 清零
5.1.2 Volatile Bits 寄存器
6 版本变化
7 包含内容
7.1 支持DSP281X的头文件
7.1.1 DSP281X的头文件-主函数
7.1.2 DSP281X的头文件-外设位域和寄存器结构定义文件
7.1.3 CCS的 .gel 文件
7.1.4 变量名和数据段
7.2 通用范例代码
7.2.1 支持的外设中断扩展模块
7.2.2 特殊外设文件
7.2.3 有用函数源文件
7.2.4 范例连接 .cmd文件
1 简介
TI针对’DSP281x系列DSP芯片使用通用的C/C++语言编写了外设头文件和范例程序。这些代码可以作为应用的工具或根据使用者的需要而作为开发平台的基础。传统的编程方法需要程序员自行编写寄存器的H文件和所需的片内外设的初始化、配置文件,与传统的编程方法比较,基于C281x C/C++的头文件提供了软件开发的程序框架,其中包含有寄存器结构定义文件、外设头文件和器件的宏与类型定义等系统所需的各种文件。通过在那新的或原有的工程文件使用外设头文件,开发者可很容易的使用C或C++语言来控制片上外设。除此之外,程序员可以改动工程中需要用到的外设和主控制程序,还可以从提供的范例代码中挑选有用的函数,丢弃那些不需要的函数。这样程序编写简便、结构清晰、易于修改和维护,同时由于框架不需做太大的变动,程序员可以将精力集中于算法的研究,从而加速项目或产品的研发进度。
注意:
本章没有提供使用CCS来编写C或连接或汇编代码的向导。前提是用户已经有了281x的硬件平台且通过计算机连接到CCS软件。使用者应该了解怎么使用CCS通过JTAG下载程序并能进行基本的DEBUG操作。
1.1 DSP281x C/C++头文件和外设例程程序包安装
在使用DSP281x C/C++头文件前,计算机中必须安装有CCS FOR 2000,然后必须安装DSP281x C/C++头文件和外设例程程序包,此文件可在TI网址下载,安装程序包为sprc097.rar。解压缩后直接点击安装,显示如下画面;
按提示继续操作,选择相应目录
点击Next安装完成。在ticds\c28\dsp281x\v100\doc目录下有相应帮助说明。
1.2目录结构
安装后,可以看到C281x C/C++头文件和外设例程清晰的目录结构。目录结构当前的版本为V1.00,从结构图可以看出C/C++头文件、外设例程和共享源代码分别单独存放。这种文件分类方法使查找文件方便,易于使用者快捷的将这些文件融合到新的或原来的工程文件中。
表1 DSP281x 主目录结构
目录
默认安装路径。
\doc
文档(包含版本更新信息)
\DSP281x_headers
合并外设头文件到新工程文件所需的文件。
头文件的bit-field结构方法的描述请见第3节
如何将外设头文件添加到新的或已有工程文件请见第4节
\DSP281x_examples
基于DSP281x 头文件的CCS编译的程序代码
这些例程说明了281x片上外设的配置
关于这些例程的综述请见第3节
\DSP281x_common
通过在DSP_281X外设程序中使用共享源文件来说明使用DSP_281X外设头文件来完成各种任务。如对新的工程文件有帮助,可以随意使用这些文件。第6节给出了这些文件的列表。
DSP281x_headers和DSP281x_common目录下的源文件根据文件类型被进一步分为各个子目录。表2列出了这些子目录及其文件的类型。
子目录
描述
DSP281x_headers\cmd
分配位域结构的连接命令文件,详见第2节
DSP281x_headers\source
需要并入新的或原有的项目文件的头文件的源文件
DSP281x_headers\include
281x片上外设的头文件
子目录
描述
DSP281x_common\cmd
281x的存储器命令范例文件
DSP281x_ common \source
281x外设例程通用 .h 文件
DSP281x_ common \include
281x外设例程通用 .c 文件
2 外设位域结构编程方法
DSP281x头文件和外设例程使用bit-field 结构方法来映射和访问基于281x的外设寄存器。本节介绍这种方法并与传统的#define方法进行了比较。
2.1 传统#define 方法
传统使用C语言访问寄存器的方法是通过使用#define宏来创建每个寄存器的地址标志。例如:
这种#define的定义方法可以重复来定义每个外设的每个寄存器。即使是的几个同类外设,例如SCI-A SCI-B,每个寄存器都可以根据其地址被独立的分开。传统的#define方法的不足主要有以下几条:
访问寄存器的每一位困难;
不能在CCS的watch window看到寄存器的位变化;
不能利用由CCS自动完成的代码向导的优势;
对于相同外设,头文件的开发者无法利用代码重用的优势。
2.2 位域和结构方法
位域结构的编程方法使用C语言将同一类外设的所有寄存器规为一组。然后连接器将每个C语言编写的外设寄存器结构体映射为存储器空间。这种映射允许编译器使用CPU的DP指针直接访问外设寄存器。除此之外,许多寄存器的位域也被定义了,这样编译器就可以直接读或操作寄存器内的单独位。
2.2.1 外设寄存器结构
2.1节中使用#define方法定义了CPU Timer 0寄存器。本节同样定义CPU Timer 0寄存器,但是使用C语言结构体将CPU Timer 寄存器统一定义。连接器将在内存中映射CPU Timer 0的寄存器结构体。
注意以下几点:
寄存器名字出现顺序必须与其在内存中分配的顺序相一致。
内存中保留的空间,在结构体中也用保留变量(rsvd1 rsvd2)表示,除非占用保留空间,否则这些保留结构体成员不会被使用。
Uint16 Uint32分别表示无符号 16-bit , 32-bit。在28x系列中,有unsigned int 和unsigned long两种类型。这主要是操作方便考虑,其相应的类型定义可以在DSP281x_Device.h中找到。
寄存器文件结构体定义用来声明一个访问寄存器的变量。芯片的每个外设都需要这样定义。多个同类外设使用同样的结构体定义。例如,在某个器件有三个CPU Timer,则可以被定义为三个 volatile struct CPUTIMER_REGS变量,如下:
声明变量时关键字volatile很重要,关键字volatile将告诉编译器变量的内容能被硬件改变,这样编译器就不会优化使用volatile定义的变量。
编译器使用DATA_SECTION 宏将每个外设结构体的相应变量分配到数据段。下面的例子,变量CpuTimer0Regs被分配到CpuTimer0RegsFile
数据段。
数据段再次为器件的每个外设寄存器结构体变量分配地址空间。每个结构体被分到其自己的数据段后,连接器直接映射每个数据段到内存映射寄存器,如下所示:
通过将变量直接映射到相同的外设寄存器内存地址空间,开发者可以使用C语言访问所需的变量成员来访问寄存器。如想写CPU-Timer 0 TCR 寄存器,则程序员不得不访问CpuTimer0Regs变量中的TCR成员。
2.3 增加某一位
实际中可能要经常直接访问寄存器的中的某位。C281x C/C++ 头文件和外设例程 中使用位域结构编程方法对许多片上寄存器的位进行了定义。
例如,可以对每个CPU-Timer寄存器的每个位定义。CPU-Timer Control寄存器的位定义如下:
使用统一体声明寄存器的优点就是既可以使寄存器以位域结构体被访问,又可以使其被当作一个16位或32位的变量整体被访问。例如,timer control 寄存器的统一体定义如下:
一旦每个寄存器的位域和统一体定义被确立,则CPU-Timer 寄存器结构体则能以统一体的定义方式被访问。
这样在C语言代码中,就可以用位域或单独量来操作CpuTimer 寄存器了。
位域结构方法具有以下的一些优点:
使用者不需要定义标志就可以操作寄存器的位;
在CCS的watch window可以直接查看寄存器文件和位;
当使用CCS时,编辑器将会自动弹出你所要输入的结构/位成分提示列表;这种自动的提示使编写代码变得很容易,从而省去了查找寄存器和位名字文档的麻烦。
2.3.1 使用位域编程时的Read-Modify-Write考虑
当对寄存器内的某一位进行写操作时,硬件将会产生一次read-modify-write操作,就是说,寄存器的内容被读出,其中的一位被修改,然后整个寄存器内容再被写回。对于28x器件这些操作在一个时钟周期即可完成。
当寄存器内容被写回时,寄存器内其他位将会以原值写回。由于一些寄存器不推荐使用位域方法访问,所以没有统一体定义。 这些例外的寄存器是那些对查询(读)某位有益的寄存器,包括:
当写1时即清除某位,如的事件管理标志寄存器;
无论何时访问都需要以一定的方式写的寄存器,如看门狗控制寄存器。
那些没有位或统一体定义的寄存器不能以 .bit或.all访问,如下:
2.3.2使用位域编程方法时的代码量考虑
使用位域定义访问寄存器使得代码易读、易修改、易维护。同时这种方法对访问或查询寄存器的某一位也非常有效。然而如果多次访问某一寄存器,每次使用.bit将会比使用一次.all访问寄存器的代码多得多。例如:
.bit的方法使得代码易读易改,但代码量稍有增加。如果代码长短对程序很重要则可以使用.all结构方法一次写整个寄存器。
3 外设实例
在C281x C/C++ Header Files and Peripheral Examples的DSP281x_examples\
目录下有几个工程项目例程,这些例程使用DSP281x V1.00头文件配置片上外设。3.4节给出了例程的清单。
3.1 入门
按以下步骤装载the DSP281x CPU-Timer例程作为开始。其他例子的调试步骤大同小异。
1.使用F2812 eZdsp或其他的硬件平台,在同CCS相连接。
2. 装载例程的GEL或工程项目文件
每个例程都包含一个CCS的GEL文件,这个文件自动装载工程项目、编译代码、配置观察窗。同样如不使用GEL文件可以直接装载工程文件。
按照以下顺序装载DSP281x CPU-Timer的GEL文件:
a 打开CCS:File->Load GEL
b 浏览CPU Timer 例程目录:DSP281x_examples\cpu_timer
c 选择并打开Example_281xCpuTimer.gel文件
d 从CCS的GEL下拉菜单中选择DSP281x CpuTimerExample-> Load_and_Build_Project装载并编译整个工程项目例程。
3 查看Example_281xCpuTimer.c原文件中main主文件最上面的注释文件Example_281xCpuTimer.c
在main程序开始有简短的介绍,包括所有的设定、所需的硬件。
4 安装调试程序所需的硬件
安装源文件中指出需备的硬件。DSP281xCPU-Timer 例程只需要硬件处于““Boot to H0”方式。其他的例程可能需要额外的硬件配置,如将模式配置引脚短接或接高、接地。
表3列出引导模式的设置,便于参考。对于使用F2812 eZdsp的用户而言,可以选择相应的跳线来选择引到模式。关于‘281x引导模式更详细的信息可以参看TMS320F28x Boot ROM Reference Guide (SPRU095).、
5 装载代码
硬件安装配置完成后,从CCS的GEL下拉菜单选择
DSP281x CpuTimerExample-> Load_Code
将.out文件下载到28器件内,在观察窗输入感兴趣的变量,复位然后执行代码到主程序开始的地方。每次当器件复位时,GEL文件会重新装载输出文件。如果不想这样,可以把GEL删掉,只要选择GEL文件,点击右键选择remove即可。
6 执行程序,在观察窗增加变量,检查内存内容
7 试验、修改、重新构建例程
当打算对例程进行一些修改时,最好拷贝一份完整的程序来修改或者至少对原始文件作个备份。TI提供的新的例程是以这些基本文件为基础的。
3.2节和3.3节对程序结构和流程有更详细的描述。
8从CCS中移除GEL文件或工程项目文件。
移除GEL文件,只要选中文件名点击右键选择remove即可。
例程中使用了the DSP281x_headers 目录中的头文件和DSP281x_common目录中的共享文件。只是example目录下的文件针对不同的例子程序也就不尽相同。
注意:多数的例程都使用位域的方法来访问寄存器。这样有利于更好的帮助使用如何去使用外设及器件。使用位域方法编程使得繁冗的代码易读易于修改。与.all方法比较只不过会增加些代码量。注意SPRC097文件中的例程文件关掉了编译优化器,如果需要可以重新设定编译环境,打开编译优化器。
3.2 例程结构
每个例程都有非常简单的结构。其中包括独立的原代码、共享原代码、头文件和连接命令文件。
3.2.1包含文件
所有的例程#include以下2个头文件。
DSP281x_Device.h
这个文件位于DSP281x_headers\include目录下。
它需要使用DSP281x的外设头文件。这个文件包含所需的外设头文件和器件的宏与类型定义。
DSP281x_Examples.h
此文件定义了例程所需的
。它不需要使用DSP281X的头文件,但是某些通用源代码要使用。这个文件在DSP281x_common\include目录下。
3.2.2 源代码
每个例程由相对独立的原代码组成,这个代码可以是通用的,也可以是共享的。
DSP281x_GlobalVariableDefs.c
使用DSP281x外设头文件的任何一个工程都必须包含这个源文件。在这个文件中,声明了外设寄存器的结构变量和数据段的分配。这个文件位于DSP281x_headers\source目录下。
详细例程代码
对某个具体的示例,这个文件是是特殊的,它的文件名有前缀Example_281x。Example_281xCpuTimer.c就是示例CPU Timer的具体文件,其它的例子中不使用这个文件。此文件位于DSP281x_examples\
目录下
通用源代码
剩下的源代码文件在示例程序中是共享的。这些文件包含外设通用函数或可利用的实用程序。共享源文件在DSP2812x_shared\source目录下。用户可以在原有工程文件或新的工程文件中选择、合并一些或全部共享源文件。
3.2.3 连接命令文件
每一个示例都使用两个连接命令文件。这些文件详细的说明了代码和程序段的存储位置。一个连接文件用来将编译产生的段分配到片上存储区,另一个用来分配使用DSP281x外设头文件编程所需的外设寄存器结构体的数据段。
存储区连接分配:
连接文件如表4所示,它用来分配片上存储段。这些连接文件在DSP281x_common\cmd目录下。每一个实例将选择以下文件中的一个,具体选择那一个由示例中的存储器决定。
表4 存储连接命令文件
存储连接命令文件示例
目录
描述
F2812_EzDSP_RAM_ink.cmd
DSP281x_common\cmd
EZdsp存储图只分配了SARAM的位置,无Flash,OTP或CSM密码保护位置
F2810.cmd
DSP281x_common\cmd
F2810存储连接命令文件,包含所有的Flash,OTP和CSM密码保护存储位置
F2812.cmd
DSP281x_common\cmd
F2812存储连接命令文件,包含所有的Flash,OTP和CSM密码保护存储位置
F2812_Xintfroot.cmd
DSP281x_common\cmd
来自F812 XINTF zone 7 的boot
DSP头文件结构数据段分配:
任何一个使用DSP281x头文件外设结构的工程必须包含一个连接命令文件,这个连接命令文件将外设寄存器结构数据段分配到正确的存储位置。
在v.058的头文件中,位置分配是包含在存储连接文件中的。为了容许将头文件从源代码中分离出来,分配文件被分成一个单独的文件,如表5所示。
表5 DSP281x外设头连接命令文件
DSP281x外设头连接命令文件
目录
描述
DSP281x_Headers_BIOS.cmd
DSP281x_Headers\cmd
Link.cmd分配BIOS工程中的头文件变量。这个文件必须包含在任意一个使用头文件的BIOS的工程中,详见4.2
DSP281x_Headers_nonBIOS.cmd
DSP281x_Headers\cmd
Link.cmd分配BIOS工程中的头文件变量。这个文件必须包含在任意一个使用头文件的nonBIOS的工程中,详见4.2
3.3 示例程序流程
在配置281x器件时,所有的示例程序都和以下推荐的流程相似。
表1反应了大致的流程:
3.4 DSP281x C/C++头文件和外设例程程序包所包含的例程
表6 包含的示例
示例
描述
adc_seqmode_test
ADC Seq 方式检测.通道A0连续转换,记录在存储器中
adc_seq_ovd_tests
使用排序ADC检测,超过芯片的C版本相应的特性。
adc_soc
使用ADCINA3和ADCINA2两通道做ADC转换。中断使能,使用SEQ1,EVA配置产生一个周期的ADC SOC。
cpu_timer
配置cpu timer0,在每次ISR中断服务程序里工作累加计数一次。
ecan_back2back
eCAN自检测模式例程。在高速的时候,用eCAN连续的传送数据
ev_pwm
事件管理器PWM示例。本程序使用EV 定时器产生PWM波形。可以使用示波器来观测这个波形。
ev_timer_period
事件管理器定时器示例。本程序使用EVA和EVB定时器,在一个周期溢出的时候,触发中断。每次中断服务程序中累加计数。
flash
将EV定时器例程从SARAM移到Flash。其中包含将程序从SARAM拷贝到Flash的相关步骤。为了更快的执行,也将部分中断服务程序从Flash复制到SARAM
gpio_ loopback
通用IO口回送检测。本程序中,将8位的GPIO口配置为输出,8位口配置为输入。配置为输出的管脚和输出的管脚形成一个闭环。输出数据从输入管脚中读回。
gpio_ toggle
使用DATA,SET/CLEAR和TOGGLE寄存器等不同的方法切换所有的IO管脚。可以使用示波器观测这些管脚
mcbsp_loopback
配置McBSP做为回送检测。使用查询来代替中断
mcbsp_loopback_interrupts
配置McBSP做为回送检测。使用中断和先进先出寄存器。
run_from_xintf
本示例说明使用F2812eZdsp开发板如何从XINTF zone 7导入和配置XINTF存储器接口
sci_autobaud
外部连接SCI-A和SCI-B,在两个外设之间传送数据。使用SCI的自动波特特性。在不同的波特率下做重复测试
sci_loopback
SCI示例代码,使用SCI模块的回送测试模式传送数据。本程序使用位查询,而不是中断。
sci_loopback_ interrupts
SCI示例代码,使用内部回送测试模式,通过SCI-A传送数据。同时使用中断方法和先进先出寄存器。
spi_loopback
SPI示例,使用外部回送检测模式传送数据
spi_loopback_interrupts
SPI示例,使用外部回送检测模式传送数据。同时使用中断方法和先进先出寄存器。
sw_prioritized_interrupts
在大多数应用中,可以使用标准中断硬件优先级。本示例说明了如果有需要,可以使用一种中断软件优先级的方法,
watchdog
说明喂狗和间接喂狗触发中断
3.5从Flash执行的例程
大部分DSP281x示例属于“H0引导”模式,都是从SARAM开始执行的。下面的示例(DSP281x_example\Flash)在“flash引导”模式下,程序将从Flash开始执行。这个示例是事件管理定时器的例子,通过以下的改变使它从Flash开始执行。
1. 改变连接命令文件连接flash
从工程文件夹中将F2812_281x_EzDSP_RAM_lnk.cmd移去,添加F2812.cmd或F2810.cmd。F2812.cmd和 F2810.cmd在DSP281x_common\cmd目录下。
2.添加DSP281x_common\source\DSP281x_CSMPasswords.asm到工程中。这个文件含有密码,此密码将被编程,放在CSM密码位置。建议在开发阶段将此密码设为0xFFFF,这样器件可以很容易打开。详细的信息可以参考TMS320F28x System control 和Interrupts Reference Guide(SPRU078).
3.修改代码,拷贝那些从Flash的导入地址到它们在SARAM中的运行地址过程中必须在SARAM中运行的函数。
特别的,flash等待状态初始化程序必须在SARAM外执行。在DSP281x的例程中,那些从SARAM执行的函数,通过下面所示的编译 CODE_SECTION #pragma声明,已经被分配在ramfuns区段中。
然后,寄存器连接命令文件(如下所示)在ramfuns段中分配flash导入地址和 SARAM的运行地址。
象上面的详细说明一样,连接器将特殊符号分配到固定的地址,如下:
使用包含示例MemCopy程序或c库的标准mencopy()功能,这些符号能被用来从Flash到SARM拷贝函数.
执行从flash到SARAM的拷贝功能,需包含示例MemCopy函数:
a. 添加DSP281x_common\source\DSP281x_MemCopy到工程项目中
b. 添加如下的函数原型到示例源文件中。在DSP281x_Examples.h已经包含了。
c. 添加以下的变量声明到源代码中,使编译器知道这些代码已经存在。连接命令文件为每一个变量分配地址,如下所示,对DSP281x例程,这些已经在DSP281x_examples.h中完成。
d.对每一个需要从flash拷贝到SARAM的区,修改代码调用MemCopy函数即可。
4. 修改代码,调用flash初始化程序:
这个功能将设置flash的等待状态,使能Flash流水线模式
5.“Flash引导”模式所需的跳接。
引导模式的需要的跳接方式如下:
表7 281x导入模式设立
注意:x=任意
对那些使用F2812 eZdsp开发板的用户,可以参考eZdsp’s user’s guide来选择导入模式的相应的跳线接法。
如果想获得更详细的信息,可以参考“281x boot modes refer to the TMS320F28x Boot ROM Reference Guide(SPRU095)”
6.烧写编译后的程序
可以使用Specturm digital’s 站点的SDFlash工具。
www.specturmdigital.com
7. 在ccs中调试、下载工程,只选择File->Load Symbols .
在调试的工作环境下,当调试者不能或不需要下载目标代码时,比如代码在ROM或flash中是,只下载符号信息是十分有用的.这中工作方式从指定的文件中下载符号信息.
4 逐步使用头文件和范例代码
按下面步骤将外围头文件和范例代码加入到自己的工程中。
4.1 准备
在开始将头文件和范例代码加到自己工程文件前,建议按以下几个步骤做好准备:
1. 按步装载一个范例工程
按步装载一个范例工程,以便熟悉头文件和范例代码。这一点在第3章节已有描述。
2. 为将要使用的源文件拷贝一个副本
-DSP281x_headers: 合并头文件到新工程文件所需的代码。
-DSP281x_common: 用在范例工程文件的一些共享源代码
-DSP281x_examples:基于头文件和共享代码的范例工程文件
4.2 包含DSP281X外设头文件
将DSP281x头文件加入到工程中后,就可以在代码中采用位域结构的方法对DSP的外设进行访问。
在新的或原有的工程文件中添加头文件需执行以下步骤:
3. 将“DSP281x_DEVICE.h”这个文件加入到你的源文件中
这个包含文件将依次包含所有的外设特定的头文件,还有一些采用位域结构的方法对DSP的外围设备中某些位的定义。
4. 编辑DSP281x_Device.h文件和选择你正在创建的对象。
在下面这个范例中,文件配置用来对F2812设备进行选择:
5. 把DSP281x_GlobalVariableDefs.c源文件加到工程中
此文件在DSP281x_headers\source\目录下,该文件包含:
—访问外设寄存器的变量的声明
-数据段#pragma的分配,连接器用它将变量分配到存储器中合适的位置
6.把合适的DSP281x的连接命令文件加到工程中
如2.2节描述,当使用DSP281x头文件方法,外设寄存器的数据段是通过连接器将变量分配到存储器中合适的位置。
为了完成你的工程中的对存储器空间的分配,下面其中的一个连接文件必须包含在你的工程中,它们位于DSP281x_headers\cmd\目录下
—对于非DSP/BIOS工程: DSP281x_nonBIOS.cmd
—对于DSP/BIOS工程: DSP281x_Headers_BIOS.cmd
添加连接文件到工程文件的方法取决于于所使用的Code Composer Studio的版本
Code Composer Studio V2.2版本及其以上版本:
对于CCS2.2,它允许工程文件中包含多个连接命令文件。
可将合适的头连接命令文件(BIOS和非 BIOS)直接添加工程中
Code Composer Studio V2.2以上版本
对于低于CCS2.2的版本,每个工程只能包含一个主要的连接命令文件。然而,如果需要,这个文件在需要时可称为additional.cmd。对DSP281x头文件,要包含所需的存储器分配,可按照下面两个步骤:
1) 更新工程的主要连接命令文件,用-I项调用已提供的DSP281x外设结构连接命令文件
2) 添加DSP281x外围连接器命令文件(.cmd)的目录路径到当前的工程中
a. 打开菜单:Project->Build Options
b. 选择Linker项,再选择Basic项
c. 在Library Search Path里将目录路径DSP281x_headers\cmd添加到你的系统中。
7.把DSP281x头文件目录路径添加到当前的工程中
确定头文件所在的目录的位置:
a. 打开菜单:Project->Build Options
b. 选择Compiler项
c. 选择pre-processor
d. 在Include Search Path里将目录路径DSP281x_headers\include添加到你的系统中
8.其他附加的build项
下面是一些附加的compiler和linker项,这些选项可通过Project->Build Options菜单进行设置。
-Compiler项
-ml 高级选择和检测
用于大存储器模式。在28x设备4M存储器空间可对数据段任何位置进行设定。
-pdr 诊断选择和检测
产生非严重性警号。编译器会产生一个警告,表明代码虽然是有效的但是可疑。在许
情况下,这些警告是使能-pdr项产生的,它提醒你代码可能会在以后引起问题。
-Linker项:
-w 高级选项和检测
对输出段的警告。这个选项将提醒你在代码中存在未分配的存储器空间。在缺省值情况,连接器会尝试对未分配的代码和数据段提供一个有效的存储器地址,而不会产生警号。但是,当这个段被分配到一个意外的地址时,可能会引起问题。
4.3 包含的通用范例代码
把通用范例代码包含在你的项目,这样可以大大影响已经为某型号芯片写好的代码。合并共享源代码到一个新的或已存在的工程文件中,可以按以下几个步骤:
1.#include”DSP281x_Examples.h”到当前的源文件中。
这个包含文件将包含范例代码中的一些通用的定义和声明。
2.将范例的包含文件的目录路径添加到你的工程中
a. 打开菜单:Project->Build Options
b. 选择Compiler项
c.选择pre-processor
d. 在Include Search Path里将目录路径DSP281x_common/include添加你的系统中
在目录之间使用分号
例如添加下面的包含文件目录路径到工程中:
..\..\DSP281x_headers\include;..\..\DSP281x_common\include
3.添加连接命令文件到当前工程中
在DSP281x_common\cmd目录下提供了下面几个存储器连接文件(.cmd),其中大多数范例使用了F2812_ExDSP_RAM_Ink.cmd文件。
表8.包含主要的连接命令文件
主要连接命令文件例子
描述
F2812_EzDSP_RAM_lnk.cmd
主要eZdsp范例连接文件。仅用在SARAM空间,它不受代码安全模式的保护。这个存储器映射文件用于F2812EzDSP的所有范例,不使用Flash或OTP存储器地址
F2812_XintfBoot.cmd
用于从XINTF Zone 7启动的连接命令文件
F2810.cmd
主要F2810连接命令文件,包含所有的Flash和OTP存储器
F2812.cmd
主要F2812连接命令文件,包含所有的Flash,OTP和XINTF存储器
4. 设定CPU频率
在DSP281x_common\include\DSP281x_Examples.h文件中指定了合适CPU频率。在这个文件中包含一些范例。
5.添加需要的通用源文件到工程中
通用的源文件可以在DSP281x_common\source\directory中找到。
6.包含.c文件用于外围中断扩展(PIE)
因为所有的281x的应用程序都用到的PIE中断模块,你可以添加PIE的 support.c文件帮助初始化PIE。设定好的壳ISR函数就可直接使用,或者使用自己的函数来重映射提供好的PIE向量表。这些文件的列表可以在7.2.1 节中找到。
5 DSP281x C/C++头文件和外设例程程序包所包含的内容
这部分将列出此版本中包含的所有文件。
5.1 头文件-DSP281x_header
DSP281x_header在\DSP281x_header\目录下
5.1.1 DSP281x头文件-主文件
以下这些文件必须添加到任何一个使用DSP281x头文件的工程中。参考4.2节的相关信息将头文件合并到一个新的或原有工程文件中。
表11 DSP281x头文件-主文件
文件
位置
描述
DSP281x_Device.h
DSP281x_Headers\include
主包含文件。在任何一个.c原文件中都包含此文件。这个文件依次包含下面列出的所有特定外设.h文件。另外,这个文件还包含类型(typedef)声明和通用的掩码值。参考4.2节。
DSP281x_GlobalVariableDefs.c
DSP281x_Headers\source
定义了一些访问外设结构的变量和数据区#pragma分配声明。任何一个使用头文件的工程都必须包含这个文件。参考4.2。
DSP281x_Headers_BIOS.cmd
DSP281x_Headers\cmd
连接.cmd文件,在使用BIOS的工程文件中分配头文件变量。 任何一个使用头文件的BIOS工程都必须包含这个文件。参考4.2。
DSP281x_ Headers_nonBIOS.cmd
DSP281x_Headers\cmd
连接.cmd文件,在non-BIOS工程中分配头文件变量. 任何一个使用头文件的non-BIOS工程都必须包含这个文件。参考4.2。
5.1.2 DSP281x头文件-外设位-域和寄存器结构定义文件
以下的文件定义281x器件每个外设位-域和寄存器结构。通过包含DSP281x_Device.h,这些文件自动的包含在工程文件中。参考4.2节的相关信息将头文件合并到一个新的或原有的工程文件中。
表12 DSP281x头文件位-域和寄存器结构定义文件
文件
位置
描述
DSP281x_Adc.h
DSP281x_Headers\include
ADC寄存器结构和位-域定义
DSP281x_CpuTimer.h
DSP281x_Headers\include
Cpu-Timer寄存器结构和位-域定义
DSP281x_DevEmu.h
DSP281x_Headers\include
仿真寄存器定义
DSP281x_ECan.h
DSP281x_Headers\include
eCAN寄存器结构和位-域定义
DSP281x_Ev.h
DSP281x_Headers\include
EV寄存器结构和位-域定义
DSP281x_Gpio.h
DSP281x_Headers\include
GPIO寄存器结构和位-域定义
DSP281x_Mcbsp.h
DSP281x_Headers\include
McBSP寄存器结构和位-域定义
DSP281x_PieCtrl.h
DSP281x_Headers\include
PIE寄存器结构和位-域定义
DSP281x_PieVect.h
DSP281x_Headers\include
完整PIE向量表定义
DSP281x_Sci.h
DSP281x_Headers\include
SCI寄存器结构和位-域定义
DSP281x_Spi.h
DSP281x_Headers\include
SPI寄存器结构和位-域定义
DSP281x_SysCtrl.h
DSP281x_Headers\include
系统寄存器结构,包含Watchdog,
PLL,CMS,Flash/OTP,Clock寄存器
DSP281x_Xintf.h
DSP281x_Headers\include
扩展存储器接口XINTF寄存器结构和位-域定义
DSP281x_Xintrupt.h
DSP281x_Headers\include
外部中断寄存器结构和位-域定义
5.1.3 Code Composer .gel文件
使用带DSP281x 头文件的外设寄存器结构, 包含以下的Code Composer Studio .gel文件
表13 包含的GEL文件
文件
位置
描述
DSP281x_Peripheral.gel
DSP281x_Headers\gel
提供一个GEL下拉菜单,将DSP281x数据结构下载到观察窗口。将GEL_LoadGel(“ DSP281x_Peripheral.h)函数添加到标准的F2812.gel中,CCS将可以自动的下载这个文件
DSP281x_GpioQuickRef.gel
DSP281x_Headers\gel
为DSP281x器件上的GPIO口提供一个快速的参考。能将MUX信息输出到调试窗口
5.1.4 变量名和数据段
本节列出了DSP281x_headers\source\DSP281x_ GlobalVariableDefs.c文件中使用的变量名和分配的数据段。
5.2通用例程代码- DSP281x_common
5.2.1 外设中断扩展(PIE)块support
DSP281x_PieCtrl.h除了说明寄存器的定义外,还为PIE块提供基本的ISR结构。这些文件是:
表14 基本PIE块特殊支持文件
文件
位置
描述
DSP281x_Defaultlsr.c
DSP281x_common\source
完整PIE向量表的中断服务外壳程序(ISRs)。可以选择填充一个函数或将你的ISR重新映射到PIE向量表。注意:这个文件对DSP\BIOS 工程文件没有用。
DSP281x_Defaultlsr.h
DSP281x_common\include
DSP281x_Defaultlsr.c中的ISR函数原型声明。注意: 这个文件对DSP\BIOS 工程文件没有用
DSP281x_PieVect.c
DSP281x_common\source
此处是DSP281x_Defaultlsr.c中ISR函数的一个实例,创建一个带指针的PIE向量表结构初始化。为了初始化到默认的ISR位置,可以拷贝这个实例到PIE向量表。
另外,以下包含的文件是为了中断的软件优先级。这些文件被用来代替上面那些需要使用的额外软件中断优先级文件。更多的信息可以参考示例和文件DSP281x_example\sw_prioritized_interrupts
表15 中断PIE软件优先级特别支持文件
文件
位置
描述
DSP281x_SWPrioritizedDefaultlsr.c
DSP281x_common\source
默认的中断服务外壳程序。 你可以选择填充一个函数或将你的ISR重新映射到PIE向量表。注意:这个文件对DSP\BIOS 工程没有用。
DSP281x_SWPrioritizedLevel.h
DSP281x_common\include
DSP281x_Defaultlsr.c中的ISR函数原型声明。注意: 这个文件对DSP\BIOS 工程没有用。
DSP281x_SWPrioritizedPieVect.c
DSP281x_common\source
DSP281x_Defaultlsr.c中创建带指向ISR函数指针的PIE向量表初始化。为了初始化到默认的ISR位置,这个示例能够被拷贝到PIE向量表。
5.2.2外设特定文件
几个外设特定初始化程序和支持函数包含在DSP281x_common\src\目录下的外设.c源文件中。这些文件有:
表16 包含的外设详细文件
文件
描述
DSP281x_GlobalPrototypes.h
这个文件包含外设详细的函数原型
DSP281x_Adc.c
ADC具体函数和宏
DSP281x_CpuTimers.c
CPU-Timer具体函数和宏
DSP281x_Ecan.c
增强CAN详细函数和宏
DSP281x_Ev.c
EV详细函数和宏
DSP281x_Gpio.c
GPIO详细函数和宏
DSP281x_Mcbsp.c
McBSP详细函数和宏
DSP281x_PieCtrl.c
PIE控制详细函数和宏
DSP281x_Sci.c
SCI详细函数和宏
DSP281x_Spi.c
SPI详细函数和宏
DSP281x_SysCtrl.c
系统控制(看门够,时钟,pll等) 详细函数和宏
DSP281x_Xintf.c
XINTF详细函数和宏
DSP281x_Xintrupt.c
外部中断详细函数和宏
注意:这些的程序是处于研发过程中,有可能对这个版本不是都适用的。随着更多的例子应用,它们将会被添加和分布在其中。
5.2.3实用源程序
表16 包含的实用原程序文件
文件
描述
DSP281x_CodeStartBranch.asm
当代码导入Flash,OTP或H0 SARAM存储器时,此程序确定代码从哪个分支开始执行。在使用包含的c 初始程序之前,需要关闭看门狗。
若程序从xintf zone 7引导执行,择使用DSP281x_XintfBootReset.asm替代。
DSP281x_XintfBootReset.asm
这个文件说明程序从xintf zone 7引导。 在使用包含的c 初始程序之前,需要关闭看门狗。如果代码导入Flash,OTP或H0 SARAM存储器时,使用DSP281x_CodeStartBranch.asm代替它。
DSP281x_DBGIER.asm
汇编函数控制来自C的DEBIER寄存器
DSP281x_usDelay.asm
在微秒内插入一个延时的汇编函数。这个函数是依赖时钟周期的,它必须从具有0 等待-状态的 RAM执行。
DSP281x_CSMPasswords.asm
包含在工程中,编译代码安全模式密码和保留位置。
5.2.4 示例连接.cmd文件
示例存储器连接命令文件,在DSP281x_common\cmd目录下。对开始使用281x器件的用户来说,建议使用基本的F2812_EzDSP_RAM_lnk.cmd
表18 包含的主连接命令文件
主连接命令文件示例
描述
F2812_EzDSP_RAM_lnk.cmd
EZDSP存储器连接示例。只分配在SARAM。这个存储映射图适用于所有的F2812 EzDSP运行的程序。不使用Flash,OTP或CSM密码保护位置
F2810.cmd
F2810存储连接命令文件。包含Flash,OTP或CSM密码保护位置。
F2812.cmd
F2812存储连接命令文件。包含Flash,OTP或CSM密码保护位置。
F2812_XintfBoot.cmd
F2812存储连接命令文件举例说明从XINTF Zone 7导入。
6 编程应用中需注意的问题
6.1 读-修改-写(read-modify-write)指令的影响
当写任何代码时,不管是用c还是汇编,紧记读-修改-写指令的影响。
‘28x dsp每次对寄存器或存储器写操作是16为或32位的。任何指令看上去都是写单独的一位,但是实际上进行了以下操作:先读寄存器,修改单独某一位,再写回结果。这就是读-修改-写指令。对大多数寄存器,这种工作方式不会引起问题。下面的除外:
6.1.1 有多个标志位,且都是写1清标志位的寄存器
例如PIEASK寄存器,写1清标志位。如果要设置多个标志位,对寄存器执行读-修改-写操作,有可能会清掉我们不想清除的标志位。
下面的解决方法是错误的。它写1时对每一位置位,因此,清除了所有的标志位。
正确的做法是只对那些需要写1的寄存器写一个掩码值
6.1.2 有可更改(volatile)位的寄存器
一些寄存器有些可更改的位,可以通过外部硬件来修改。
以PIEIFRx寄存器为例。原子操作读-修改-写指令将读16位的寄存器,修改它的值,将其写回。在这种工作方式中的修改操作期间,由于外设硬件事件的触发,PIEIFRx寄存器中的一位可能会改变,因此,在写的过程中,这个值有可能会被破坏。
规定在运行时候寄存器的这种特性不能被修改。让cpu进入中断,清IFR标志。
6.2 常遇问题及解答
1) “EALLOW”和“EDIS”。
EALLOW:为了集合指令EALLOW,在DSP281x_Device.h中的宏定义,同理定义EDIS。这就是EALLOW,它和嵌入集合指令asm(“EALLOW”)是一样的。
28x系列芯片的几个控制寄存器受EALLOW的保护机制保护,防止cpu的非法写入。状态寄存器1中的EALLOW位说明保护是使能还是禁止。当置保护位时,所有的cpu写寄存器操作被忽略了,cpu只能读,JATG可以读和写。通过执行EALLOW指令,将其置位的话,cpu就可以自由的写被保护的寄存器了。在修改寄存器后,通过执行EDIS指令清EALLOW位,这些寄存器将再次被保护。
想要得到完整的被保护寄存器信息,可以参考TMS320F28x System control 和Interrupts Reference Guide(SPRU078)
2)外设寄存器读回0x0000,而且不能写?
外设寄存器不能修改或读取,除非是指定的外设时钟使能。在DSP281x_commom\source目录下的函数InitPerpheralClocks()给出了一个使能外设时钟的例子。
3)存贮区L0,L1读回的全都是0x0000?
这种情况最大的可能就是代码安全模式被锁住,因此保护的存贮位址读回的都是0x0000。更多的代码安全模式信息,参考TMS320F28x System control 和Interrupts Reference Guide(SPRU078)
4)代码不能写进L0或L1存储块
这种情况最大的可能就是代码安全模式被锁住,因此保护的存贮位置读回的都是0x0000。当CSM锁上时,从外部保护执行的代码是不能读或写入保护存贮区中的。更多的代码安全模式信息,参考TMS320F28x System control 和Interrupts Reference Guide(SPRU078)
5)一个外设寄存器可以读回,但是不能写入
EALLOW位保护了一些寄存器被cpu非法访问。如果你的程序看起来好象不能