你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

发现CubeMX一个bug。DMA和ADC初始化顺序反了,导致DMA设置错误

[复制链接]
zhengxk-344971 发布时间:2020-1-7 15:21

问题描述:

    利用CubeMX初始化ADCDMA,发现DMA设置CCR寄存器不能设置成功,导致DMA不能按照预定工作模式工作,后经调试发现,Cube生成的初始化代码先进行ADC设置代码中也对DMA一部分寄存器进行了设置,但这部分设置由于DMA未启动,导致设置不成功。具体描述如下:



软件版本:CubeMXV5.4.0

ADC设置:
1.png




DMA设置:

2.png



生产初始化代码为:

  /* Initialize all configured peripherals */

  MX_GPIO_Init();

  MX_ADC1_Init();

  MX_DAC1_Init();

  MX_RTC_Init();

  MX_TIM6_Init();

  MX_DMA_Init();


MX_ADC1_Init->HAL_ADC_Init->HAL_ADC_MspInit:


voidHAL_ADC_MspInit(ADC_HandleTypeDef* hadc):

    /* ADC1 DMA Init */

    /* ADC1 Init */

    hdma_adc1.Instance = DMA1_Channel1;

    hdma_adc1.Init.Request = DMA_REQUEST_0;

    hdma_adc1.Init.Direction =DMA_PERIPH_TO_MEMORY;

    hdma_adc1.Init.PeriphInc =DMA_PINC_DISABLE;

    hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;

    hdma_adc1.Init.PeriphDataAlignment =DMA_PDATAALIGN_HALFWORD;

    hdma_adc1.Init.MemDataAlignment =DMA_MDATAALIGN_HALFWORD;

    hdma_adc1.Init.Mode = DMA_CIRCULAR;

    hdma_adc1.Init.Priority =DMA_PRIORITY_HIGH;

    if (HAL_DMA_Init(&hdma_adc1)!= HAL_OK)

    {

      Error_Handler();

    }


    __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);


    /* ADC1 interrupt Init */

    HAL_NVIC_SetPriority(ADC1_IRQn, 5, 0);

    HAL_NVIC_EnableIRQ(ADC1_IRQn);

  /* USER CODE BEGIN ADC1_MspInit 1 */


HAL_DMA_Init:


HAL_StatusTypeDefHAL_DMA_Init(DMA_HandleTypeDef *hdma)

{

  uint32_t tmp;


  /* Check the DMA handle allocation */

  if(hdma == NULL)

  {

    return HAL_ERROR;

  }


  /* Check the parameters */

assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));

  assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));

assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));

assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));

assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));

  assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));

assert_param(IS_DMA_MODE(hdma->Init.Mode));

assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));


assert_param(IS_DMA_ALL_REQUEST(hdma->Init.Request));


  /* Compute the channel index */

  if ((uint32_t)(hdma->Instance) <(uint32_t)(DMA2_Channel1))

  {

    /* DMA1 */

    hdma->ChannelIndex =(((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) /((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U;

    hdma->DmaBaseAddress = DMA1;

  }

  else

  {

    /* DMA2 */

    hdma->ChannelIndex =(((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) /((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2U;

    hdma->DmaBaseAddress = DMA2;

  }


  /* Change DMA peripheral state */

  hdma->State = HAL_DMA_STATE_BUSY;


  /* Get the CR register value */

  tmp = hdma->Instance->CCR;


  /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC,DIR and MEM2MEM bits */

  tmp &= ((uint32_t)~(DMA_CCR_PL    | DMA_CCR_MSIZE  | DMA_CCR_PSIZE  |

                      DMA_CCR_MINC  | DMA_CCR_PINC   | DMA_CCR_CIRC   |

                      DMA_CCR_DIR   | DMA_CCR_MEM2MEM));


  /* Prepare the DMA Channel configuration */

  tmp |= hdma->Init.Direction        |

          hdma->Init.PeriphInc           | hdma->Init.MemInc           |

          hdma->Init.PeriphDataAlignment |hdma->Init.MemDataAlignment |

          hdma->Init.Mode                | hdma->Init.Priority;


  /* Write to DMA Channel CR register */

  hdma->Instance->CCR = tmp;


上述初始化代码为CubeMX根据配置生产,代码本身没有问题。在此时设置DMA时,需要设置CCR寄存器,但此时DMA的使能并没有打开,因此设置不成功。

3.png


    如果调整一开始的初始化顺序,先进行DMA初始化,调整代码如下:

  /* Initialize allconfigured peripherals */

  MX_GPIO_Init();

  MX_DMA_Init();

  MX_ADC1_Init();

  MX_DAC1_Init();

  MX_RTC_Init();

  MX_TIM6_Init();


4.png

此时DMA1EN为1,CCR1寄存器也设置成功。


    以前也是这么用的,也没这个问题,等到更新了CubeMX版本后,就出现了这个问题。总感觉CubeMX更新太快,而且每次更新变化太大,刚刚适应的一更新又变了,而且更新完了还有问题。虽然更新是好事情,但不能没测试好就更新吧,这么多人把代码用在产品中,出一点问题就增加多少人的工作量和隐患呢?希望以后更新能慎重。




收藏 评论3 发布时间:2020-1-7 15:21

举报

3个回答
pkoko 回答时间:2020-1-8 12:53:09
最近搞一个UART的串口DMA也碰到类似问题,CubeMX自动生成的代码如下,初始化DMA放到初始化串口后面了
  1.   MX_USART2_UART_Init();
  2.   MX_TIM2_Init();
  3.   MX_DMA_Init();
复制代码

改为如下,才能正常工作:
  1.   MX_DMA_Init();
  2.   MX_USART2_UART_Init();
  3.   MX_TIM2_Init();
复制代码
zhengxk-344971 回答时间:2020-1-9 13:42:01
pkoko 发表于 2020-1-8 12:53
最近搞一个UART的串口DMA也碰到类似问题,CubeMX自动生成的代码如下,初始化DMA放到初始化串口后面了

改为 ...

看了以前版本生成的代码,DMA初始化在前面,就没有问题,不知道为什么后来的版本调整为后面了。
zhengxk-344971 回答时间:2020-1-13 09:22:50
发现这个论坛里面好像没什么官方技术支持人员,这样的问题都不出来声明一声,是这个问题太小了,根本不值得说明呢,还是我的用法错误,水平太低了,不值得指出错误在什么地方?

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版