STM32ADC同步采样
本文主要讲解如何实现STM32ADC同步采样。
所需工具:
- 开发板:STM32F103RCT6
- STM32CubeMX
- IDE: Keil-MDK
模式简介
同步采样可以让多个ADC同时采集它们各自的输入信号,并且保留它们之间的相位关系,这有助于更有效地捕捉信号的动态变化,特别是对于相位频率分析来说,它具有重要的应用价值。
实现方式1
STM32 的 ADC 有一种同步模式,但配置较复杂,信号处理也不直接。已经有可用的教程,写得不错,所以我就不重复造轮子了。
- 两个的ADC同步:STM32 进阶教程 16 - ADC1与ADC2同步采样张十三的博客的博客-CSDN博客adc同步采样
- 三个的ADC同步:STM32三个ADC同步规则采样天外飞仙CUG的博客-CSDN博客同步采样
实现方式2
有一个非常简单的思想,可以用来实现两个ADC的同步采样,即ADC1和ADC3分别进行交流采样,并且使用同一个定时器作为触发源。
编程起来非常简单,只需要先开启两个ADC采样,然后开启定时器触发,这样定时器产生的触发信号同时到达两个ADC,两个ADC在接收到触发信号后,随即同一时刻进行采样,就可以实现同步采样啦!
是否很简单?如果有思路了,就不用再看下面的内容了。下面是具体实现步骤,因为同步采样是提高的功能,一些ADC采样基础的配置,比如:基础的ADC采集交流、建立工程等操作,我就不再赘述了。(不会的话可以参考我的相关博客,写了我好久,非常非常详细)
STM32F103RCT6 的 ADC2 不支持 DMA,因此我只能演示 ADC1 和 ADC3 的同步。对于其他型号,例如 F4 和 H7,可以实现三个 ADC 的同步。
原理讲解
两个ADC可以选择同一个触发源,这样当触发源发出触发信号时,两个ADC同时接收触发,并且同时开始采样。
工程建立
ADC1的配置
ADC2的配置
定时器配置
代码编写
#define SAMP_NUM 1024 //采样点数
uint16_t ADC1_BUFF_16[SAMP_NUM]; // ADC1的数据缓冲区
uint16_t ADC3_BUFF_16[SAMP_NUM]; // ADC1的数据缓冲区
__IO uint8_t ADC_con_flag = 0;//ADC采集完成标志
和单个ADC采集交流一样。
HAL_ADCEx_Calibration_Start(&hadc1); // AD校准,f4不支持
HAL_ADCEx_Calibration_Start(&hadc3); // AD校准,f4不支持
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC1_BUFF_16, SAMP_NUM);
HAL_ADC_Start_DMA(&hadc3, (uint32_t *)ADC3_BUFF_16, SAMP_NUM);
HAL_TIM_Base_Start(&htim8);//一定要在ADC开启后在开启触发
可以分为下面两步走,顺序不能乱。
- ADC开启采样
- 开启定时器
注意,这里的顺序非常重要:先开启ADC采样,然后再开启定时器。如果定时器没有开启,则没有触发信号来触发ADC采样,因此两个ADC都必须等待定时器开启后才开始采样。
如果先开启定时器,即这样编写代码。
由于ADC启动顺序不同,当ADC1启动后,立即开始采样,而ADC3仍在启动过程中,导致ADC3开始采样时,ADC1已经采集了一部分点,这也就导致采集到的数据不同步,或者说没对齐。
这就好比同时开两盏灯,拉上电闸后,无论我们手速多快,分别去按两个灯的开关总归会有先后,无法做到同步;但是我们可以不拉电闸,而是先把两盏灯的开关打开,因为电闸没拉没有通电,灯泡不亮,电闸一拉下来,通电了,两盏灯便会同时亮起。此处两个ADC好比两盏灯,定时器的开启,则是电闸。
下面我们举例来理解下:
ADC1和ADC3都捕获同一个正弦信号的5个点,分别存储在数组A和B中。首先,启动定时器,然后先后启动ADC1和ADC3。
当启动ADC1时,它会收到定时器传来的采样触发信号,并开始采样。但是,ADC3尚未启动,因此当它被启动时,ADC1已经捕获了一个数据点,并将其存储在A[0]中。
当ADC3启动时,两个ADC开始同步采样。考虑到ADC1已经捕获了一个信号,因此会产生一个偏移。A[1]和B[0]是同步的,A[2]和B[1]也是同步的。
在这种情况下,由于已知存在一个数据点的偏差,可以忽略首位,把A[1]-A[4]和B[0]-B[3]视为有效的同步信号。实际使用中,可以测量出数据点的偏差数,再进行去头去尾的操作实现“同步”。
extern uint8_t ADC_con_flag;
ADC_con_flag = 1;
因为ADC1和ADC3是同时采集完成的。所以只需要在其中任意一个ADC的DMA的采集完成中断位置把标志位置一表示采集完成即可。我这里选择的是ADC1的DMA中断。
同步采样的作用
萌新宝宝第一次听到同步采样可能会有些困惑。下面我来介绍下这个模式有什么作用。
很多电路系统都有一套属于自己的幅频和相频曲线,这点在电分、模电等课本中都有提到,已经是常客了。
我们测量幅频的时候比较简单,测量不同频率下输入信号的幅度,再测量输出信号的幅度,两个幅度的比值就是幅频曲线。
而相位则是比较输入和输出信号的相位差来计算。输入信号的相位每一个时刻去测量都是不一样的。例如,前1ms是0°,而后1ms就是45°。但是输入和输出信号的相位差是固定的。
我如果先去测量输入信号,测完后,再去测量输出信号,或者先后顺序反过来便不能得到输入输出信号的相位差。只有同时对信号进行测量才能“锁存”住两个信号的相位差。
如下图所示,无论是在T1时间段还是T2时间段同步采集,两个信号的相位差是固定的,均是45°。试想如果不同步采样会是如何呢?显然T1时间段的输入信号和T2时间段的输出信号信号相位差就是不“稳定”的,取决于两个时间段之间的时间间隔,不是输入输出本身的45°相位差。
同步采样把相位信息“锁存”到了单片机里面。下面就可以采用各种方式,比如FFT变换等分析信号之间的相位相位差了。如果没有同步,相位信息就“丢失”了,无论使用什么方法,都无法计算信号的相位差。
如果理解不了,好好做下练习1,实践感受一下,我相信你可以懂的。
练习
- 用信号发生器产生两个相差30°、45°、90°的信号,让单片机分别去采集,打印导VOFA上,观察波形的相位差。每一个信号都多测几次,好好体会下博客中讲解的同步采样的作用。
- 有F4、H7的可以尝试开启三个ADC的同步采样。
后记
配套工程:
电赛培训资料: 整理了电赛培训过程中的例程代码 - Gitee.com
更新日志:文章来源:https://www.toymoban.com/news/detail-412802.html
2023-2-18:修改了文中的错别字和语句不通顺的地方,增加了例子来说明不按照顺序开启定时器,产生的数据偏移。对“同步采样的作用”进行了更加详尽的描述。
2023-4-19:增加了电闸同时开灯的类比。文章来源地址https://www.toymoban.com/news/detail-412802.html
到了这里,关于STM32ADC同步采样的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!