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

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

[复制链接]
STMCU小助手 发布时间:2021-12-12 22:12
基于HAL库,实现最简单ADC采集。& r. p* h1 K. ^: |; ?
第一步,使用CubeMX配置时钟。
3 I, F; m  B$ ]0 _: n  U  s' [
202004191224273.png

) a3 |- t" ]6 P5 g4 C
. _* A& O0 E5 B  v+ A; Y然后是adc的配置:
. Y# D+ ^! ]/ z+ p% D( p0 H* L9 b: y
20200419125831989.png

1 M8 c& j1 ~# N' ~
: D( j7 d' V- A2 @% Y+ @将,稍微修改一下风格,并手写头文件和源文件。
- `; R6 k! C, Y
: d' w" c7 |2 L) Z/ p  S7 u- eadc.h很简单,就不说了。
/ d/ \( g1 C- a; G
2 P! `/ M2 @! ?5 ]7 Q. {- q6 p1 b
  1. #ifndef __ADC_H! X4 K& e" I' k+ v
  2. #define __ADC_H1 i$ {$ ?; I9 v: {& X# r: w' c  f" @
  3. #include "sys.h"
    - Q& C% }2 b7 A6 q- X( E

  4. 3 w5 @; `# q( C1 k' s/ S. q. Q/ l
  5. void MY_ADC_Init(void);                                 //ADC通道初始化* Y$ K1 n( e" c+ R+ ]3 k4 ~
  6. u16  Get_Adc(void);                         //获得某个通道值 ( E! _6 Y' Y" p' p5 D& p3 e
  7. #endif
复制代码
4 K+ {  a% v4 `% ^" R  Y
其中,MY_ADC_Init和HAL_ADC_MspInit的内容完全是根据CubeMX生成的代码写的,就改了一个变量名字。Get_Adc则简单了,当我们需要获取adc的值的时候,先HAL_ADC_Start启动ADC,然后HAL_ADC_PollForConversion等待转换完成,最后HAL_ADC_GetValue返回结果。
4 @! p7 `% v" G# x: ~& P+ n0 x! _- X) \$ \6 T: G5 }
  1. #include "adc.h"0 j6 ~5 Q1 W# Z% N4 |* @3 e
  2. #include "delay.h"
    , C- ]- t: X3 P. d2 g
  3. & a  J% @1 i2 R* B

  4. / @& f9 g* v7 L& B- H6 Y4 m" k9 ^
  5. ADC_HandleTypeDef ADC1_Handler;                 //ADC句柄
    $ B! e2 M! c$ p/ g2 y) _9 J- S) q7 N
  6. ADC_ChannelConfTypeDef ADC1_ChanConf;       //ADC通道配置句柄
    ! i1 b5 @! t  X7 h& `) Q

  7. + e7 `0 H# G% Y8 G0 Z

  8. 6 y2 Q: }' B( t) l8 U4 g+ n; t
  9. //初始化ADC
    5 h4 K; b$ p# a. _* _" R. z
  10. void MY_ADC_Init(void)% E. A$ S( f$ X& Q6 a" S
  11. {
    ! `) L( J' e4 ~( U8 e
  12.     ADC1_Handler.Instance = ADC1;
    $ X- t1 X4 i3 T
  13.     ADC1_Handler.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; //4分频,ADCCLK=PCLK2/4=108/4=27MHZ  B8 X6 i, c1 L. `
  14.     ADC1_Handler.Init.Resolution = ADC_RESOLUTION_12B;           //12位模式
    6 W/ g7 Q5 e; w2 y! Q" v* K
  15.     ADC1_Handler.Init.ScanConvMode = DISABLE;                    //非扫描模式
    $ p8 {. [- \5 A
  16.     ADC1_Handler.Init.ContinuousConvMode = DISABLE;              //关闭连续转换
    0 G8 y- c! |& a$ e; C5 G
  17.     ADC1_Handler.Init.DiscontinuousConvMode = DISABLE;           //禁止不连续采样模式
    5 X' [, p# h, S2 Y; f( D: o
  18.     ADC1_Handler.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; //使用软件触发
      D3 i* ], s0 I& \
  19.     ADC1_Handler.Init.ExternalTrigConv = ADC_SOFTWARE_START;     //软件触发3 Y! B, U+ E+ |2 S8 W( \0 w/ g: Q  O
  20.     ADC1_Handler.Init.DataAlign = ADC_DATAALIGN_RIGHT;           //右对齐
    ( S+ K5 i" N! Y: l" \$ t9 K% u
  21.     ADC1_Handler.Init.NbrOfConversion = 1;                       //1个转换在规则序列中 也就是只转换规则序列1" W* r0 K, \  G% s, N
  22.     ADC1_Handler.Init.NbrOfDiscConversion = 0;                   //不连续采样通道数为0( Q- J. G% K+ B
  23.     ADC1_Handler.Init.DMAContinuousRequests = DISABLE;           //关闭DMA请求
    2 t& {, D+ T3 ]6 T3 D$ A
  24.     ADC1_Handler.Init.EOCSelection = DISABLE;                    //关闭EOC中断1 c3 Q( |) _% y8 ?
  25.     HAL_ADC_Init(&ADC1_Handler);                                 //初始化6 @' C" l% `' r' M+ t. R' @
  26. 5 m$ ^7 ?7 Q2 Z$ `1 f
  27.     ADC1_ChanConf.Channel = ADC_CHANNEL_5;                      //通道5 PA5
    * m. r  H! D) J
  28.     ADC1_ChanConf.Rank = 1;                                     //1个序列
      e4 Y. k% G" [( V# m% J
  29.     ADC1_ChanConf.SamplingTime = ADC_SAMPLETIME_480CYCLES;      //采样时间5 B. r9 l9 G, ^; L* B
  30.     ADC1_ChanConf.Offset = 0;
    - ?) A$ B2 ?" n/ j, `& M  z
  31.     HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC1_ChanConf);       //通道配置
    + r/ w0 P4 n; r6 l4 B/ T6 n9 F
  32. 6 K' M: t& Q* H$ ^7 p8 X" n' p
  33. }' ]' c# _+ [( W1 z' ]0 c
  34. 0 V- t% m( O* o9 i3 L- n0 y: z5 W2 _
  35. //ADC底层驱动,引脚配置,时钟使能
    * F) {8 @/ {2 K1 v7 R
  36. //此函数会被HAL_ADC_Init()调用/ G7 }- x$ s: N# F/ C! }
  37. //hadc:ADC句柄
    ) X" n9 V+ b. g! [/ Z
  38. void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
    " E. p0 M" v" x) s% E
  39. {* b7 ?, j7 D* R5 n
  40.     GPIO_InitTypeDef GPIO_Initure;
      _) g, z# r% i! W% s
  41.     __HAL_RCC_ADC1_CLK_ENABLE();            //使能ADC1时钟
    . r5 H2 k, a1 q7 j4 a0 a
  42.     __HAL_RCC_GPIOA_CLK_ENABLE();           //开启GPIOA时钟, V5 G! \# F5 C) x7 _

  43. ) N0 W9 @: [( r/ j1 j- _
  44.     GPIO_Initure.Pin = GPIO_PIN_5;          //PA5
    ' M' C% x6 e0 b6 x
  45.     GPIO_Initure.Mode = GPIO_MODE_ANALOG;   //模拟
    0 T9 P  i, O% F1 {" H) R
  46.     GPIO_Initure.Pull = GPIO_NOPULL;        //不带上下拉
    / |! a" d; A" \/ ]6 @& \. F1 v
  47.     HAL_GPIO_Init(GPIOA, &GPIO_Initure);9 P" ^& K$ d4 S) S+ H2 [- B
  48. }
    $ N( V3 V& A7 j, S4 B3 g
  49.   k# I3 b& b( H" a
  50. //获得ADC值  |6 h! T* V" j
  51. //ch: 通道值 0~16,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16% c+ v/ J4 S2 W5 L1 d* c0 Q6 C" V
  52. //返回值:转换结果
    $ \: a" ^% o$ G# L$ b4 l
  53. u16 Get_Adc()
    6 F& S% N, r+ h' f$ J. P
  54. {
    0 g0 x6 \: ~( j' p2 s
  55.     HAL_ADC_Start(&ADC1_Handler);                               //开启ADC
    7 v0 b9 P0 U" U) q
  56.     HAL_ADC_PollForConversion(&ADC1_Handler, 10);               //轮询转换
    ! J5 O* T( p9 Y
  57.     return (u16)HAL_ADC_GetValue(&ADC1_Handler);                //返回最近一次ADC1规则组的转换结果
    - N- x/ h) L2 m# e
  58. }
复制代码

$ C3 e+ ^3 Q1 q6 nmain.c中,主函数初始化之后,直接读取adc的值,并打印。
8 o/ E( i( K+ m/ a  k; a7 o
3 O" z4 ~2 _; t  ~2 _
  1. #include "sys.h"- q7 q! F. h7 p. f- `7 ^8 b
  2. #include "delay.h"
    + A, K/ D" l* o  N& C
  3. #include "usart.h"
    / ^  o' l1 w% ?
  4. #include "adc.h"
    : F8 W' g4 h2 ]" r  a

  5. ( {0 Y+ F, }/ s
  6. int main(void)
    3 h2 a1 h& K) H+ f) `9 P
  7. {
    0 K- ~$ [' z! |5 A0 d$ ~: S
  8.     u16 adcx;
    2 n2 m% J% Y! S  ^; a
  9.     Cache_Enable();                 //打开L1-Cache, Z& ?" Y" T( S! |0 g
  10.     HAL_Init();                     //初始化HAL库$ L1 c0 h" C( z' y6 K7 N
  11.     Stm32_Clock_Init(432, 8, 2, 9); //设置时钟,216Mhz6 E2 {' y* Z  D' m! z; x3 \
  12.     delay_init(216);                //延时初始化% [1 ?* `! ?+ C" v5 g
  13.     uart_init(115200);              //串口初始化( t8 o  [3 k0 E/ x6 x, d. A) h8 {) f7 c
  14.     MY_ADC_Init();                  //初始化ADC1通道5+ a' S/ _3 x4 M0 ~+ @% O, j
  15.         
    ' `. [- Z2 f' U3 t+ W
  16.     while (1)# |# ?4 t) f5 C; v6 Z6 v1 w
  17.     {
    9 Q7 X5 @7 u1 Q3 i* r4 r) `5 X
  18.         adcx = Get_Adc(); //获取通道5的转换值,20次取平均6 P$ y2 |* H! R+ E2 a
  19.         printf("%d\r\n", adcx);; M/ n. ^% W* r* S4 t4 |
  20.         delay_ms(250);  H. _; j0 q* K% F7 i
  21.     }& ^5 L% m" ~4 K4 @
  22. }
复制代码

7 o9 a) G- E7 Q, ]1 U- u如果需要对多个通道进行轮询读取,可以稍微修改一下函数Get_Adc,在每次读取之前设置一下需要转换的通道:, p7 w6 X/ H1 a) z; p7 y( A
3 t2 z) X% v3 |+ Y) ]8 A
  1. //获得ADC值
    $ j4 N& r1 k( B* t! O
  2. //ch: 通道值 0~16,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
    0 P3 s0 k) Z. T( D% {1 N
  3. //返回值:转换结果  Q8 J; ~0 P+ X( j3 I  a. w  u
  4. u16 Get_Adc(u32 ch)   
    5 n; i8 e& C) b& U- y& b/ l
  5. {! K5 m9 V' b: c2 A  W- G
  6.     ADC_ChannelConfTypeDef ADC1_ChanConf;
    " T+ u, ]+ K) c& N' M& |

  7. . A2 G& b8 k: D! W' O
  8.     ADC1_ChanConf.Channel=ch;                                   //通道
    * ~' [0 y  t/ s& V. i- z6 e; _
  9.     ADC1_ChanConf.Rank=1;                                       //1个序列5 @8 d: o* B3 C5 \
  10.     ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //采样时间% N) x, ]0 b8 F3 `
  11.     ADC1_ChanConf.Offset=0;                 ' C3 A# w( Z* A1 I# E6 e4 X/ C
  12.     HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //通道配置
    0 Y3 L' G; Y$ o8 N# S" W2 Z
  13.         & D8 j; x3 o2 s' V# j; T
  14.     HAL_ADC_Start(&ADC1_Handler);                               //开启ADC% s; h$ R0 X+ n* x9 ?+ F1 O5 U
  15.         ; f9 i3 k% k, a' S
  16.     HAL_ADC_PollForConversion(&ADC1_Handler,10);                //轮询转换! a# {  u9 E9 U0 C" z; f
  17. 9 S; [& E- ~% q' i( m5 e% l
  18.         return (u16)HAL_ADC_GetValue(&ADC1_Handler);                    //返回最近一次ADC1规则组的转换结果
    * ^2 n! _2 ^; Y9 E3 f& P! B- R
  19. }, G, D9 v1 I' V6 s% d! i
复制代码

" J! s% P7 U* j/ X9 m4 X
" g4 n2 G" J$ ^7 W
6 {" r9 v$ _8 O- S" y
收藏 评论0 发布时间:2021-12-12 22:12

举报

0个回答

所属标签

相似技术帖

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