你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32ADC同步采样

[复制链接]
STMCU小助手 发布时间:2022-11-1 17:19
本文主要讲解如何实现STM32ADC同步采样。1 n4 O8 e* X5 F
$ {' K" s/ u# h) @$ C/ d
所需工具:
6 t" `/ `* u$ O2 t/ j! g开发板:STM32F103RCT6
5 N& A8 A7 ?$ ZSTM32CubeMX
' K7 m& q, z; q3 `+ S- d# ~IDE: Keil-MDK
% Z, ?: p9 t3 J$ ^: g7 f. X模式简介
6 \$ C4 D. D2 n- ], }+ _  V同步采样可以让两、三个ADC同时对各自的待测信号进行采样,这样就可以保留住两个信号之间的相位差。在相频分析中极具应用价值。7 j( K7 _4 ]* I4 u4 F! ~/ {! @

/ o" K4 n' ?- G实现方式16 z9 k5 M6 {8 O! Y0 o, d
STM32的ADC自带同步模式,这种方式配置有些复杂,信号处理的也不直接。已有现成的教程了,写的不错,我就不重复造轮子了。6 R- [4 C4 d: v  l4 ?/ g* W$ E
/ m9 X$ Y0 y$ `
实现方式25 I8 |! @4 ]: |# _
这种方式的核心思想非常简单,可是网上却没有发现有人写。以两个ADC的同步为例,就是ADC1、ADC3分别进行交流采样,触发源选择同一个定时器。这样在编程时,先开启两个ADC采样,再开启定时器触发,就可以实现同步采样了。/ z  x1 z; _8 K9 D- R( K
1 V+ h0 e2 q( Q; \- I# d" u
是不是非常简单?如果有思路了就不用往下看了。下面是具体的实现过程,能看这篇文章,说明你已经会基础的ADC采集交流、建立工程等操作了,一些细节我就不再赘述。(不会的话可以参考我的相关博客,写了我好久,非常非常详细)" E5 U5 U" T) `
0 x+ g" \4 E; h3 `% ]& J
STM32F103RCT6的ADC2不支持DMA,所以我只能演示ADC1、ADC3的同步。对于其他型号比如F4,H7就可以实现三个ADC同步了。不过电赛用不到3个同步,两个就够。4 \: y0 |$ D$ F# _4 s# [
% v7 _1 r6 p0 O, m3 T; \) M
原理讲解
  m5 U2 m# A: I- u
两个ADC选择同样的触发源,这样当触发源发出触发信号时,两个ADC同时接收到触发,同时开始采样。
! q$ n7 A% L2 R- r& o$ A# G! d2 V5 {
e436aaa71abb155999ee8a38802f5a73.png + v- R* Y6 B' `) X

0 }  x) o9 j/ ]' Z* W7 L9 I
# i. P5 y- c( W工程建立
, w' F& }$ }' I$ }6 OADC1的配置

5 g1 n6 Z# i  E0 C: m$ j8 F' c0 R" @  e- j' h. L1 k
22d95a7fb52d996bcb1dd0c02929ac1c.png # T# J0 g! v  }1 o, P- p% C( t
- T, @6 R6 F' j+ E1 |' B
ffcde181d695839859ee704084af47f2.png
  f$ l9 [/ d% ]; O2 W5 H# _! w- P* H2 j
ADC2的配置
' M" {- \7 P# e- A5 S" E' k% \& ~7 G: v; h- C- p
196088b1ff44a026af9069de90487782.png " \3 |9 B6 z% |1 e
* L% K6 o, }0 Z7 C
+ t8 z' h4 ^# F4 ^4 R1 n3 V
3 L5 J. m: A4 q4 Q6 d2 a
定时器配置
0 |2 G9 V% Q, e
; X8 ?6 j& l. S+ G0 T$ e% s
d260d8ce7b35f27e8f377ba9d8290399.png 8 S2 M2 d6 d4 H: I* B8 B

