STM32ADC同步采样

STM32ADC同步采样

本文主要讲解如何实现STM32ADC同步采样。

所需工具:

  • 开发板:STM32F103RCT6
  • STM32CubeMX
  • IDE: Keil-MDK

模式简介

同步采样可以让多个ADC同时采集它们各自的输入信号,并且保留它们之间的相位关系,这有助于更有效地捕捉信号的动态变化,特别是对于相位频率分析来说,它具有重要的应用价值。

实现方式1

STM32 的 ADC 有一种同步模式,但配置较复杂,信号处理也不直接。已经有可用的教程,写得不错,所以我就不重复造轮子了。

实现方式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开启后在开启触发

可以分为下面两步走,顺序不能乱

  1. ADC开启采样
  2. 开启定时器

注意,这里的顺序非常重要:先开启ADC采样,然后再开启定时器。如果定时器没有开启,则没有触发信号来触发ADC采样,因此两个ADC都必须等待定时器开启后才开始采样。

如果先开启定时器,即这样编写代码。

由于ADC启动顺序不同,当ADC1启动后,立即开始采样,而ADC3仍在启动过程中,导致ADC3开始采样时,ADC1已经采集了一部分点,这也就导致采集到的数据不同步,或者说没对齐。

这就好比同时开两盏灯,拉上电闸后,无论我们手速多快,分别去按两个灯的开关总归会有先后,无法做到同步;但是我们可以不拉电闸,而是先把两盏灯的开关打开,因为电闸没拉没有通电,灯泡不亮,电闸一拉下来,通电了,两盏灯便会同时亮起。此处两个ADC好比两盏灯,定时器的开启,则是电闸。

下面我们举例来理解下:

image-20230218233110588

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°。但是输入和输出信号的相位差是固定的。

image-20230219001251219

我如果先去测量输入信号,测完后,再去测量输出信号,或者先后顺序反过来便不能得到输入输出信号的相位差。只有同时对信号进行测量才能“锁存”住两个信号的相位差。

如下图所示,无论是在T1时间段还是T2时间段同步采集,两个信号的相位差是固定的,均是45°。试想如果不同步采样会是如何呢?显然T1时间段的输入信号和T2时间段的输出信号信号相位差就是不“稳定”的,取决于两个时间段之间的时间间隔,不是输入输出本身的45°相位差。

image-20230219002227000

同步采样把相位信息“锁存”到了单片机里面。下面就可以采用各种方式,比如FFT变换等分析信号之间的相位相位差了。如果没有同步,相位信息就“丢失”了,无论使用什么方法,都无法计算信号的相位差。

如果理解不了,好好做下练习1,实践感受一下,我相信你可以懂的。

练习

  1. 用信号发生器产生两个相差30°、45°、90°的信号,让单片机分别去采集,打印导VOFA上,观察波形的相位差。每一个信号都多测几次,好好体会下博客中讲解的同步采样的作用。
  2. 有F4、H7的可以尝试开启三个ADC的同步采样。

后记

配套工程:

电赛培训资料: 整理了电赛培训过程中的例程代码 - Gitee.com

更新日志:

2023-2-18:修改了文中的错别字和语句不通顺的地方,增加了例子来说明不按照顺序开启定时器,产生的数据偏移。对“同步采样的作用”进行了更加详尽的描述。
2023-4-19:增加了电闸同时开灯的类比。

  • 52
    点赞
  • 227
    收藏
    觉得还不错? 一键收藏
  • 29
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值