stm32与RS485上位机通信
时间: 2025-04-26 22:16:49 浏览: 32
### STM32与RS485上位机之间通信实现
#### 硬件连接
为了使STM32能够通过RS485总线与其他设备通信,需正确连接硬件。通常情况下,这涉及到将USART TX/RX引脚连接至MAX485模块的数据输入/输出端子,并控制RE/DE信号以切换收发状态[^1]。
#### 软件配置
利用STM32CubeMX工具可以简化初始化过程。对于RS485应用来说,除了常规的UART参数设定外,还需要特别注意启用半双工模式并调整波特率匹配两端设备的要求[^2]。
```c
// 初始化 UART 接口为 RS485 半双工模式
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600; // 设置合适的波特率
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_INIT;
/* Enable half-duplex mode */
MODIFY_REG(huart1.Instance->CR3, USART_CR3_HDSEL, USART_CR3_HDSEL);
}
```
#### 数据传输逻辑
当作为Modbus RTU从站工作时,程序应能响应来自主站的各种请求,比如读取保持寄存器(功能码03)或写入单个寄存器(功能码06)。下面给出一段简单的接收处理函数:
```c
uint8_t buffer[256];
int length;
while (HAL_OK == HAL_UART_Receive(&huart1, &buffer[length], 1, 10))
{
if ((length >= 7 && CRC_Check(buffer, length)) || length > 250)
{
ProcessRequest(buffer); // 处理接收到的有效帧
length = 0;
}
else
{
++length;
}
}
if(length != 0){
// 清除错误帧
length = 0;
}
```
上述代码片段展示了如何持续监听串行端口上的新字符到达事件,并累积成完整的消息包直至遇到有效的CRC校验为止;之后调用`ProcessRequest()`解析具体指令。
#### Python上位机编程实例
为了让PC端充当RS485网络中的客户端角色并与嵌入式目标交互,可借助Python语言及其丰富的第三方库完成此任务。这里推荐使用pySerial扩展来操作物理层接口[^4]。
```python
import serial
from time import sleep
ser = serial.Serial(
port='COM3', # 替换成实际使用的串口号
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
)
def send_modbus_request(slave_id, function_code, start_address, quantity):
request = bytearray([
slave_id, # 设备地址
function_code, # 功能码
(start_address >> 8) & 0xFF, # 寄存器起始位置高字节
start_address & 0xFF, # 寄存器起始位置低字节
(quantity >> 8) & 0xFF, # 请求数量高字节
quantity & 0xFF # 请求数量低字节
])
crc = calculate_crc(request[:-2]) # 计算CRC校验值
request.extend(crc.to_bytes(2,'little'))
ser.write(request)
response = ser.readall()
return parse_response(response)
print(send_modbus_request(1, 3, 0x0000, 10))
sleep(1)
ser.close()
```
这段脚本定义了一个辅助函数用于构建标准MODBUS RTU查询报文并向指定的目标发出询问,随后等待回应并打印出来自远程节点的信息摘要。
阅读全文