2. DSP基础工程创建:新建CCS工程、配置编译器与链接器选项、编写第一个LED闪烁程序并下载运行
说实话,很多初学者一上来就急着写代码,结果连工程是怎么搭起来的都没搞明白。我见过不少同事,代码写得挺溜,但换个芯片型号就不知道怎么配工程了。这一章,咱们就从零开始,把CCS工程创建、编译器配置、链接脚本调整,再到LED闪烁程序下载运行,整个流程走一遍。
你想想看,DSP开发跟单片机开发最大的区别在哪?就是它的内存模型和启动流程更复杂。如果工程配置不对,代码根本跑不起来,甚至连仿真器都连不上。所以,别嫌这一步啰嗦,打好基础后面才顺。
本章核心目标:掌握CCS工程的标准创建流程,理解编译器与链接器选项的作用,能够独立完成一个可运行的LED闪烁程序。
2.1 新建CCS工程——别急着点“Finish”
打开CCS,点击 File → New → CCS Project。这里有几个关键选项,我一个个说。
| 配置项 | 推荐设置 | 说明 |
|---|---|---|
| Target | TMS320F28335(或其他具体型号) | 必须与开发板一致,选错会导致无法连接 |
| Connection | Texas Instruments XDS100v2 USB Emulator | 根据仿真器类型选择,常用XDS100或XDS200 |
| Project name | led_blink | 建议用英文,不要带空格和特殊字符 |
| Output type | Executable | 生成可执行文件(.out) |
| Project templates and examples | Empty Project (with .cmd file) | 选择带链接脚本的空工程,省去手写cmd的麻烦 |
嗯,这里要注意:不要选“Empty Project”而不带.cmd文件。我曾经有个学生,选了空工程后自己写链接脚本,结果段地址配错了,程序下载进去直接跑飞,查了两天才找到问题。所以,新手阶段就选带cmd模板的,省心。
点击 Finish 后,CCS会自动生成工程结构。你会看到这么几个文件:
- main.c —— 主程序文件,代码写在这里
- F28335.cmd —— 链接命令文件,定义内存映射和段分配
- DSP2833x_Headers_nonBIOS.cmd —— 外设寄存器地址映射文件
小技巧:我个人习惯在工程根目录下建一个 source 文件夹,把.c文件放进去,include 文件夹放头文件。这样工程结构清晰,多人协作时不容易乱。
2.2 配置编译器与链接器选项——别用默认值
很多人建完工程就直接写代码,编译报错才回头找配置。其实,提前配好编译器选项能省很多事。
右键工程 → Properties → Build → C2000 Compiler,重点看这几个:
| 选项路径 | 推荐值 | 为什么这么配 |
|---|---|---|
| Include Options (-i) | 添加DSP2833x头文件路径 | 否则编译会报“找不到头文件” |
| Optimization Level (-O) | 0(调试阶段) | 优化级别高了,单步调试时变量值可能看不到 |
| Debugging Model | Full Symbolic Debug (-g) | 生成完整的调试符号信息 |
| Specify floating point support | --float_support=fpu32 | F28335有硬件浮点单元,不开就浪费了 |
再切换到 C2000 Linker 选项卡:
- Stack Size (-stack):建议设为 0x400(1KB),默认0x200有时不够用
- Heap Size (-heap):如果不用malloc,保持默认0x200就行
- Output Format:选
eabi(新标准),别选老的coff
避坑指南:我曾经在项目里遇到一个诡异的问题——程序跑着跑着就复位了。查了两天,最后发现是栈溢出。默认栈大小只有512字节,我那个程序里有个递归函数,栈直接撑爆了。所以,调试阶段把栈设大一点,没坏处。
2.3 编写第一个LED闪烁程序——让灯亮起来
配置搞定了,接下来写代码。F28335的GPIO控制很简单,说白了就是三步:
- 使能GPIO时钟
- 配置GPIO方向(输入/输出)
- 写数据寄存器控制电平
下面是一个完整的LED闪烁程序,我加了详细的注释:
#include "DSP2833x_Device.h" // DSP2833x 设备头文件
#include "DSP2833x_Examples.h" // 例程常用函数
// 假设LED接在GPIO0,低电平点亮
#define LED_GPIO 0
void delay_loop(Uint16 count)
{
Uint16 i;
for(i = 0; i < count; i++);
}
void main(void)
{
// 1. 初始化系统控制、PLL、看门狗、外设时钟
InitSysCtrl();
// 2. 禁止全局中断(调试阶段先关掉)
DINT;
// 3. 初始化GPIO
EALLOW; // 允许写保护寄存器
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0 设为普通IO
GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; // GPIO0 设为输出
EDIS; // 禁止写保护寄存器
// 4. 主循环
while(1)
{
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; // 输出低电平,LED亮
delay_loop(2000);
GpioDataRegs.GPASET.bit.GPIO0 = 1; // 输出高电平,LED灭
delay_loop(2000);
}
}
这里有个细节:EALLOW和EDIS 是TI DSP特有的保护机制。有些寄存器在正常运行时不希望被意外修改,所以加了写保护。操作这些寄存器前必须执行 EALLOW,操作完马上 EDIS。我见过有人忘了加EALLOW,结果GPIO死活配不成功,折腾了半天。
个人经验:delay_loop里的计数值2000是拍脑袋写的。实际延时时间取决于CPU主频。F28335默认主频150MHz,2000次循环大概延时几十微秒。如果想精确延时,建议用CPU定时器,后面章节会讲。
2.4 编译、下载与运行——看到灯闪的那一刻
代码写完了,按 Ctrl+B 编译。如果没报错,控制台会显示 Build Finished,并生成 led_blink.out 文件。
接下来连接仿真器:
- 用USB线连接仿真器和电脑
- 用JTAG线连接仿真器和开发板
- 给开发板上电
- 点击CCS工具栏上的 Debug 按钮(绿色小虫子图标)
CCS会自动连接目标板,下载程序,并停在 main() 函数的入口处。这时候:
- 点击 Resume (F8) —— 程序全速运行,LED应该开始闪烁
- 点击 Suspend —— 暂停程序,查看变量和寄存器状态
- 点击 Terminate —— 断开调试会话
常见问题:如果点击Debug后提示 Error connecting to the target,先检查这几项:
- 仿真器驱动是否安装?
- 开发板是否上电?
- CCS的Target Configuration里选的芯片型号和仿真器类型是否正确?
- JTAG线是否插反?(别笑,我干过这事)
2.5 本章知识体系总览
下面这张图把本章的核心流程串起来了,你可以对照着回顾一下:
看到LED闪烁的那一刻,说实话,还是挺有成就感的。虽然只是个简单的灯,但背后涉及了工程创建、编译器配置、链接脚本理解、GPIO操作、调试器使用等多个环节。这些基础打牢了,后面做PWM、ADC、串口通信才会顺手。
本章小结:
- 新建CCS工程时,务必选对芯片型号和仿真器类型
- 编译器选项在调试阶段关优化、开完整调试符号
- 链接器选项注意栈大小,默认值偏小
- GPIO操作三步走:时钟使能 → 方向配置 → 数据读写
- EALLOW/EDIS是TI DSP的保护机制,不能忘