历史上的今天
今天是:2025年07月28日(星期一)
2021年07月28日 | STM32CubeMX | 37 - 使用RS485总线进行双板通信(SP3485)
2021-07-28 来源:eefocus
本篇详细的记录了如何使用STM32CubeMX配置 STM32F407ZGT6 使用 RS485 总线与另一个开发板之间通信。
STM32CubeMX_07 | 使用USART发送和接收数据(中断模式)。
创建并添加驱动文件
首先在工程目录下,新建文件夹和两个文件,存放编写的RS485驱动程序:
然后将rs485_drv.c添加到工程目录中:
再将rs485_drv.h所在路径添加到头文件路径中:
编写头文件
#ifndef _RS485_DRV_H_
#define _RS485_DRV_H_
#include "usart.h"
/* User Config */
#define RS485_USART huart2
#define RS485_RE_GPIO_PORT GPIOG
#define RS485_RE_GPIO_PIN GPIO_PIN_8
/* RS485 TX/RX Control */
#define RS485_TX_ENABLE() HAL_Delay(1);
HAL_GPIO_WritePin(RS485_RE_GPIO_PORT, RS485_RE_GPIO_PIN, GPIO_PIN_SET);
HAL_Delay(1);
#define RS485_RX_ENABLE() HAL_Delay(1);
HAL_GPIO_WritePin(RS485_RE_GPIO_PORT, RS485_RE_GPIO_PIN, GPIO_PIN_RESET);
HAL_Delay(1);
void RS485_Init(void);
int RS485_Transmit(uint8_t *data, uint16_t len);
#endif /* _RS485_DRV_H_ */
其中最重要的是RS485_TX_ENABLE和RS485_RX_ENABLE这两个宏定义,用来控制RS485收发器的工作模式。
编写初始化函数
因为STM32CubeMX自动生成的代码中已经完成了串口初始化和控制GPIO初始化,所以在RS485的初始化函数中,只需要使能串口中断 ,控制RS485收发器处于接收模式即可:
/**
* @breif 初始化RS485收发器为接收模式
* @param 无
* @retval 无
* @note 在调用此函数之前,确保已经初始化通信串口和控制GPIO
*/
void RS485_Init()
{
/* 使能串口接收中断 */
HAL_UART_Receive_IT(&RS485_USART, rx_data, 4);
RS485_RX_ENABLE();
}
编写发送函数
RS485发送函数与普通串口发送基本一样,只不过在发送之前需要先控制RS485收发器处于发送模式,在发送之后控制RS485收发器处于接收模式即可。
/**
* @breif 控制RS485收发器发送数据
* @param data 要发送的数据
* @param len 要发送数据的长度
* @retval 0 - 发送成功,-1 = 发送失败
*/
int RS485_Transmit(uint8_t *data, uint16_t len)
{
HAL_StatusTypeDef status;
RS485_TX_ENABLE();
status = HAL_UART_Transmit(&RS485_USART, data, len, 0xFFFF);
HAL_Delay(1);
RS485_RX_ENABLE();
return status == HAL_OK ? 0 : -1;
}
编写串口接收中断处理函数
RS485的串口接收中断处理和普通的串口接收一样,直接编写回调函数即可:
/**
* @brief 串口中断回调函数
* @note 此函数属于弱定义函数的重新实现,HAL库会自动调用
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* 判断是哪个串口触发的中断 */
if(huart ->Instance == USART2)
{
//将接收到的数据打印
printf("RX Data[0]:0x%02xrn", rx_data[0]);
printf("RX Data[1]:0x%02xrn", rx_data[1]);
printf("RX Data[2]:0x%02xrn", rx_data[2]);
printf("RX Data[3]:0x%02xrn", rx_data[3]);
//重新使能串口接收中断
HAL_UART_Receive_IT(&RS485_USART, rx_data, 4);
}
}
此处为了演示我将接收到的数据打印,实际使用中建议此处使用环形缓冲区存储接收数据,具体参考文章:ringbuff | 通用FIFO环形缓冲区实现库。
4. 编写RS485测试函数
① 在main.c中包含刚刚编写的驱动头文件:
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include #include "rs485_drv.h" /* USER CODE END Includes */ ② 然后在main函数中调用初始化函数: /* USER CODE BEGIN 2 */ printf("----- RS485 1# Board -----rn"); RS485_Init(); /* USER CODE END 2 */ ③ 在main函数最开始前定义发送测试数据: /* USER CODE BEGIN 1 */ uint8_t data[4] = {0x01, 0x02, 0x03, 0x04}; /* USER CODE END 1 */ 然后在while(1)循环中每隔5s发送一次: /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ RS485_Transmit(data, 4); HAL_Delay(5000); } /* USER CODE END 3 */ 5. 编写2#实验板的测试程序 2#实验板的配置方法、程序编写和前面的一样,不再讲述。 ① 修改2#实验板发送的测试数据: 1#实验板的日志如下: 2#实验板的日志如下:
② 修改2#实验板的打印日志:
编译、下载到2#开发板中。
史海拾趣
|
这是个ARM最小系统开发板,大家可以上淘宝买一个玩,不到50元的成本, [ 本帖最后由 jxb01033016 于 2009-9-17 11:57 编辑 ]… 查看全部问答> |
|
给大家转发个MSP430 JTAG(USB的和并口的)与目标板连接需要注意的几点总结 经常看到有初学MSP430的朋友在坛里询问MSP430 JTAG与目标板连接方面的问题,我在这里给大家总结一下,希望能给初学MSP430的朋友拨云见日,不再疑惑。 MSP430的JTAG连接主要有两种方式:4线JTAG方式(包含TDO、TDI、TMS、TCK四路标准JTAG ...… 查看全部问答> |




