STM32G474 CubeMX + CLion双重ADC交替采样实现2M+2M = 4M采样率
文章目录
前言
并非所有通道都有三重ADC的采样,笔者之前配过G474RET6,找了半天最多只有双重,没有三重。
换了H750发现也只有引脚支持三重ADC ,而F407有不知道多少引脚能够三重。怪不得那么多人买F407。
1.cube配置
都用上交替采样了,时钟就配成120M,方便后面的ADC2分频
然后引脚这边加上ADC1和ADC2
也可以不选A0做双重,选其他引脚也可以。
记得选完在左边的ADC中使能这个通道。
1.1配置下ADC
注意到这里用的定时器8,因为手头这块板子似乎TIM3有问题,没法用来做触发ADC
ADC2不用配,已经帮你同步成跟ADC1一样了
1.2接下来配置DMA
注意选全字,交替模式DMA的数据存在一个32位数组中,其中低16位是ADC1,高16位是ADC2。就随便试验下,DMA配成NOMAL。channel随便选一个。
ADC2的DMA不用配,一个DMA搬运完ADC1的就去搬运ADC2的,如果配置了那么对不起,高16位就没数据了。
1.3定时器(重要)
这边配置上2M频率,然后我们讲下之前为什么要配成12cycle。
首先明确下,cycle就是ADC时钟经过分频后的数值,也就是说,我们120M经过二分频,60M就是者的cycle。
同时,ADC双重采样,是ADC1先采样,经历了采样时间与等待时间后,再经历这个Delay between 2 sampling phases,然后轮到ADC2采样,ADC2经历采样时间与等待时间,然后就是等待下一次TIM8的上升沿到来。
所以我们知道了,这里的 Delay between 2 sampling phases 最好正好是定时器频率的两倍,也就是说
n ∗ c y c l e = 2 ∗ T I M n*cycle=2*TIM n∗cycle=2∗TIM
我们这120M/2=60M,要匹配上定时器的2M理论上需要60/15个cycle=4M,配置栏中没有,只能退而求其次选择12cycle,实际测试下来误差很小了。
2.代码编写
usart记得cube配置下,printf重定向不再赘述。
/* USER CODE BEGIN PM */
#define data_len 100//
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint32_t dmabuffer[data_len];
double adc_123[data_len*2];
uint16_t conv_done=0;//DMA传输完成标志
/* USER CODE END PV */
HAL_ADC_Start(&hadc2);
HAL_ADCEx_MultiModeStart_DMA(&hadc1,(uint32_t *)dmabuffer,data_len);
//多重adc开启,并让dma把数据搬运到dmabuffer数组中
HAL_TIM_Base_Start(&htim8);
while(!conv_done) ; //等待dma传输完成
for(int i=0;i<data_len*2;i++)
{
printf("%d,%.3f\r\n",i,adc_123[i]); //打印采样得到的值
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
conv_done=1;
int i=0,j=0;
for(i=0,j=0;j<data_len && i<data_len*2;i++)
{
adc_123[i]=(dmabuffer[j] & 0x0000FFFF)*3.3/4096 ;//取低16位ADC1的数据
i++;
adc_123[i]=((dmabuffer[j] >>16))*3.3/4096 ;//取高16位ADC2的数据
j++;
}//取出DMA传输的数据
}
用了两种写法获取高低位的值
3.结果
Delay between 2 sampling phases 的选择至关重要,如果不选好了就会出现下图的情况
两次时钟的间隔就不对了
下图为12cycle的图像
可以看到已经很漂亮了
200KHZ波,一个周期20个点,2M的adc实现了4M采样率,牺牲了硬件资源换取了采样率
Something for nothing.