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

【经验分享】STM32F7实现ADC采集(软件触发+轮询)

[复制链接]
STMCU小助手 发布时间:2021-12-12 22:12
基于HAL库,实现最简单ADC采集。
0 f5 Y9 e5 G9 ]# D3 P0 C第一步,使用CubeMX配置时钟。& ]' A* K' ^: p/ Z: q
202004191224273.png
# w! T% p& ?, s+ ~
, ^: o  q  _0 V1 c9 y
然后是adc的配置:
+ }6 O5 V6 O9 `7 p& l: W
/ l' U4 m7 E1 J$ i* W0 S
20200419125831989.png

4 m+ `9 T. [0 j' V1 R; z0 u, }  X
! [5 ?$ @2 \) R7 X) V% n; @. x. y将,稍微修改一下风格,并手写头文件和源文件。7 }3 \4 K6 Y% o- ^- F) `6 a% B

% }( X0 d0 h) `0 F3 J( s0 q& t# @adc.h很简单,就不说了。9 E2 D1 l; V7 B8 F1 v2 g
; R  r. v4 f# Y. V/ `. d
  1. #ifndef __ADC_H
    ! Z9 h9 W' B& N
  2. #define __ADC_H1 T/ g2 ~) W. w- b- f0 m
  3. #include "sys.h"
    ) r1 Z- v4 Q% b7 o3 O

  4. 7 H4 H5 [2 L* k. O
  5. void MY_ADC_Init(void);                                 //ADC通道初始化
    6 L/ q! s+ J' P) a# t
  6. u16  Get_Adc(void);                         //获得某个通道值
    - m  X8 b8 M+ |
  7. #endif
复制代码
1 [) o: w1 m" U7 T% b2 T
其中,MY_ADC_Init和HAL_ADC_MspInit的内容完全是根据CubeMX生成的代码写的,就改了一个变量名字。Get_Adc则简单了,当我们需要获取adc的值的时候,先HAL_ADC_Start启动ADC,然后HAL_ADC_PollForConversion等待转换完成,最后HAL_ADC_GetValue返回结果。
3 }' ^" b  i4 L, M* Y; y0 b! ]
0 G3 n. B4 B5 @8 J& z
  1. #include "adc.h"
    7 L+ k' {2 K  E# ?
  2. #include "delay.h"7 p6 j3 d. z) W% E4 s3 O3 U% n* H
  3. % i: r- B7 S/ z. H* v8 X
  4. * X1 Q8 j2 O0 Y3 s
  5. ADC_HandleTypeDef ADC1_Handler;                 //ADC句柄0 n1 w7 i3 T9 b
  6. ADC_ChannelConfTypeDef ADC1_ChanConf;       //ADC通道配置句柄; D! P8 t2 B2 T$ ]5 j" H
  7. ' e$ S+ Y4 \$ V- C
  8. % d9 _) T) o; {9 ^
  9. //初始化ADC9 p0 c. |, e% h( O# ~2 O
  10. void MY_ADC_Init(void)$ i+ _8 N- d: }5 Y" B8 F$ C
  11. {0 b6 V* g. l# A% W5 Q' _3 I
  12.     ADC1_Handler.Instance = ADC1;
    ' h4 C+ c' j' e5 E
  13.     ADC1_Handler.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; //4分频,ADCCLK=PCLK2/4=108/4=27MHZ
      X. J! z1 w  Q; R" [
  14.     ADC1_Handler.Init.Resolution = ADC_RESOLUTION_12B;           //12位模式; o1 a3 F7 d5 o! k" L
  15.     ADC1_Handler.Init.ScanConvMode = DISABLE;                    //非扫描模式9 H/ ~% ?' _4 |/ y+ l
  16.     ADC1_Handler.Init.ContinuousConvMode = DISABLE;              //关闭连续转换! i2 f/ V8 x0 {0 y; H3 ~& _
  17.     ADC1_Handler.Init.DiscontinuousConvMode = DISABLE;           //禁止不连续采样模式
    # p% w! b$ e; F( w9 T
  18.     ADC1_Handler.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; //使用软件触发- p' d, K! L! O, m7 j
  19.     ADC1_Handler.Init.ExternalTrigConv = ADC_SOFTWARE_START;     //软件触发
    2 I( o2 l; `# x) j8 e8 t" E6 p2 y( b
  20.     ADC1_Handler.Init.DataAlign = ADC_DATAALIGN_RIGHT;           //右对齐  h+ h; F8 S8 f: a+ y
  21.     ADC1_Handler.Init.NbrOfConversion = 1;                       //1个转换在规则序列中 也就是只转换规则序列19 S  T+ q; m% H0 D7 T5 j7 ~6 z
  22.     ADC1_Handler.Init.NbrOfDiscConversion = 0;                   //不连续采样通道数为0" [' I- E7 W/ q
  23.     ADC1_Handler.Init.DMAContinuousRequests = DISABLE;           //关闭DMA请求( f5 X4 z) K# T* q1 o# o
  24.     ADC1_Handler.Init.EOCSelection = DISABLE;                    //关闭EOC中断1 f' I0 W1 m% L9 I
  25.     HAL_ADC_Init(&ADC1_Handler);                                 //初始化
    8 z5 p1 _7 d; I* E0 z/ L

  26. . M3 ~; p* J. {8 m5 D1 R# o0 J4 b
  27.     ADC1_ChanConf.Channel = ADC_CHANNEL_5;                      //通道5 PA5! f. z9 H% g" T& J# e
  28.     ADC1_ChanConf.Rank = 1;                                     //1个序列! l3 U, E9 K$ k
  29.     ADC1_ChanConf.SamplingTime = ADC_SAMPLETIME_480CYCLES;      //采样时间2 N' L+ ^0 v9 F& M" F9 B& b. J- y+ \
  30.     ADC1_ChanConf.Offset = 0;
    1 }+ g; l2 j9 A2 E
  31.     HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC1_ChanConf);       //通道配置
    ' c' f0 p; n+ w! _( f3 e1 ?3 I

  32. 5 L( p. F' \6 g4 v
  33. }
      E& O' W( M! j0 X. [6 g
  34. 4 P' T, p4 [/ N; l3 O1 L+ r
  35. //ADC底层驱动,引脚配置,时钟使能5 C! ^& Y" g- o. Q4 ^1 k
  36. //此函数会被HAL_ADC_Init()调用
    $ `$ m0 P0 h. H
  37. //hadc:ADC句柄" i: X& h" b9 b7 ?
  38. void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
    " p6 G# N# a' L2 i% G
  39. {6 {1 E3 [2 K5 ?' m
  40.     GPIO_InitTypeDef GPIO_Initure;
    ! L; p) F1 Q) `2 P# L$ q- D
  41.     __HAL_RCC_ADC1_CLK_ENABLE();            //使能ADC1时钟
    3 `3 @9 M6 X, v7 [$ ^- J
  42.     __HAL_RCC_GPIOA_CLK_ENABLE();           //开启GPIOA时钟
    . ]& \( `7 S* r6 J! _8 D8 i

  43. ( h+ i. [3 V+ m
  44.     GPIO_Initure.Pin = GPIO_PIN_5;          //PA5
    5 O0 P4 {, F4 U, L0 l
  45.     GPIO_Initure.Mode = GPIO_MODE_ANALOG;   //模拟
    + b' z+ z; D- T5 n
  46.     GPIO_Initure.Pull = GPIO_NOPULL;        //不带上下拉9 X2 w& I7 v+ U' d
  47.     HAL_GPIO_Init(GPIOA, &GPIO_Initure);
    4 j& S4 Z3 i3 }3 f/ K& E; x
  48. }# @* b8 F0 ?( l7 c2 k' a6 l" S
  49. : n& R; J: E7 `; D8 X- z
  50. //获得ADC值1 s( g7 X8 |  d, B0 v; l+ y7 L2 r
  51. //ch: 通道值 0~16,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16, T" E- t! r9 q
  52. //返回值:转换结果
    0 M, |/ C, D4 d. j
  53. u16 Get_Adc()' ^, S" a0 ^  ]* U2 y
  54. {; u1 U  f5 i9 f" e0 h5 Q8 V( r1 d
  55.     HAL_ADC_Start(&ADC1_Handler);                               //开启ADC
    - K$ h: S5 w/ q0 u' p9 i3 h; {- c
  56.     HAL_ADC_PollForConversion(&ADC1_Handler, 10);               //轮询转换+ k& F% [: Q9 m! w/ h4 o) ~# p
  57.     return (u16)HAL_ADC_GetValue(&ADC1_Handler);                //返回最近一次ADC1规则组的转换结果
    6 u- }5 ]( A6 M- X0 F
  58. }
复制代码
$ ?& r- h0 v0 X0 d  A$ A7 ?
main.c中,主函数初始化之后,直接读取adc的值,并打印。
4 F' u9 [4 U) \, R
5 b1 l; E7 l, J: _6 R2 {1 \' \1 a& \
  1. #include "sys.h"
    5 [6 R' M# ^8 I
  2. #include "delay.h"& {' d( c/ }" L! p' u, d) I- @2 c
  3. #include "usart.h"- w5 X4 F  {( S( s' ?
  4. #include "adc.h"# W# u! v) W$ S9 L- u
  5. , {6 n! c& ~3 F8 x
  6. int main(void)# C8 i) G! r3 }% g. L! h
  7. {
    / i, f4 i# T0 L) A( Z. S! r
  8.     u16 adcx;
    8 a7 a; g; u; l0 _0 I3 x* H
  9.     Cache_Enable();                 //打开L1-Cache( J- T' x/ C" f- {& U
  10.     HAL_Init();                     //初始化HAL库
    & ]4 @) m- P7 e. S: L0 K5 I
  11.     Stm32_Clock_Init(432, 8, 2, 9); //设置时钟,216Mhz
    $ P1 n; o* s3 J! B' I- m' T" ~/ o
  12.     delay_init(216);                //延时初始化
    ! l7 E# s+ n2 F! |8 @6 g
  13.     uart_init(115200);              //串口初始化
    . T: U- Z2 x! }8 b: \; p
  14.     MY_ADC_Init();                  //初始化ADC1通道5
    4 x# }) z2 X% t" F% X& G3 v( `% ~
  15.         
    : X" [; L4 k3 T* }# O, c
  16.     while (1)6 l. Z# {$ T$ n- e: O1 i
  17.     {6 N* }3 ?/ d4 M
  18.         adcx = Get_Adc(); //获取通道5的转换值,20次取平均
    ( b  G0 M5 z# I1 \9 x$ V
  19.         printf("%d\r\n", adcx);, B1 o" a( n  L+ x
  20.         delay_ms(250);
    1 d! ?4 |7 R  a- @( G
  21.     }
    2 N+ n! B* @* ^$ u% f
  22. }
复制代码

( C+ T! o# G& O7 K" L+ U如果需要对多个通道进行轮询读取,可以稍微修改一下函数Get_Adc,在每次读取之前设置一下需要转换的通道:/ L7 K; I' i: R$ T8 P& t# {

, o  _# N% r6 I7 Q. `1 x. R0 D' m: o
  1. //获得ADC值
    9 X8 `- _/ e! \" p9 r2 i: f0 a
  2. //ch: 通道值 0~16,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
    * u  h5 f$ ?1 X: _
  3. //返回值:转换结果0 {+ |) C+ y( Y
  4. u16 Get_Adc(u32 ch)   
      k+ e! f& f8 q3 k& y" W
  5. {
    - t& v+ H% G0 L' O% u3 E
  6.     ADC_ChannelConfTypeDef ADC1_ChanConf;! n  U. @: u, O8 W  o* f, a) M! V

  7. + K; O; ]+ Q% e  l; F/ W: B% S
  8.     ADC1_ChanConf.Channel=ch;                                   //通道* S) w$ f# Z2 d; @+ _; C9 x
  9.     ADC1_ChanConf.Rank=1;                                       //1个序列0 i6 k- ^2 [& g$ G2 M7 P2 X
  10.     ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //采样时间% u( M+ Z/ P3 A1 s" A/ N  T( B& U; o
  11.     ADC1_ChanConf.Offset=0;                 
    & |9 c0 N- r, x. X3 d* Q- i$ h
  12.     HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //通道配置
    4 r: W: f9 d9 M5 b% s: F3 D9 R
  13.         5 l2 d" a: F. V3 S2 @* c
  14.     HAL_ADC_Start(&ADC1_Handler);                               //开启ADC
    $ q& ^# B+ F) h5 r
  15.         6 S- O3 j5 M2 o* ]5 a( {9 B! d
  16.     HAL_ADC_PollForConversion(&ADC1_Handler,10);                //轮询转换
    9 U) e# ?) _; I! x! s; B+ }

  17. 2 v6 I! H. z, i; V! p* Y
  18.         return (u16)HAL_ADC_GetValue(&ADC1_Handler);                    //返回最近一次ADC1规则组的转换结果
    * a( B+ f9 p  W0 L' t( Y: ~8 ?0 d
  19. }
    6 P3 K: w$ d; S4 k. v
复制代码
' j) X+ X3 M# j" u! m5 v4 a& ~

( \0 b8 v8 w( z% H3 g+ H) p' ~
1 V1 ~! d4 m8 Z. h; v6 f
收藏 评论0 发布时间:2021-12-12 22:12

举报

0个回答

所属标签

相似技术帖

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