/ O, c; ]* j$ n% {8 `. ^: O代码编写

! y& K" U4 N* X/ z* t6 M  t
% N$ c/ i  n8 U+ Y" {9 n; P 69406e153dd4d32f312e07e6fa180fca.png
) y# v4 I: O* v! T! v* R. D: j1 f* N$ H0 Z' v4 @
  1. #define SAMP_NUM 1024 //采样点数
    1 T$ {+ j1 h: V. Q+ o
  2. # k4 s( Q7 P! l$ j' R& ^1 M
  3. uint16_t ADC1_BUFF_16[SAMP_NUM]; // ADC1的数据缓冲区- d# ]* z" a$ E0 C' m
  4. uint16_t ADC3_BUFF_16[SAMP_NUM]; // ADC1的数据缓冲区
    : o: t: v' V. j, e2 `

  5. 1 O' ^) B: e7 g4 ~' m1 N+ d% P, Q
  6. __IO uint8_t ADC_con_flag = 0;//ADC采集完成标志
复制代码
% K3 O9 {8 K7 ?: U% ?) s
和单个ADC采集交流一样。
% f2 A0 z' N6 L3 x/ H' q8 K- H4 _/ a. g  K* F
75904bd1bd618208df1313d57a990706.png * S% K7 Q0 e/ A" p+ F9 h4 \& n* F
% a$ b$ F, @) m9 @) V2 c
  1. HAL_ADCEx_Calibration_Start(&hadc1); // AD校准,f4不支持
    % `0 ~) P/ a0 W5 ]" _( B
  2. HAL_ADCEx_Calibration_Start(&hadc3); // AD校准,f4不支持
    ) l' L5 n7 v9 @8 m8 i
  3. 1 _/ S, [4 |( z/ ^' Z
  4. HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC1_BUFF_16, SAMP_NUM);3 m4 ?; \2 O1 v  r* ]; u9 z4 A3 S
  5. HAL_ADC_Start_DMA(&hadc3, (uint32_t *)ADC3_BUFF_16, SAMP_NUM);: U) Q. j4 t8 O+ N+ x0 e
  6. 2 s/ f; W8 W: K, ?. ]5 i; F" ~9 ^
  7. HAL_TIM_Base_Start(&htim8);//一定要在ADC开启后在开启触发
复制代码

& U" Y7 {0 q  y7 o5 T可以分为下面两步走,顺序不能乱。1 k/ w& t3 n, d/ l! z2 D9 u1 [
ADC开启采样
$ b0 c( I" a7 ~+ q+ Y+ q开启定时器' D5 ~0 h. M0 d2 ]" U! L
" j- `$ E8 {1 T2 l3 ]1 V' c  X
一定要注意这样顺序,因为两个ADC是分别开启的,开启的时间有先后,先开启ADC采样,因为定时器没开,就没有触发信号来触发ADC采样,这样两个ADC都在等待定时器没有开采。+ x' a" Y8 c1 u/ P

* M$ I: P1 l8 Q7 \) V! ~" V; \2 W9 v如果先开启定时器,也就是这样编写代码: o9 A4 q) w( U! X1 e1 S

