|
问题描述: 利用CubeMX初始化ADC和DMA,发现DMA设置CCR寄存器不能设置成功,导致DMA不能按照预定工作模式工作,后经调试发现,Cube生成的初始化代码先进行ADC设置代码中也对DMA一部分寄存器进行了设置,但这部分设置由于DMA未启动,导致设置不成功。具体描述如下: 软件版本:CubeMXV5.4.0 ADC设置:
DMA设置:
生产初始化代码为: /* 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的使能并没有打开,因此设置不成功。
如果调整一开始的初始化顺序,先进行DMA初始化,调整代码如下: /* Initialize allconfigured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_ADC1_Init(); MX_DAC1_Init(); MX_RTC_Init(); MX_TIM6_Init();
此时DMA1EN为1,CCR1寄存器也设置成功。 以前也是这么用的,也没这个问题,等到更新了CubeMX版本后,就出现了这个问题。总感觉CubeMX更新太快,而且每次更新变化太大,刚刚适应的一更新又变了,而且更新完了还有问题。虽然更新是好事情,但不能没测试好就更新吧,这么多人把代码用在产品中,出一点问题就增加多少人的工作量和隐患呢?希望以后更新能慎重。 |
微信公众号
手机版
改为如下,才能正常工作:
看了以前版本生成的代码,DMA初始化在前面,就没有问题,不知道为什么后来的版本调整为后面了。