一、硬件设计
1. 电路连接原理图
c
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模块)
c
#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方向控制
c
#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校验函数
c
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. 数据帧发送示例
c
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); // 发送完整帧
}
四、完整主程序框架
c
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
六、参考电路图
c
+-------------------+
| |
| 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方式传输数据 实现零拷贝数据缓冲区