% a$ v+ a! K4 W! }, f% l f65cb2f14063941386a3e87f89a604cf.png
. r) V( M' h# ^( B3 F- E+ ?3 g. ]" h# T) U/ `7 Q3 ]# u3 ~  P9 [0 C
因为ADC开启顺序不一样,当ADC1开启后,立马开始采样,这个时候ADC3正在开启,前面的个点就不在同步了。
4 f8 Z5 @4 Y$ {9 f
  S" G+ e6 w- O. O% h: T4 F 8c32efe6862b6e5f1383c17a2d894aa3.png 1 d0 }1 f& C9 _8 K
4 H8 V4 e% Q. {" O
88f00e7b4d6719fab7658afd698ff487.png 1 |. o! Y* L, I$ P$ c8 u- P

" ?0 m+ V, H! d8 H6 y  I$ W$ C+ H! A% d
  1. extern uint8_t ADC_con_flag;
    4 U: \2 |% A4 E+ c* u( y( h
  2. , S3 @' o, F; I9 V1 C
  3. ADC_con_flag = 1;
复制代码
- ?; a9 X( w5 P8 @& k) {# P
因为ADC1和ADC3是同时采集完成的。所以只需要在其中任意一个ADC的DMA的采集完成中断位置把标志位置一表示采集完成即可。我这里选择的是ADC1的DMA中断。" S, }+ V/ J; r4 T/ y- i4 N

/ K: f5 g9 e: K& U同步采样的作用
: l# A6 V6 S3 b4 D& @萌新宝宝第一次听到同步采样会有些懵。下面我来介绍下这个模式有什么作用。
0 Z4 P" t: O2 l2 N" L$ S& b3 M6 G% h. ?6 f8 s7 B( ?8 Y
很多电路系统都有一套属于自己的幅频和相频曲线,这点在电分、模电等课本中都有提到,已经是常客了。! m8 \( O# I" Y& O0 j
1 W) K4 s( R3 W, B8 ?- G3 f3 s% {
我们测量幅频的时候比较简单,测量不同频率下输入信号幅度,再测量输出信号的幅度,两个幅度一比就是幅频曲线。3 C' c7 G6 }; k1 w1 q# C

' K3 s. ?$ a0 S3 \6 X( `相位呢则是对比输入输出信号的相位差来计算。输入信号的相位每一个时刻去测量都是不一样的。前1ms还是0°。后一1ms就是45°了。但是输入与输出信号的相位差是固定的。6 Y) i- k0 B. s/ R* n$ K
5 \0 e* n5 g5 n9 q* q7 _. Q
79174b869120f4f4f0a8ae1ec7a159be.png : F& t% |8 g0 Y6 ?6 m4 `

1 \1 ~3 ^; F& N我如果先去测量输入信号,测完后,再去测量输出信号,或者先后顺序反过来,上面不同时刻测量相位不同的问题。只有同时对信号进行测量才能“锁存”住两个信号的相位差。% ?# |  a7 e6 q4 i
- h) G2 g+ J, Y- W  J! F3 x7 y* P
35ac7a06dc8c4275a82f213d3e049510.png
% U! o" J: }* m/ F+ }) I0 M: }) s6 V6 f0 u  `
无论上面时候采集,两个信号的相位差是固定的。
6 `, x& O# a: b
2 Y. v/ n5 y# _8 v8 A- D9 G 10c1a5f952b816331392c2a116bca443.png " U6 s5 S# R' H, z
6 ^" i5 f/ p6 e2 {& P
这样就把相位信息“锁存”到了单片机里面。下面就可以采用各种方式,比如FFT变换等分析信号之间的相位相位差了。如果不同步,相位信息就“丢失”了,无论有什么方法都不可能推算处来信号的相位差。8 u. |  X' t& d
4 W( F5 f- p) J6 \2 c; d: s
如果理解不了,好好做下练习1,实践感受一下,我相信你可以懂的。! Y! _! W! T: A% ~
8 t2 n* c; L# z' o  _6 F  P
练习
, z) w# N. t. I4 H8 v$ v, T2 W: `用信号发生器产生两个相差30°、45°、90°的信号,让单片机分别去采集,打印导VOFA上,观察波形的相位差。每一个信号都多测几次,好好体会下博客中讲解的同步采样的作用。
- X9 y3 r7 }& W) ^: i有F4、H7的可以尝试开启三个ADC的同步采样。
0 o; S" w) [% p. R7 O————————————————! W: @/ d9 o& N6 K+ A  l
版权声明:四臂西瓜
) M9 \: k3 \; l# D' Q. C
$ X  }* v& b* q/ o. N+ d% D; [& b! Y1 J, r
48d1f4629b6a61fbf9559a514333c882.png
收藏 评论0 发布时间:2022-11-1 17:19

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版