CUBEMX生成代码需要注意顺序,折腾STM32+ADC+DMA

问题现象:

用最新版的6.3.0版CUBEMX+最新的L0系列1.12.1的库,生成ADC+DMA代码,添上几句简单的代码和回调函数本应该就可以正常AD了,结果DMA始终无法传输数据,而单步运行所有初始化和运行过程始终返回HAL_OK,但是始终不进DMA传输过程
一度以为买到假的STM32,又一度以为板子设计有问题而开始怀疑人生。

解决办法:

将CUBEMX生成的原始代码中main初始化代码

  MX_GPIO_Init(); 
  MX_ADC_Init();
  MX_DMA_Init();

调整ADC和DMA初始化顺序成为

  MX_GPIO_Init(); 
  MX_DMA_Init();
  MX_ADC_Init();

原因:

CUBEMX在ADC的初始化过程中加入了DMA和ADC之间产生关联的代码

/**
* @brief ADC MSP Initialization
* This function configures the hardware resources used in this example
* @param hadc: ADC handle pointer
* @retval None
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hadc->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspInit 0 */
		HAL_DMA_DeInit(&hdma_adc);

  /* USER CODE END ADC1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_ADC1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**ADC GPIO Configuration
    PA0     ------> ADC_IN0
    PA1     ------> ADC_IN1
    PA7     ------> ADC_IN7
    */
    GPIO_InitStruct.Pin = Battry_vol_Pin|Temp85_1st_Input_Pin|Temp85_2st_Input_Pin;
    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.Request = DMA_REQUEST_0;
    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_HIGH;
    if (HAL_DMA_Init(&hdma_adc) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc);

    /* ADC1 interrupt Init */
    HAL_NVIC_SetPriority(ADC1_COMP_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(ADC1_COMP_IRQn);
  /* USER CODE BEGIN ADC1_MspInit 1 */
		
  /* USER CODE END ADC1_MspInit 1 */
  }

}

而DMA的时钟却在执行完ADC初始化后才开启,换句话就是如果先运行ADC初始化而没有开启DMA时钟会导致DMA配置失败,而不会返回任何错误代码。

static void MX_DMA_Init(void)
{

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

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

}

由此产生了DMA不传输AD数据。

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值