个人理解是
hal库配置串口中断接收,就是一开始在main函数内初始化串口中断函数,再配置中断回调函数,等待数据接收自动进入中断调用我自己写的回调函数,再重新开启接收中断
流程可具体是
使用HAL库配置串口中断接收的过程:
-
初始化串口:首先,在
main
函数或其他适当的位置初始化串口。这包括配置串口的波特率、数据位、停止位、校验位等参数。 -
配置中断:配置并使能串口的中断。这通常涉及到NVIC(嵌套向量中断控制器)的配置,确保中断优先级和使能中断。
-
编写中断回调函数:实现一个中断回调函数,这个函数将会在接收到串口数据时被自动调用。HAL库提供了一个叫做
HAL_UART_RxCpltCallback
的回调函数,你可以在这个函数内实现你的数据处理逻辑。 -
启动中断接收:通过调用类似
HAL_UART_Receive_IT()
的函数来启动中断接收。这个函数通常需要传入一个指向接收缓冲区的指针和希望接收的字节数。 -
在回调函数中处理接收到的数据:一旦接收到数据,
HAL_UART_RxCpltCallback
函数将被调用。你可以在这个函数里处理接收到的数据。
#include "stm32f1xx_hal.h"
UART_HandleTypeDef huart1;
// 初始化串口
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
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.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
// 错误处理
}
}
// 中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
// 处理接收到的数据
// ...
// 重新启动中断接收
HAL_UART_Receive_IT(&huart1, (uint8_t*)recvBuffer, recvSize);
}
}
int main(void)
{
// 系统初始化
HAL_Init();
// 配置串口
MX_USART1_UART_Init();
// 启动中断接收
HAL_UART_Receive_IT(&huart1, (uint8_t*)recvBuffer, recvSize);
while (1)
{
// 主循环中的其他任务
}
}
串口中断执行操作属于非阻塞通信,阻塞通信是一种同步通信方式,其中数据传输调用会阻塞调用线程,直到操作完成
#include "stm32f1xx_hal.h"
UART_HandleTypeDef huart1;
// 初始化串口
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
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.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
// 初始化失败的处理
}
}
int main(void)
{
HAL_Init();
MX_USART1_UART_Init();
// 待发送的数据
uint8_t txData[] = "Hello, World!\n";
// 接收缓冲区
uint8_t rxData[100] = {0}; // 清零接收缓冲区
while (1)
{
// 发送数据 - 阻塞模式
HAL_UART_Transmit(&huart1, txData, sizeof(txData)-1, 1000);
// 在这里,可以添加发送成功的后续操作,如日志记录或状态更新
// 接收数据 - 阻塞模式
HAL_UART_Receive(&huart1, rxData, sizeof(rxData), 1000);
// 在这里处理接收到的数据,例如打印或者进一步解析
// 例如,打印接收到的字符串
printf("Received: %s\n", rxData);
// 清零接收缓冲区以准备下一次接收
memset(rxData, 0, sizeof(rxData));
HAL_Delay(1000); // 等待1秒,这样循环不会太快
}
}
PS 串口中断回调函数的说明
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//串口中断回调函数
{
if(huart ==&huart1)//判断中断来源(串口1:USB转串口)
{
printf("%c",USART1_NewData); //把收到的数据以 a符号变量 发送回电脑
if((USART1_RX_STA&0x8000)==0)
{//接收未完成
if(USART1_RX_STA&0x4000)
{//接收到了0x0d
if(USART1_NewData!=0x0a)USART1_RX_STA=0;//接收错误,重新开始
else USART1_RX_STA|=0x8000; //接收完成了
}
else
{ //还没收到0X0d
if(USART1_NewData==0x0d)USART1_RX_STA|=0x4000;
else
{
USART1_RX_BUF[USART1_RX_STA&0X3FFF]=USART1_NewData; //将收到的数据放入数组
USART1_RX_STA++; //数据长度计数加1
if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_NewData,1); //再开启接收中断
}
先判断中断来源,再将收到的数据以符号变量printf出,再设定一个16位的USART1_RX_STA变量,该变量的低14位负责接收数据并存储到数组中,而高两位分别作为标志是否接收到回车键(\r\n,0x0d 0x0a)