引言
在很多工业应用中,设备之间的通信十分重要,特别是使用串口进行数据传输。在这篇文章中,我们将讨论如何使用STM32单片机配置RS-485串口通讯,并通过简单的实验来演示这个过程。
工具与环境
-
硬件:
- STM32开发板(本文使用STM32H750)
- RS-485转USB模块
- MAX485模块
-
软件:
- STM32CubeMX
- STM32CubeIDE
- 串口调试工具
RS-485 简介
RS-485是一种使用差分信号进行串行通信的标准,适用于长距离和抗干扰的环境。由于具备多点通信的能力,它被广泛应用于工业控制和自动化领域。在STM32中,通过UART模块可以轻松配置485通讯。
硬件连接
以下是STM32和RS-485模块的连接示意:
STM32 RS-485模块
-------------------------------
TX (PE8) ---------> DI
RX (PE7) ---------> RO
GND ---------> GND
VCC ---------> VCC
PE4 ---------> RE/DE
MAX485芯片的工作原理及引脚详细说明见(MAX485原理及引脚说明-CSDN博客)
总结来说:由于485只能以半双工的形式工作,接收和发送数据不能同时进行。RE和DE引脚连在一起的,切换状态电平状态就可以做到只能发送或者只能接收了。MAX485芯片中有“RE”和“DE”两个引脚,用于控制485芯片的收发工作状态的, 当RE引脚为低电平时,485芯片处于接收状态,当DE引脚为高电平时芯片处于发送状态。实验板中使用了STM32的PE4直接连接到这两个引脚上, 所以通过控制PE4的输出电平即可控制485的收发状态。
关于延迟时间
-
数据发送完后的延迟:
当MCU通过UART发送数据后,必须等待足够的时间以确保所有数据都已经通过RS-485收发器发送完毕。这个时间取决于发送的最后一个字节的位数以及UART的波特率。通常情况下,对于一个字节的发送,我们需要至少等待1个字节时间再切换状态。计算公式:
延迟=字节位数×1/波特率对于RS-485,通常一个字节包含8位数据,加上1位起始位和1位停止位,所以总共是10位。因此,如果波特率是9600波特,需要等待的时间为:
延迟=10×1/9600≈1.04ms -
数据接收后的延迟:
在接收数据后,需要确保在切换状态之前,有足够的时间来处理接收到的数据。为了避免数据丢失,常见的做法是确保接收数据期间RE(接收使能)为高状态,并在收完一个完整字节后再将DE拉高,开始下一次发送。一般来说,在接收设置结束后,也需要稍等1个字节的时间。这里的延迟同样使用上面的计算公式。
STM32CubeMX配置
-
创建工程:打开STM32CubeMX,创建一个新工程,选择STM32H750系列的芯片。
-
配置USART:
-
开启串口中断、DMA(可选):
4. 配置PE4输出模式
5. 生成代码:配置完成后,点击“Project”->“Generate Code”生成代码,并在IDE中打开。
编写代码
串口初始化准备,串口DMA中断函数
//初始化准备
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4, GPIO_PIN_RESET); //PE4低电平,接收模式
HAL_UART_Receive_DMA(&huart7, (uint8_t*) charge_485_Rxdata,
sizeof(charge_485_Rxdata));
__HAL_UART_ENABLE_IT(&huart7, UART_IT_IDLE); //使能空闲中断
//串口中断函数
void UART7_IRQHandler(void)
{
/* USER CODE BEGIN UART7_IRQn 0 */
if (__HAL_UART_GET_IT( &huart7, UART_IT_IDLE ) != RESET) //判断是否是空闲中断
{
__HAL_UART_CLEAR_IDLEFLAG(&huart7); //清除空闲中断标志
HAL_UART_AbortReceive(&huart7); //停止DMA
charge_485_data_Len = sizeof(charge_485_Rxdata) - __HAL_DMA_GET_COUNTER(&hdma_uart7_rx); //接收的数据长度
charge_485_data_flag = 1; //接收中断标志位
HAL_UART_Receive_DMA(&huart7,(uint8_t *)charge_485_Rxdata,sizeof(charge_485_Rxdata)); //使能接收
}
/* USER CODE END UART7_IRQn 0 */
HAL_UART_IRQHandler(&huart7);
/* USER CODE BEGIN UART7_IRQn 1 */
/* USER CODE END UART7_IRQn 1 */
}
主函数循环中监测标志位收到485信息:
if (charge_485_data_flag) {
HAL_Delay(100); //接收延时时间,因为接收在中断函数中,延时写在这里方便大家理解
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4, GPIO_PIN_SET); //PE4高电平,发送模式
HAL_UART_Transmit_DMA(&huart7, (uint8_t*) charge_485_Rxdata,
charge_485_data_Len);
HAL_Delay(100); //发送延时时间
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4, GPIO_PIN_RESET);//PE4低电平,接收模式
charge_485_data_flag = 0;
}
测试与调试
-
连接设备:确保RS-485模块连接正确。
-
打开串口调试工具,设置相同的波特率等参数。
-
上传代码到STM32开发板,观察串口调试工具的输出。
总结
在本实验中,我们介绍了如何使用STM32配置串口进行RS-485通讯。通过STM32CubeMX的配置和相应的代码实现,实现了基本的数据发送与接收功能。这个实验为后续更复杂的通信系统搭建奠定了基础。
希望这篇文章对你有所帮助!如果有任何问题或建议,请在评论区留言。串口DMA中断模块具体如何配置后续会有专门的篇章发出。