STM32 利用空闲中断接收数据
- 利用cubeMX打开DMA串口接收中断
- 利用CubeMX打开串口中断
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
-
打开空闲中断 //打开空闲中断使能
__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
-
使能DMA 接收数据 //启动 DMA 接收数据
HAL_UART_Receive_DMA(&huart2, uart2_data, 128);
-
在中断函数内部调用自定义中断函数
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
HB_IRQHandler(&huart2);
/* USER CODE END USART2_IRQn 1 */
}
- 空闲中断触发以后需要清除空闲中断标志(使用如下函数),
- 在空闲中断函数内部计算已经传输的字节数量
uint8_t uart2_data[128];
uint8_t uart2_flag = 0;
void HB_IRQHandler(UART_HandleTypeDef *huart)
{
if (huart == &huart2)
{
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
{
HAL_UART_DMAStop(huart);
//__HAL_UART_CLEAR_FLAG(huart,UART_FLAG_IDLE); //使用这个函数不生效,不知道为啥
__HAL_UART_CLEAR_IDLEFLAG(huart);
uart2_flag = 1;
//计算获取到的数据个数
//huart->RxXferSize 希望传输的数据个数
//huart->hdmarx->Instance->CNDTR DMA还需要传输的字节数
huart->RxXferCount = huart->RxXferSize - huart->hdmarx->Instance->CNDTR;
}
}
}
串口口中断函数调用自定义中断函数
/**
* @brief This function handles USART2 global interrupt.
*/
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
//调用自定义函数
HB_IRQHandler(&huart2);
/* USER CODE END USART2_IRQn 1 */
}
cubeMX设置
main 函数初始化代码
/**
* @brief The application entry point.
* @retval int
*/
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_DMA_Init();
MX_I2C1_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
printf("hello hebao\r\n");
Button_Create("Button1",
&Button1,
Read_KEY1_Level,
0);
Button_Attach(&Button1, EV_CLICK, Btn1_Dowm_CallBack); //单击
Button_Attach(&Button1, EV_DOUBLE_CLICK, Btn1_Double_CallBack); //双击
Button_Attach(&Button1, EV_LONG_CLICK, Btn1_Continuos_CallBack); //连按
//HAL_UART_Receive_IT(&huart2, uart2_data, 32);
//打开空闲中断使能
__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
//启动 DMA 接收数据
HAL_UART_Receive_DMA(&huart2, uart2_data, 128);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
Button_Process(); //需要周期调用按键处理函数
HAL_Delay(50);
if (uart2_flag)
{
for (uint8_t i = 0; i < huart2.RxXferCount; i++)
{
printf("%02x ", uart2_data[i]);
}
printf("\r\n");
uart2_flag = 0;
//数据处理完成以后再次打开接收数据
HAL_UART_Receive_DMA(&huart2, uart2_data, 128);
//__HAL_UART_CLEAR_OREFLAG(&huart2);
// HAL_UART_Receive_IT(&huart2, uart2_data, 32);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
测试结果
|