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控制很简单,说白了就是三步:

  1. 使能GPIO时钟
  2. 配置GPIO方向(输入/输出)
  3. 写数据寄存器控制电平

下面是一个完整的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 文件。

接下来连接仿真器:

  1. 用USB线连接仿真器和电脑
  2. 用JTAG线连接仿真器和开发板
  3. 给开发板上电
  4. 点击CCS工具栏上的 Debug 按钮(绿色小虫子图标)

CCS会自动连接目标板,下载程序,并停在 main() 函数的入口处。这时候:

  • 点击 Resume (F8) —— 程序全速运行,LED应该开始闪烁
  • 点击 Suspend —— 暂停程序,查看变量和寄存器状态
  • 点击 Terminate —— 断开调试会话

常见问题:如果点击Debug后提示 Error connecting to the target,先检查这几项:

  • 仿真器驱动是否安装?
  • 开发板是否上电?
  • CCS的Target Configuration里选的芯片型号和仿真器类型是否正确?
  • JTAG线是否插反?(别笑,我干过这事)

2.5 本章知识体系总览

下面这张图把本章的核心流程串起来了,你可以对照着回顾一下:

DSP基础工程创建流程 DSP基础工程创建流程 1. 新建CCS工程 选择芯片/仿真器/模板 2. 配置编译器选项 优化/调试/浮点支持 3. 配置链接器 栈/堆/输出格式 4. 编写LED闪烁程序 GPIO初始化 + 主循环 5. 编译 (Ctrl+B) 生成 .out 文件 6. 下载 & 调试 连接仿真器 → 运行 ✅ LED闪烁成功 💡 关键检查点 • 芯片型号与开发板一致 • 仿真器驱动安装正确 • GPIO配置时记得加 EALLOW/EDIS

看到LED闪烁的那一刻,说实话,还是挺有成就感的。虽然只是个简单的灯,但背后涉及了工程创建、编译器配置、链接脚本理解、GPIO操作、调试器使用等多个环节。这些基础打牢了,后面做PWM、ADC、串口通信才会顺手。

本章小结:

  • 新建CCS工程时,务必选对芯片型号和仿真器类型
  • 编译器选项在调试阶段关优化、开完整调试符号
  • 链接器选项注意栈大小,默认值偏小
  • GPIO操作三步走:时钟使能 → 方向配置 → 数据读写
  • EALLOW/EDIS是TI DSP的保护机制,不能忘