1. DSP28035的CAN升级方案概述
在工业控制和汽车电子领域,CAN总线因其高可靠性和实时性成为主流通信协议。DSP28035作为TI经典的C2000系列数字信号处理器,其内置CAN控制器为设备升级提供了硬件基础。本文将详细解析基于GPIO30引脚实现的500Kbps波特率CAN通信测试平台,以及与C#上位机交互的完整解决方案。
这个方案特别适用于需要远程固件更新(FOTA)的场合,比如:
- 工业现场设备的程序升级
- 新能源汽车电控单元的参数调整
- 分布式传感器网络的配置更新
相比传统JTAG烧录方式,CAN升级具有明显优势:
- 无需拆机即可完成升级
- 支持多节点批量操作
- 传输距离可达理论1km(实际约40m@500Kbps)
2. 硬件设计与关键配置
2.1 DSP28035的CAN外设初始化
首先需要配置系统时钟和CAN模块时钟。DSP28035的CAN时钟源自SYSCLKOUT,通过配置HISPCP和LOSPCP分频器获得合适的工作频率。以下是关键寄存器配置示例:
c复制// 系统时钟初始化(假设使用内部10MHz振荡器,PLL×10得到100MHz)
SysCtrlRegs.PLLCR.bit.DIV = 10;
while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1);
// CAN模块时钟配置(使用LSPCLK)
SysCtrlRegs.LOSPCP.all = 0x02; // 设置低速外设时钟为100MHz/4=25MHz
// CAN控制器初始化
ECanaRegs.CANMC.bit.SCB = 1; // 退出初始化模式
ECanaRegs.CANMC.bit.CCR = 1; // 进入配置模式
while(ECanaRegs.CANES.bit.CCE != 1); // 等待配置模式就绪
2.2 GPIO30作为CANRX的特殊配置
DSP28035的GPIO30复用为CANRX引脚时需特别注意:
- 必须禁用数字输入缓冲(降低功耗和噪声)
- 配置正确的上拉/下拉电阻
- 设置输入限定滤波(防抖动)
具体配置代码:
c复制GpioCtrlRegs.GPAPUD.bit.GPIO30 = 0; // 启用上拉
GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 3; // 异步输入模式
GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 3; // 复用为CANRX功能
2.3 500Kbps波特率计算与配置
CAN总线时序由以下参数决定:
- 同步段(SYNC_SEG):固定1个时间量子(TQ)
- 传播时间段(PROP_SEG):补偿物理延迟
- 相位缓冲段1/2(PS1/PS2):调整采样点位置
对于25MHz的CAN时钟,500Kbps波特率配置如下:
c复制ECanaRegs.CANBTC.bit.BRP = 4; // 波特率预分频:(BRP+1)=5 → 5MHz
ECanaRegs.CANBTC.bit.TSEG1 = 6; // PS1=7 TQ
ECanaRegs.CANBTC.bit.TSEG2 = 1; // PS2=2 TQ
ECanaRegs.CANBTC.bit.SJW = 1; // 同步跳转宽度=2 TQ
实际波特率计算:
code复制TQ = (BRP+1)/CAN_CLK = 5/25MHz = 200ns
位时间 = (1 + TSEG1+1 + TSEG2+1) × TQ = 10 × 200ns = 2μs → 500Kbps
3. 固件设计实现
3.1 双Bank Flash架构设计
DSP28035的Flash分为Bank0(64K)和Bank1(32K),安全升级方案通常采用以下分区:
- Bank0:Bootloader(8K)
- Bank0剩余:应用代码V1
- Bank1:应用代码V2(备份/待升级)
关键操作流程:
- Bootloader验证V1签名
- 通过CAN接收新固件写入Bank1
- 校验通过后跳转至Bank1执行
- 下次启动时将Bank1内容复制到Bank0
3.2 CAN通信协议设计
自定义应用层协议帧格式:
| 字段 | 长度 | 说明 |
|---|---|---|
| HEAD | 2B | 0xAA55帧头 |
| CMD | 1B | 指令类型 |
| LEN | 1B | 数据长度 |
| DATA | 0-8B | 有效载荷 |
| CRC | 2B | CCITT-CRC16校验 |
常用指令示例:
- 0x01:查询设备信息
- 0x10:开始传输(含总包数)
- 0x11:数据包(含序号)
- 0x12:结束传输(含整体CRC32)
3.3 看门狗与异常处理
为确保升级过程可靠,必须实现多级保护:
c复制// 独立看门狗配置(每500ms喂狗)
SysCtrlRegs.WDCR = 0x0028; // 启用WDT,预分频64
while(1) {
SysCtrlRegs.WDKEY = 0x55;
SysCtrlRegs.WDKEY = 0xAA;
// ... 主循环代码 ...
}
异常处理策略:
- 通信超时:3次重试后复位
- CRC校验失败:丢弃当前包并请求重传
- Flash写入错误:回滚至上一版本
4. C#上位机开发要点
4.1 PCAN-USB接口配置
使用PCAN-Basic API进行通信初始化:
csharp复制TPCANStatus result = PCANBasic.Initialize(
PCANBasic.PCAN_USBBUS1,
PCANBasic.PCAN_BAUD_500K,
PCANBasic.PCAN_TYPE_ISA,
0, 0);
if (result != TPCANStatus.PCAN_ERROR_OK) {
// 错误处理...
}
4.2 多线程数据处理架构
推荐采用生产者-消费者模式:
csharp复制BlockingCollection<CANMsg> queue = new BlockingCollection<CANMsg>(1000);
// 接收线程
Thread receiver = new Thread(() => {
while (true) {
TPCANMsg msg;
PCANBasic.Read(PCANBasic.PCAN_USBBUS1, out msg);
queue.Add(new CANMsg(msg));
}
});
// 处理线程
Thread processor = new Thread(() => {
foreach (var msg in queue.GetConsumingEnumerable()) {
// 解析协议、更新UI等
}
});
4.3 进度显示与断点续传
实现进度条需要计算:
csharp复制double progress = (double)receivedPackets / totalPackets * 100;
progressBar1.Invoke((Action)(() => {
progressBar1.Value = (int)progress;
}));
断点续传实现要点:
- 每个数据包带有序号
- 上位机记录已发送包
- 重连后请求缺失的包
5. 系统联调与性能优化
5.1 眼图测试与信号完整性
使用示波器观察CANH-CANL差分信号时,应关注:
- 上升/下降时间:建议30-70ns
- 显性电平:≥1.5V
- 隐性电平:≤0.5V
常见问题处理:
- 过冲:增加终端电阻(120Ω)
- 振铃:缩短布线长度或加磁珠
- 边沿过缓:检查驱动器供电电压
5.2 传输速率实测数据
不同包大小的实际吞吐量对比:
| 数据长度 | 理论速率 | 实测速率 | 效率 |
|---|---|---|---|
| 8字节 | 500Kbps | 380Kbps | 76% |
| 64字节 | 500Kbps | 420Kbps | 84% |
| 256字节 | 500Kbps | 460Kbps | 92% |
注意:实际效率受协议开销(帧间隔、ACK等)影响
5.3 抗干扰测试方案
通过以下测试验证可靠性:
- 静电放电:接触放电±8kV(IEC 61000-4-2)
- 脉冲群:±2kV(IEC 61000-4-4)
- 浪涌:±1kV(IEC 61000-4-5)
整改措施:
- 添加TVS管(如SM712)
- 共模扼流圈(100Ω@100MHz)
- 优化PCB布局(缩短差分线长度)
6. 常见问题与解决方案
6.1 CAN通信失败排查步骤
-
检查物理连接:
- 终端电阻是否安装
- 线缆是否短路/断路
- 极性是否正确(CANH/CANL)
-
验证信号质量:
bash复制# Linux环境使用candump观察原始帧 candump can0 -l -
寄存器状态检查:
c复制if (ECanaRegs.CANES.bit.BOFF) { // 总线关闭状态 } if (ECanaRegs.CANES.bit.EPASS) { // 错误被动状态 }
6.2 Flash写入异常处理
典型错误及对策:
| 错误代码 | 原因 | 解决方案 |
|---|---|---|
| 0x0001 | 地址越界 | 检查分区表 |
| 0x0002 | 写保护 | 解锁Flash区 |
| 0x0004 | 校验失败 | 重写并验证 |
关键解锁序列:
c复制EALLOW;
FlashRegs.FOPT.bit.ENPIPE = 1;
FlashRegs.FBANKWAIT.bit.PAGEWAIT = 5;
EDIS;
6.3 上位机兼容性问题
多版本兼容处理技巧:
csharp复制// 动态加载不同版本的DLL
[DllImport("PCANBasic.dll", EntryPoint = "CAN_Initialize")]
private static extern TPCANStatus InitializeV1(/*...*/);
[DllImport("PCANBasic_v2.dll", EntryPoint = "CAN_Initialize")]
private static extern TPCANStatus InitializeV2(/*...*/);
7. 进阶优化方向
7.1 差分升级策略
通过对比新旧固件生成差异包:
- 使用bsdiff算法生成补丁
- 上位机应用补丁生成新固件
- 传输量减少60-80%
实现示例:
python复制# 生成差异文件
import bsdiff4
bsdiff4.file_diff("old.bin", "new.bin", "patch.bin")
# 应用补丁
bsdiff4.file_patch("old.bin", "patch.bin", "new.bin")
7.2 安全加密方案
基于AES-128的固件加密流程:
- 上位机生成随机密钥K
- 用设备公钥加密K:E(K, PubKey)
- 用K加密固件:AES(Firmware, K)
- 设备私钥解密K,再解密固件
7.3 无线中继扩展
通过WiFi/4G转CAN的网关架构:
code复制[PC] ←HTTP→ [网关] ←CAN→ [DSP28035]
网关实现要点:
- 协议转换(JSON↔CAN)
- 数据缓存(防止丢包)
- 心跳监测(连接保持)