HAL库程序里面中断的响应及调用过程

这个文章的主要总结的是程序在HAL库里面初始化和执行过程,同时对于一些中断的响应执行过程

GPIO

对于普通的GPIO的初始化没有任何回调函数
对于使用了中断的GPIO,中断的开启和优先级设置时在初始化时完成,但是其中断的响应是调用首先调用HAL库提供的中断处理函数HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);在这个函数里面通过回调HAL_GPIO_EXTI_Callback(GPIO_Pin);函数完成中断的响应和处理,因此这个函数需要我们自己编写代码实现

串口

对于串口的初始化调用的函数为HAL_UART_Init,但是这个函数会回调一个函数HAL_UART_MspInit 这个函数需要我们自己编写完成,主要完成的功能是对对应外设引脚的初始化和中断设置操作

串口的中断发送和接收,使用这两个函数
在这里插入图片描述
中断发送和接收完成的处理过程为:
通过中断服务程序调用 HAL_UART_IRQHandler(&huart1),并回调如下两个函数(接收和中断完成调用的回调函数不一样),这两个函数如果使用中断都需要我们自己编写完成
在这里插入图片描述

ADC

初始化使用函数HAL_ADC_Init(&hadc),但是会回调函数HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)完成初始化。
注意上面的仅是初始化了ADC的功能,但是ADC并不知道去采集那个通道的数据

需通过如下设置,完成通道的采样设置
在这里插入图片描述

如果ADC使用了中断
中断调用这个函数HAL_ADC_IRQHandler(&hadc);并回调HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)ADC转换完成回调函数

DMA

初始化

void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspInit 0 */

  /* USER CODE END ADC1_MspInit 0 */
    /* ADC1 clock enable */
    __HAL_RCC_ADC1_CLK_ENABLE();
  
    /**ADC GPIO Configuration    
    PA1     ------> ADC_IN1
    PA4     ------> ADC_IN4 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* ADC1 DMA Init */
    /* ADC Init */
    hdma_adc.Instance = DMA1_Channel1;
    hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_adc.Init.Mode = DMA_CIRCULAR;
    hdma_adc.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_adc) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }

    __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc);

  /* USER CODE BEGIN ADC1_MspInit 1 */

  /* USER CODE END ADC1_MspInit 1 */
  }
}

void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{

  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspDeInit 0 */

  /* USER CODE END ADC1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_ADC1_CLK_DISABLE();
  
    /**ADC GPIO Configuration    
    PA1     ------> ADC_IN1
    PA4     ------> ADC_IN4 
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1|GPIO_PIN_4);

    /* ADC1 DMA DeInit */
    HAL_DMA_DeInit(adcHandle->DMA_Handle);
  /* USER CODE BEGIN ADC1_MspDeInit 1 */

  /* USER CODE END ADC1_MspDeInit 1 */
  }
} 

如果DMA需要打开中断,在任意地方调用这两个函数即可

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

DMA中断的执行过程
中断响应函数调用
HAL_DMA_IRQHandler(&hdma_adc);,并回调HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)这个函数

这里有个需要注意的点,如果直接跟踪函数HAL_DMA_IRQHandler,是无法看到对应回调的实现的,而是通过函数指针调用的这个函数(具体的函数指针是:hdma->XferCpltCallback(hdma);),这指针的初始化是在打开DMA功能时赋值进去的即这个函数HAL_ADC_Start_DMA(这里有这么一段:在这里插入图片描述
这函数函数就是后期我们需要实现,分别转换完成,半转换,错误时的调用完成的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值