STM32G070RBT6基于STM32CubeMX创建串口中断接收数据
✨这里只演示串口接收中断。不包含配置串口发送以及重映射printf函数。
- 🌻STM32CubeMX配置演示和Keil代码补充全过程演示:
🍁注意事项
🚩串口中断接收数据,在每次接收完成串口中断数据后,需要调用一次接收中断函数:
HAL_UART_Receive_IT(&huart1, &rx_buf, 1);
📝重写相关串口中断服务回调函数内容
📗在主程序main.c中添加全局接收字符变量以及串口中断接收数据处理部分内容。
- ⛳实现串口中断接收字符长度小于10的数据才能完整接收并转发
uint8_t rx_buf;//定义中断接收变量
/*重写串口接收中断回调函数*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1) {
HAL_UART_Transmit(&huart1, &rx_buf, 1, 1000);//串口转发数据
HAL_UART_Receive_IT(&huart1, &rx_buf, 1);//再次调用串口接收中断,否则下次无法接收到数据
}//实现接收字符长度小于10的数据才能完整接收并转发
}
//在main函数体中添加初始化代码
/* 开启 USART 1 中断 */
HAL_UART_Receive_IT(&huart1, &rx_buf, 1);//能够进入回调函数HAL_UART_RxCpltCallback的条件之一:&rx_buf==sizeof(rx_buf)
HAL_UART_Transmit(&huart1, tx_buf, sizeof(tx_buf), 1000);
HAL_Delay(1000);
⚡实现串口接收不定长数据
📓在主程序main.c中添加全局接收字符变量以及串口中断接收数据处理部分内容
#define MAX_RECV_LEN 1024 //设定可以接收的最大字节
uint8_t msg_buff[MAX_RECV_LEN] = {0}; //接收缓存区
uint8_t * msg = msg_buff; //定义一个指针指向接收缓存区
int flag = 0; //接收完成标志
int len_u4=0; //数据长度记录
/*重写串口接收中断回调函数*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/*实现串口接收不定长数据*/
uint8_t ret = HAL_OK;
msg++;
len_u4++;//数据长度计数
if( msg == msg_buff + MAX_RECV_LEN)
{
msg = msg_buff;
}
do
{
ret = HAL_UART_Receive_IT(&huart1,(uint8_t *)msg,1);
}while(ret != HAL_OK);
if(*(msg-1) == '\n') //接收以\n为结尾字符,则表示接收完成
{
flag = 1;
}
}
//在main函数体中添加初始化代码
/* 开启 USART 1 中断 */
HAL_UART_Receive_IT(&huart1, &rx_buf, 1);//能够进入回调函数HAL_UART_RxCpltCallback的条件之一:&rx_buf==sizeof(rx_buf)
HAL_UART_Transmit(&huart1, tx_buf, sizeof(tx_buf), 1000);
HAL_Delay(1000);
🚩实现数据的不定长接收参考:
https://blog.csdn.net/weixin_30616969/article/details/99339828
📚程序源码
链接:https://pan.baidu.com/s/1Cg1OnAM1BDUSjpQZgyracg
提取码:crgy
📙串口中断接收+滴答定时器超时检测实现数据不定长接收(更新补充:2024-5-25)
串口接收中断配合滴答定时器超时检测,实现数据不定长接收。滴答定时器步长单位1ms,在串口低速率通讯下,字节输出数据小于1ms,设定一个超时接收即可实现。
🥕虽然没有空闲中断+DMA方式好,但是也算是实现对不定长数据的接收,使用条件有写限制,如需要更高的通讯速率,需要匹配一个专门的定时器来做检测判断。
- 📝滴答中断回调函数处理内容:
void HAL_SYSTICK_Callback(void)
{
static uint8_t count = 0;
static uint8_t Rx_Data_Flag2 = 0;
if (Rx_Data_Flag == 1)
{
Rx_Data_Flag = 0;
Rx_Data_Flag2=1;
count = 0;//清空
}
if (Rx_Data_Flag2 == 1)
{
if (++count > 3)//接收超时3ms
{
Rx_Data_Flag2 = 0;
Receive_Data_COMPLETE = 1;
count = 0;
}
}
}
- 📄串口接收中断回调处理函数内容:
/*重写串口接收中断回调函数*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
// HAL_UART_Transmit(&huart1, &rx_buf, 1, 1000);//sizeof(rx_buf)
// HAL_UART_Receive_IT(&huart1, &rx_buf, 1);//sizeof(rx_buf)
rx_buf[r_count++] = r_data;
HAL_UART_Receive_IT(&huart1, &r_data, 1);
Rx_Data_Flag = 1;
if (r_count >= sizeof(rx_buf))
{
// r_count = 0;
rx_buf_overflow=1;//溢出标志
Receive_Data_COMPLETE = 1;//接收完成标志
}
HAL_UART_Receive_IT(&huart1, &r_data, 1);
}
}
- 📜main函数:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* 开启 USART 1 中断 */
HAL_UART_Receive_IT(&huart1, &r_data, 1); // 能够进入回调函数HAL_UART_RxCpltCallback的条件之一:&rx_buf==sizeof(rx_buf)
// HAL_UART_Transmit(&huart1, tx_buf, sizeof(tx_buf), 1000);
HAL_Delay(1000);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if (1==Receive_Data_COMPLETE&&r_count>0)
{
Receive_Data_COMPLETE = 0;
HAL_UART_Transmit(&huart1, rx_buf, r_count, 1000);
r_count = 0;
// Rx_Data_Flag = 0;
}
if (rx_buf_overflow)
{
rx_buf_overflow = 0;
HAL_UART_Transmit(&huart1, "rx_buf overflow!\r\n", 16, 1000);
HAL_UART_Transmit(&huart1, rx_buf, r_count, 1000);
}
}
/* USER CODE END 3 */
}
📚接收中断+滴答定时器检测,测试源码:
链接:https://pan.baidu.com/s/1CFDO57hIIfPuhYvf7M1BJw?pwd=cgf8
提取码:cgf8
📙hal库串口接收中断补充说明(2025-4-24)
- 使用hal库串口中断标准配置和执行流程
- 使能串口接收中断。
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);/*使能串口接收断 */
- 设置串口中断接收缓存
HAL_UART_Receive_IT(&huart1, &rx_data, 1); // 启动单字节接收中断
- 重写串口接收中断回调函数:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)//涉及多串口判断
{
//处理接收的数据放这里
HAL_UART_Receive_IT(&huart1, &rx_data, 1);//重新开启串口中断接收
}
}
串口接收空闲中断
- 使能串口接收空闲中断。
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
- 设置串口空闲中断接收缓存
#define RX_BUFFER_SIZE 256
uint8_t rx_buffer[RX_BUFFER_SIZE];
HAL_UARTEx_ReceiveToIdle_IT(&huart1, rx_buffer, RX_BUFFER_SIZE);
- 重写串口接收空闲中断回调函数:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart->Instance == USART1)
{
// 重新启动接收
HAL_UARTEx_ReceiveToIdle_IT(&huart1, rx_buffer, RX_BUFFER_SIZE);
}
}