CC2640R2F 是SimpleLink系列中的一款强大 BLE 无线 MCU,集成了强大的 ARM Cortex-M3 应用处理器和专用的射频核心,非常适合开发高性能、低功耗的蓝牙应用。
一、开发准备
开发环境使用CCS,TI 官方对 CCS 的支持非常完善,推荐使用 CCS。
SimpleLink CC13x2/26x2 SDK是最重要的软件包。它包含了所有的驱动程序(Driver)、射频协议栈(BLE5 stack)、丰富的示例代码(Examples)、操作系统(TI-RTOS)和配置文件。
手机上下载一个 BLE 调试 App(如 nRF Connect 或 LightBlue),用于扫描和测试你的蓝牙设备。
SmartRF Flash Programmer 2:用于烧录程序到芯片中。
SysConfig:一个图形化配置工具,集成在 CCS 和 SDK 中,用于配置引脚、电源、射频参数等,极大简化了配置过程。
二、 软件架构
在开始编程前,理解 TI BLE 程序的架构至关重要。它采用分层设计:
应用层 (Application Layer):这是编写业务逻辑的地方,例如读取传感器数据、控制 LED、处理用户按键等。运行在 TI-RTOS 任务(Tasks)中。
协议栈 (BLE Stack):一个预编译的二进制库(libble.a),处理所有复杂的蓝牙协议,如广播、连接、安全管理、属性协议(ATT)等。应用层通过一组定义好的 API(在 icall.h 等头文件中)与协议栈进行交互。
蓝牙配置文件 (GATT Profile):这定义了设备的功能和数据类型。例如,心率 profile、电池服务等。使用属性表 (GATT Table) 来实现,表中包含了服务 (Services)、特征值 (Characteristics) 和描述符 (Descriptors)。可以使用 SysConfig 工具图形化地生成 GATT 表,而无需手动编写繁琐的 XML 或 C 代码。
硬件抽象层 (HAL/Driverlib):SDK 提供的驱动程序库,用于操作 GPIO、ADC、I2C、SPI、UART 等外设。
实时操作系统 (TI-RTOS):一个轻量级的实时操作系统,负责任务调度、内存管理、中断处理和同步(如信号量、事件、队列)。应用程序是建立在它之上的。
三、 开发
步骤 1:创建工程,使用 Project -> New CCS Project。选择目标器件 CC2640R2F。从修改示例工程开始。
步骤 2:使用 SysConfig 配置 GATT 服务,这是最关键的一步。我们将创建一个自定义服务来控制 LED。
在 CCS 中打开工程的 .syscfg 文件。找到 BLE Stack Configuration 部分。在 GATT Settings 中,点击 “+” 添加一个新服务。
Name: LED Service
UUID: 可以使用标准 UUID 或自定义一个 128-bit 的 UUID(例如 0xF0001111-0451-4000-B000-000000000000)。在新创建的服务下,添加一个特征值 (Characteristic):
Name: LED State
UUID: 自定义,如 0xF0001112-...
Properties: 选择 Read 和 Write(因为我们既要读取 LED 状态也要能写入控制)。
Variable Length: 否
Length: 1 (一个字节,0 关,1 开)
Read Authorization: None
Write Authorization: None
保存 .syscfg 文件。SysConfig 会自动在后台生成对应的 C 代码(在 syscfg 文件夹中),包括 GATT 表、属性句柄(handle)和函数声明。
步骤 3:编写应用层逻辑
在应用文件中(如 simple_peripheral.c)定义句柄:
// 这些句柄由 SysConfig 自动生成,在 ti_ble_config.h 中声明
extern uint16_t ledServiceHandle;
extern uint16_t ledStateCharHandle;
处理写操作(当手机App发送数据来控制LED时):
在 SimplePeripheral_processGattMsg 函数或类似的消息处理函数中,添加 case 语句来处理 GATT_WRITE_CMD 或 GATT_WRITE_REQ 事件。
#include "ti_ble_config.h" // 包含自动生成的句柄定义
static void SimplePeripheral_processGattMsg(appEvt_t *pMsg) {
switch (pMsg->hdr.event) {
case GATT_MSG_EVENT:
if (pMsg->msg.gattMsgEvent.opcode == GATT_WRITE_CMD ||
pMsg->msg.gattMsgEvent.opcode == GATT_WRITE_REQ) {
// 检查写入的是否是我们的 ‘LED State’ 特征值
if (pMsg->msg.gattMsgEvent.handle == ledStateCharHandle) {
uint8_t ledState = pMsg->msg.gattMsgEvent.pValue[0]; // 获取写入的值
// 控制开发板上的 LED,假设 LED1 连接到 GPIO pin 10
GPIO_write(IOID_10, ledState ? 1 : 0); // 1=ON, 0=OFF
// 更新本地的特征值,以便后续读取能返回正确状态
// Attr_SetAttribute(ledStateCharHandle, sizeof(ledState), &ledState);
// 如果需要,还可以发送通知确认(如果是WRITE_REQ)
// GATT_WriteRsp(connHandle, pMsg->msg.gattMsgEvent.opcode);
}
}
break;
}
}
处理读操作(当手机App读取LED状态时):通常协议栈会自动处理读操作,返回属性表中存储的值。如果你在代码中动态改变了 ledState 变量的值,你需要使用 Attr_SetAttribute 函数来更新属性表中的值,如上例注释所示。
步骤 4:初始化外设
在 main() 函数或应用初始化函数中,初始化 GPIO:
#include <ti/drivers/GPIO.h>
#include "ti_drivers_config.h" // 由 SysConfig 生成的板级配置
// 初始化 GPIO
GPIO_init();
// 将 LED 引脚配置为输出
GPIO_setConfig(IOID_10, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
步骤 5:编译、下载和调试
点击 CCS 的 Build 按钮编译工程。将开发板连接至 PC。点击 Debug 按钮将程序下载到开发板并启动调试会话。运行程序。
步骤 6:测试
打开手机上的 nRF Connect App。扫描并找到你的设备(默认名可能是 "Simple Peripheral")。连接至设备。
浏览服务列表,你应该能看到你创建的 "LED Service" 和其中的 "LED State" 特征值。点击 "向上箭头"(写入)按钮,输入 01 并发送,开发板上的 LED 应该点亮。
输入 00 并发送,LED 应该熄灭。点击 "向下箭头"(读取)按钮,应该能返回当前的状态(00 或 01)。
四、 注意事项
功耗优化:CC2640R2F 的优势在于低功耗。充分利用低功耗模式(休眠)。在不需要时关闭外设和传感器。优化广播和连接参数(连接间隔、从机延迟)。
内存管理:芯片的 RAM 有限,注意变量和堆栈的使用。
中断处理:在 TI-RTOS 中,耗时的操作应放在任务中处理,中断服务例程(ISR)应尽可能短。
通过这个流程,基于强大的 SDK 和工具,快速实现 CC2640R2F 的 BLE 功能开发,而无需深入理解蓝牙协议栈的所有细节。
|