用hal库实现ADC+DMA中断关闭ADC分享

2019-07-20 00:45发布

最近用hal库做ADC+DMA,想在DMA传输完成后停止ADC,考虑用DMA的传输完成中断做
2019-07-09_165829.jpg
开DMA传输完成中断:__HAL_DMA_ENABLE_IT(&hdma_adc1, DMA_IT_TC);
开全局中断:
  /* DMA2_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);            

想法没问题,但找不到中断判断函数

注意到 DMA结构体中有下面标红的函数句柄,应该配置它可以
typedef struct __DMA_HandleTypeDef
{
  DMA_Stream_TypeDef         *Instance;                                                    /*!< Register base address                  */
  DMA_InitTypeDef            Init;                                                         /*!< DMA communication parameters           */
  HAL_LockTypeDef            Lock;                                                         /*!< DMA locking object                     */  
  __IO HAL_DMA_StateTypeDef  State;                                                        /*!< DMA transfer state                     */
  void                       *Parent;                                                      /*!< Parent object state                    */  
  void                       (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma);     /*!< DMA transfer complete callback         */
  void                       (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA Half transfer complete callback    */
  void                       (* XferM1CpltCallback)( struct __DMA_HandleTypeDef * hdma);   /*!< DMA transfer complete Memory1 callback */
  void                       (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma);    /*!< DMA transfer error callback            */
__IO uint32_t               ErrorCode;                                                    /*!< DMA Error code                         */
uint32_t                    StreamBaseAddress;                                            /*!< DMA Stream Base Address                */
uint32_t                    StreamIndex;                                                  /*!< DMA Stream Index                       */
}DMA_HandleTypeDef;

基本结构为
hdma_adc1.XferCpltCallback = END_Conv;

END_Conv为传输完成的函数名
传输完成,关闭ADC函数:
void END_Conv(DMA_HandleTypeDef *hdma)
{
        ADC_DMA_DeInit();                                        //传输完成,关闭函数       
}


一切都没错,然后居然不行!!!!
得重新查问题啊
全工程搜索了一下XferCpltCallback,发现它已经有一个回调函数
/**
  * @brief  DMA transfer complete callback.
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
  *                the configuration information for the specified DMA module.
  * @retval None
  */
static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma)   
{
  ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->arent;

  /* Check if an injected conversion is ready */
  if(hadc->State == HAL_ADC_STATE_EOC_INJ)
  {
    /* Change ADC state */
    hadc->State = HAL_ADC_STATE_EOC_INJ_REG;  
  }
  else
  {
    /* Change ADC state */
    hadc->State = HAL_ADC_STATE_EOC_REG;
  }  
  HAL_ADC_ConvCpltCallback(hadc);
}

HAL_ADC_ConvCpltCallback(hadc); 是以_weak函数声明的,可以直接复制后重新定义
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
  /* Prevent unused argument(s) compilation warning */
                ADC_DMA_DeInit();                                        //传输完成,关闭函数
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_ADC_ConvCpltCallback could be implemented in the user file
   */
}

也就是我指定的END_Conv函数被ADC_DMAConvCplt给覆盖了,问题得到解决!
参考链接:http://www.stm32cube.com/article/37

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。