基于stm32F407ZGT6的三重ADC交替采样+DMA传输数据+定时器TRGO触发
作者:互联网
好久没写博客了,最近挺忙的。近来有些好玩的实现,网上的资料并不是非常详细,打算慢慢写下来,希望别人能少走一点弯路。 因为希望提高ADC的采样率,这次我试着实现了一下三重ADC交替采样+DMA搬运至内存+TIM的TRGO触发采样(环境是stm32cubemx 6.5.0和keil 5)
首先打开cubemx进行基础设置(设置时钟树,RCC,SYS)
然后设置ADC1(下图为具体设置,仅供参考)
此处我们将ADC_Mode设置为Triple regular simultaneous mode only,并打开DMA连续请求(为了使DMA能够填满数组,按照我们的预期工作)
外部触发源设置为TIM2的TRGO
由于已经设置了ADC模式,ADC2和ADC3是跟随ADC1的,所以他们的模式是不能改变的,和ADC1一样设置就可以了
接下来我们设置DMA,记住要设置成circular模式,不然他就只会传输一次,选择一次传输Half Word,从外设搬运到内存
主要的设置就这些,串口的初始化已经省略了,后面我们将用串口重定向打印数据至串口(详见我之前的博客串口重定向发送和接收)
现在我们只需要生成代码,打开工程
这里有个小细节:DMA和ADC的初始化顺序不能错了,要先初始化DMA再初始化ADC(其实用到DMA传输数据的外设都要在DMA初始化之后再进行初始化,因为不先初始化DMA的话,在初始化其他外设时,当配置到DMA相关的设置时会出现错乱,导致外设无法正常工作,比如ADC就会传输数据失败,但是DMA一直是处于busy状态)
下面我们进行垃圾核心代码的编写
我的初始化顺序(仅供参考)
1 MX_GPIO_Init(); 2 MX_DMA_Init(); 3 MX_ADC1_Init(); 4 MX_ADC2_Init(); 5 MX_ADC3_Init(); 6 MX_DAC_Init(); 7 MX_TIM2_Init(); 8 MX_USART1_UART_Init();
主函数当中编写的代码如下:
1 HAL_ADC_Start(&hadc1); 2 HAL_ADC_Start(&hadc2); 3 HAL_ADC_Start(&hadc3);//启动ADC 4 HAL_ADCEx_MultiModeStart_DMA(&hadc1,(uint32_t *)ADC_value,3000); 5 HAL_TIM_Base_Start(&htim2);//启动TIM2,用于触发ADC采样
对于数据的处理,我更倾向于写在回调函数里面
1 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) 2 { 3 int i; 4 for(i = 0;i < 1000;i++) 5 { 6 printf("%f,%f,%f\n",ADC_value[3 * i] * 3 / 4096.0,ADC_value[3 * i + 1] * 3 / 4096.0,ADC_value[3 * i + 2] * 3 / 4096.0); 7 } 8 return; 9 }
我们再编译,烧录程序。 至此,我们就可以实现ADC三重交替采样了
/*------------------------------------------------------------------------分割线------------------------------------------------------------------------*/
我思来想去感觉还是在回调函数里面改变一个标志位就可以了,把这么一大段处理放进去不太好,容易出现中断嵌套等我们不希望出现的现象
尽量把处理的步骤写到函数里面去执行,只需通过判断标志位即可达到同等效果
标签:DMA,stm32F407ZGT6,初始化,传输数据,Init,ADC,设置,MX 来源: https://www.cnblogs.com/Edwardssss/p/16485125.html