在STM32中编写串口通信数据收发有三种方式:轮询模式(阻塞方式),中断模式(非阻塞方式)以及DMA模式。
一. 串口通信(中断模式)
打开STM32CubeMX,前部分配置流程如串口数据收发基础(二)节里一样。配置好USART1的基本参数后,接下来就要开启USART1的串口中断了。
设置好之后,设置存储路径,选择所用IDE,然后点击GENERATE CODE创建工程,open project打开工程进行全局编译。
二. HAL库中串口收发的重要函数(中断模式)
1. 非阻塞式发送函数:HAL_UART_Transmit_IT ( UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
@简介 以非阻塞模式发送一定数量的数据。
@参数 huart,串口实例的指针,指向UART_HandleTypeDef结构体的指针,该结构体包含指定UART模块的配置信息。
@参数 pData,待发送数据缓冲区的指针。
@参数 Size,待发送数据的字节数。
@返回值 函数执行状态。
2. 串口发送完毕中断回调函数 以及 串口发送过半中断回调函数
@简介 Tx传输完成的回调函数。
@参数 huart,串口实例的指针,指向UART_HandleTypeDef结构体的指针,该结构体包含指定UART模块的配置信息。
@返回值 空
__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
}
-----------------------------------------------------------------------
@简介 Tx传输完成过半的回调函数。
@参数 huart,串口实例的指针,指向UART_HandleTypeDef结构体的指针,该结构体包含指定UART模块的配置信息。
@返回值 空
__weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
}
3. 非阻塞式接收函数:HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
@简介 以非阻塞模式发送一定数量的数据。
@参数 huart,串口实例的指针,指向UART_HandleTypeDef结构体的指针,该结构体包含指定UART模块的配置信息。
@参数 pData,数据接收据缓冲区的指针。
@参数 Size,待接收数据的字节数。
@返回值 函数执行状态。
2. 串口接收完毕中断回调函数 以及 串口接收过半中断回调函数
@简介 Rx接收完成过半的回调函数。
@参数 huart,串口实例的指针,指向UART_HandleTypeDef结构体的指针,该结构体包含指定UART模块的配置信息。
@返回值 空
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
}
-----------------------------------------------------------------------
@简介 Rx接收完成过半的回调函数。
@参数 huart,串口实例的指针,指向UART_HandleTypeDef结构体的指针,该结构体包含指定UART模块的配置信息。
@返回值 空
__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
}
以上提及的函数均在stm32f1xx_hal_uart.c中,在该文件中找到
三. 实现串口收发通信(中断模式)
在mian.c文件中Private variables下的USER CODE BEGIN PV注释对中写入以下代码
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
unsigned char String_1[] = "hello world!!!\r\n";
unsigned char txbuff[16];
unsigned char rxbuff[3];
/* USER CODE END PV */
在mian.c文件中Private function prototypes下的USER CODE BEGIN PFP注释对中写入以下代码
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
// 串口接收中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
if(huart == &huart1){
if(rxbuff[0] == 0xAA && rxbuff[2] == 0xCC){ //检测输入的命令帧 AA为帧头,CC为帧尾
if(rxbuff[1] == 0x01){ // 当接收到的中间控制字为0x01,点亮LED
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET); // 点亮LED
sprintf((char *)txbuff,"LED open.\r\n");
}else if(rxbuff[1] == 0x00){ // 当接收到的中间控制字为0x00,熄灭LED
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET); // 熄灭LED
sprintf((char *)txbuff,"LED close.\r\n");
}else{ //当接受到的中间控制字不为0x00或0x01时,输出error
sprintf((char *)txbuff,"error.\r\n");
}
}else{
sprintf((char *)txbuff,"error.\r\n");
}
HAL_UART_Transmit_IT(&huart1,txbuff,sizeof(txbuff));
}
HAL_UART_Receive_IT(&huart1,rxbuff,sizeof(rxbuff));
}
/* USER CODE END PFP */
在mian.c文件中main函数下的while中写入以下代码
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_UART_Receive_IT(&huart1,rxbuff,sizeof(rxbuff));
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */