有人使用STM32U5系列MCU开发产品,在用到ADC结合DMA传输时遇到点障碍,这里针对片内ADC1和ADC4基于DMA标准请求模式和链表模式演示下实现过程,以供参考。
先对ADC1基于DMA标准请求模式做演示。
随意选择ADC1的4个通道,扫描模式,连续转换,DMA传输转换结果并令DMA工作在外设字到内存字的循环传输模式。使用CubeMx进行配置。其中DMA通道使用Channel 1。
![]()
![]()
![]()
相关代码:
- #define ADC_BUFFRER_SIZE ((uint32_t) 8)
- uint32_t ADC1_Result[ADC_BUFFRER_SIZE];
- ADC_HandleTypeDef hadc1;
- DMA_HandleTypeDef handle_GPDMA1_Channel1; //For ADC1
- /* USER CODE BEGIN 2 */
- HAL_PWREx_EnableVddA(); //add it manually with lower cubeMx version
- __HAL_LINKDMA(&hadc1, DMA_Handle, handle_GPDMA1_Channel1);
- if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC1_Result,
- (ADC_BUFFRER_SIZE)
- ) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE END 2 */
复制代码
运行结果如下图所示:【目前4个通道我是悬空的】
![]()
现在对ADC4基于DMA链表模式做演示,其实就一个节点。
选择ADC4的4个内部信号通道,扫描模式,连续转换,DMA传输转换结果,并令DMA工作在外设字到内存字的循环模式。使用CubeMx进行配置。其中DMA通道使用Channel 0。对于内部信号的采样,往往有最小采样时间要求,我这里的演示随便选了个参数,具体应用时请参考数据手册及当时ADC时钟具体拟定。特此提醒!
![]()
关于DMA链表模式的配置在CubeMx界面里的Utility菜单下。
![]()
![]()
![]()
相关用户代码:
- /* Private variables ---------------------------------------------------------*/
- ADC_HandleTypeDef hadc4;
- DMA_NodeTypeDef Node_GPDMA1_Channel1;
- DMA_QListTypeDef List_GPDMA1_Channel1;
- DMA_HandleTypeDef handle_GPDMA1_Channel0;
- /* USER CODE BEGIN PV */
- /* USER CODE BEGIN 2 */
- HAL_PWREx_EnableVddA(); //add it manually with lower cubeMx version
- MX_ADC4Queue_Config();
- __HAL_LINKDMA(&hadc4, DMA_Handle, handle_GPDMA1_Channel0);
- HAL_DMAEx_List_SetCircularMode(&ADC4Queue);
- if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel0, &ADC4Queue) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_ADC_Start_DMA(&hadc4,
- (uint32_t *)ADC4_Result,
- (ADC_BUFFRER_SIZE)
- ) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN WHILE */
复制代码
结果验证【显示了2组数据】:
![]()
最后还提醒下,如果CubeMx版本比较低时,HAL_PWREx_EnableVddA()函数需要自己手动添加。我目前CubeMx 6.9.0版本已经不用手动添加了,创建工程时会将其自动生成于相应位置。
如有侵权请联系删除
|