基于TMS320F28069 DSP开发板实现RS485通信
一、硬件设计
1. 电路连接原理图
TMS320F28069开发板 MAX485芯片 RS485总线
-------------------------------
GPIO12 (TX) → DI
GPIO13 (RX) → RO
GPIO14 → DE/RE(高电平发送)
GND → GND
3.3V → VCC
A+ → A+
B- → B-
2. 关键参数配置
| 参数 | 值/配置说明 |
|---|---|
| UART波特率 | 115200bps(可配置) |
| 数据格式 | 8N1(默认) |
| 终端电阻 | 120Ω(总线两端) |
| 逻辑控制电平 | 3.3V兼容(MAX485支持) |
二、软件实现
1. UART初始化(使用SCI模块)
#include "F28x_Project.h"// UART配置结构体
typedef struct {uint32_t baudRate;uint16_t dataBits;uint16_t stopBits;uint16_t parity;
} UART_Config;// 初始化SCI-A(UART)
void UART_Init(UART_Config *config) {EALLOW;SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // 使能SCI-A时钟SciaRegs.SCICCR.all = 0x0007; // 8N1模式SciaRegs.SCICTL1.all = 0x0003; // 使能TX/RX// 波特率设置(假设系统时钟100MHz)SciaRegs.SCIHBAUD = 0x0000; // 高字节SciaRegs.SCILBAUD = (100000000/config->baudRate) - 1; SciaRegs.SCICTL1.all |= 0x0020; // 清除错误标志EDIS;
}// 发送单个字符
void UART_SendChar(char c) {while(SciaRegs.SCICTL2.bit.TXEMPTY == 0); // 等待发送缓冲区空SciaRegs.SCITXBUF = c;
}// 接收单个字符
char UART_RecvChar() {while(SciaRegs.SCICTL2.bit.RXRDY == 0); // 等待接收完成return SciaRegs.SCIRXBUF;
}
2. RS485方向控制
#define RS485_TX_EN GPIO_SetBits(GPIOA, GPIO_Pin_14) // PA14控制DE/RE
#define RS485_RX_EN GPIO_ResetBits(GPIOA, GPIO_Pin_14)// 发送数据函数
void RS485_SendData(uint8_t *buf, uint16_t len) {RS485_TX_EN; // 切换到发送模式for(uint16_t i=0; i<len; i++) {UART_SendChar(buf[i]);}while(SciaRegs.SCICTL2.bit.TXEMPTY == 0); // 等待最后字节发送完成DELAY_US(100); // 保持发送状态确保数据稳定RS485_RX_EN; // 切换回接收模式
}// 接收中断服务函数
interrupt void SCIA_RX_ISR() {static uint8_t rxBuffer[256];static uint16_t index = 0;uint16_t data = SciaRegs.SCIRXBUF; // 读取接收数据if(index < sizeof(rxBuffer)) {rxBuffer[index++] = data;}// 检测帧结束符(如<CR>)if(data == '\r') {ProcessReceivedData(rxBuffer, index); // 处理完整数据帧index = 0;}PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // 清除中断标志
}
三、通信协议实现(MODBUS RTU)
1. CRC校验函数
uint16_t ModbusCRC16(uint8_t *buf, uint16_t len) {uint16_t crc = 0xFFFF;for(uint16_t i=0; i<len; i++) {crc ^= (uint16_t)buf[i] << 8;for(uint8_t j=0; j<8; j++) {if(crc & 0x8000) {crc = (crc << 1) ^ 0x1021;} else {crc <<= 1;}}}return crc;
}
2. 数据帧发送示例
void SendModbusRequest(uint8_t slaveAddr, uint8_t funcCode, uint16_t startAddr, uint16_t numRegs) {uint8_t frame[8];frame[0] = slaveAddr; // 从站地址frame[1] = funcCode; // 功能码(03读保持寄存器)frame[2] = (startAddr >> 8) & 0xFF; // 起始地址高字节frame[3] = startAddr & 0xFF; // 起始地址低字节frame[4] = (numRegs >> 8) & 0xFF; // 寄存器数量高字节frame[5] = numRegs & 0xFF; // 寄存器数量低字节uint16_t crc = ModbusCRC16(frame, 6);frame[6] = crc & 0xFF; // CRC低字节frame[7] = (crc >> 8) & 0xFF; // CRC高字节RS485_SendData(frame, 8); // 发送完整帧
}
四、完整主程序框架
void main(void) {// 系统初始化InitSysCtrl();InitGpio();UART_Init(&uartConfig); // 波特率115200, 8N1// 配置中断PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // 使能SCI-A中断EALLOW;PieVectTable.SCIRXINTA = &SCIA_RX_ISR;EDIS;PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;while(1) {// 主循环处理(可执行周期性任务)CheckBusStatus(); // 监测总线状态}
}
五、关键调试要点
- 电平匹配验证 使用示波器测量TX/RX引脚电平(TTL 0-3.3V) 检查DE/RE引脚与MAX485的连接是否正确
- 波特率校准 通过逻辑分析仪捕获数据帧,验证波特率精度 调整系统时钟分频系数(如需要)
- 总线终端电阻 在总线首尾各接120Ω电阻(确保通信距离>50米时必需)
- 抗干扰措施 添加0.1μF和10μF去耦电容 使用双绞线或屏蔽电缆
参考代码 tms320f28069开发板实现485通信功能 www.youwenfan.com/contentcsl/72139.html
六、参考电路图
+-------------------+| || TMS320F28069 || |
GPIO12 (TX) -->|SCITXDA |
GPIO13 (RX) <--|SCIRXDA |
GPIO14 -->|GPIOA14 (DE/RE) |
GND --------|GND |
3.3V -------|VCC |
A+ ---------|A+ (总线) |
B- ---------|B- (总线) || |+-----|-----+ || MAX485 || |+-------+||+-----|-----+| 120Ω || 终端电阻 |+----------+|+-----|-----+| 其他节点|+----------+
七、开发建议
- 开发环境 使用CCS v7.5(TI官方IDE) 配置SCI-A中断优先级为最高
- 调试技巧 通过SCI控制台输出调试信息 使用逻辑分析仪捕获RS485差分信号
- 代码优化 采用DMA方式传输数据 实现零拷贝数据缓冲区
