一、硬件架构设计
1. 硬件连接示意图
1STM32(F103C8T6) MAX485芯片 LabVIEW PC 2- - 3USART1_TX → DI → RO (MAX485) 4USART1_RX ← RO → DI (MAX485) 5DE/RE → GPIOA.8 → DE/RE (控制) 6GND → GND 73.3V → VCC 8
2. 关键元器件选型
| 元件 | 型号 | 作用 |
|---|---|---|
| MCU | STM32F103C8T6 | 主控芯片 |
| RS485收发器 | MAX485 | 电平转换 |
| 终端电阻 | 120Ω | 抑制信号反射 |
二、STM32固件开发
1. USART初始化代码
1// USART1配置 (9600bps, 8N1) 2void USART1_Init(void) { 3 GPIO_InitTypeDef GPIO_InitStruct; 4 USART_InitTypeDef USART_InitStruct; 5 6 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); 7 8 // GPIO配置 9 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; // TX 10 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; 11 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 12 GPIO_Init(GPIOA, &GPIO_InitStruct); 13 14 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; // RX 15 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; 16 GPIO_Init(GPIOA, &GPIO_InitStruct); 17 18 // USART配置 19 USART_InitStruct.USART_BaudRate = 9600; 20 USART_InitStruct.USART_WordLength = USART_WordLength_8b; 21 USART_InitStruct.USART_StopBits = USART_StopBits_1; 22 USART_InitStruct.USART_Parity = USART_Parity_No; 23 USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 24 USART_Init(USART1, &USART_InitStruct); 25 26 // 使能接收中断 27 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); 28 USART_Cmd(USART1, ENABLE); 29} 30 31// RS485控制引脚配置 32#define RS485_DE_PIN GPIO_Pin_8 33#define RS485_DE_PORT GPIOA 34 35void RS485_SetTxMode() { 36 GPIO_SetBits(RS485_DE_PORT, RS485_DE_PIN); 37} 38 39void RS485_SetRxMode() { 40 GPIO_ResetBits(RS485_DE_PORT, RS485_DE_PIN); 41} 42
2. 数据帧结构定义
1#define FRAME_HEADER 0xAA 2#define FRAME_TAIL 0x55 3 4typedef struct { 5 uint8_t header; // 帧头 6 uint8_t addr; // 设备地址 7 uint8_t cmd; // 命令码 8 uint16_t data_len; // 数据长度 9 uint8_t *payload; // 数据负载 10 uint8_t checksum; // 校验和 11 uint8_t tail; // 帧尾 12} RS485_Frame; 13
3. 数据收发实现
1// 发送数据函数 2void RS485_SendData(uint8_t *data, uint16_t len) { 3 RS485_SetTxMode(); 4 HAL_UART_Transmit(&huart1, data, len, 1000); 5 RS485_SetRxMode(); 6} 7 8// 中断接收处理 9void USART1_IRQHandler(void) { 10 if (USART_GetITStatus(USART1, USART_IT_RXNE)) { 11 uint8_t byte = USART_ReceiveData(USART1); 12 // 实现环形缓冲区存储 13 ring_buffer_write(&rx_buf, byte); 14 } 15} 16
三、LabVIEW上位机开发
1. VISA串口配置
1[VISA Configure Serial Port] 2Resource Name: COM3 3Baud Rate: 9600 4Data Bits: 8 5Stop Bits: 1 6Parity: None 7Flow Control: None 8Termination Character: 0xA 9
2. 数据解析流程图
1[While Loop] 2│ 3├─[VISA Read] → [Bytes at Port] → [Case Structure] 4│ │ 5│ └─[Data Parsing] 6│ ├─[Check Header] → 0xAA? 7│ ├─[Extract Address] → [Compare Address] 8│ ├─[CRC Check] → [Compare Checksum] 9│ └─[Data Processing] 10│ 11└─[VISA Write] → [Response Frame] 12
3. 关键VI模块
- 串口初始化VI:配置串口参数
- 数据发送VI:构建标准数据帧
- 数据解析VI:提取有效载荷
- 状态监控VI:显示通信状态
四、通信协议设计
1. 自定义协议规范
| 字段 | 长度 | 描述 |
|---|---|---|
| Header | 1字节 | 固定为0xAA |
| Addr | 1字节 | 设备地址(0x01-0xFE) |
| Cmd | 1字节 | 命令码(如0x10=读取数据) |
| DataLen | 2字节 | 数据长度(大端格式) |
| Payload | N字节 | 有效数据 |
| Checksum | 1字节 | 前6字节累加和取低8位 |
| Tail | 1字节 | 固定为0x55 |
2. CRC校验实现
1uint8_t CalculateCRC(uint8_t *data, uint16_t len) { 2 uint8_t crc = 0; 3 for(uint16_t i=0; i<len; i++) { 4 crc ^= data[i]; 5 for(uint8_t j=0; j<8; j++) { 6 crc = (crc & 0x80) ? (crc << 1) ^ 0x31 : crc << 1; 7 } 8 } 9 return crc; 10} 11
五、完整通信流程
- 初始化阶段 STM32配置USART和GPIO LabVIEW打开串口连接
- 数据发送流程
1LabVIEW → 构建帧 → 发送帧 → 等待ACK → 处理响应
- 数据接收流程
1STM32 → 接收数据 → 校验完整性 → 触发中断 → 存入缓冲区
参考代码 STM32+RS485串口通信,上位机是labview www.youwenfan.com/contentcsl/70326.html
六、工程文件结构
1STM32_RS485_Project/ 2├── Src/ 3│ ├── main.c 4│ ├── usart_driver.c 5│ └── crc.c 6├── Inc/ 7│ ├── usart_driver.h 8│ └── crc.h 9├── LabVIEW/ 10│ ├── Serial_Comm.vi 11│ └── Data_Parser.vi 12└── Hardware/ 13 ├── schematic.pdf 14 └── gerber_files/ 15
七、扩展功能实现
- Modbus协议封装
1void Modbus_SendRequest(uint16_t addr, uint8_t func, uint16_t reg) { 2 uint8_t frame[8] = {0xAA, addr, func, 0x00, 0x02, 0x00, reg, 0x00}; 3 frame[6] = CalculateCRC(frame, 6); 4 RS485_SendData(frame, 8); 5}
- 多设备轮询
1[For Loop] 2│ 3├─[Set Address] → 0x01 → 0x02 → 0x03 4├─[Send Query] → [Read Data] 5└─[Store Results]
《基于STM32与RS485总线的串口通信》 是转载文章,点击查看原文。