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

基于STM32CUBEIDE在DMA模式下扫描多个通道的ADC经验分享

[复制链接]
攻城狮Melo 发布时间:2023-6-14 11:38
概述
   本章STM32CUBEMX配置STM32F103的ADC在DMA模式扫描多个通道,通过串口进行打印。

. J, a' }+ B' z生成例程
% _1 ?) I' K. [4 U7 J+ f
   使用STM32CUBEMX生成例程,这里使用NUCLEO-F103RB开发板。
- h  E: F/ \  F' X
微信图片_20230614113232.png
4 t* `1 J3 X& D" J1 I
    查看原理图,PA2和PA3设置为开发板的串口。

" z% k  {+ v% B5 J
微信图片_20230614113235.png

5 D4 D2 V; y/ x4 \7 K
    配置串口。
6 z. P: C$ w4 N! j
微信图片_20230614113325.png

4 A: B) G4 I) {4 f
    开启中断。

6 {( V8 X* M4 L0 J, Z" b5 t
微信图片_20230614113328.png
- C1 f9 H, o* P( L
    查看原理图,Arduino的接口A0-A5都是AD口。
3 |! O, F0 O/ n: r  A9 ^
微信图片_20230614113330.png
$ G7 r, {. t3 q. ?( l% A$ r
ADC通道配置

; p1 s- k5 |3 Z6 @9 i. r- Q7 F5 \# O+ w! x" L+ a& c
微信图片_20230614113334.png
& t) k+ L9 K3 e
ADC1配置。

6 j! x3 N6 l, P7 M& u/ p
微信图片_20230614113337.png
2 p" i; x, D8 R9 u1 N7 u
● ADCs_Common_Settings:
  ○ Mode:
    Independent mod 独立 ADC 模式,当使用一个 ADC 时是独立模式,使用两个 ADC 时是双模式,在双模式下还有很多细分模式可选,具体配置 ADC_CR1UALMOD 位。
● ADC_Settings:
  ○ Data Alignment:
    Right alignment 转换结果数据右对齐,一般我们选择右对齐模式。
    Left alignment 转换结果数据左对齐。
  ○ Scan Conversion Mode:
    Disabled 禁止扫描模式。如果是单通道 AD 转换使用 DISABLE。
    Enabled 开启扫描模式。如果是多通道 AD 转换使用 ENABLE。
  ○ Continuous Conversion Mode:
    Disabled 单次转换。转换一次后停止需要手动控制才重新启动转换。
    Enabled 自动连续转换。
  ○ DiscontinuousConvMode:
    Disabled 禁止间断模式。这个在需要考虑功耗问题的产品中很有必要,也就是在某个事件触发下,开启转换。
    Enabled 开启间断模式。
● ADC_Regular_ConversionMode:
    Enable Regular Conversions 是否使能规则转换。
    Number Of Conversion ADC转换通道数目,有几个写几个就行。
    External Trigger Conversion Source 外部触发选择。这个有多个选择,一般采用软件触发方式。
● Rank:
    Channel ADC转换通道
    Sampling Time 采样周期选择,采样周期越短,ADC 转换数据输出周期就越短但数据精度也越低,采样周期越长,ADC 转换数据输出周期就越长同时数据精度越高。
● ADC_Injected_ConversionMode:
    Enable Injected Conversions 是否使能注入转换。注入通道只有在规则通道存在时才会出现。
● WatchDog:
    Enable Analog WatchDog Mode 是否使能模拟看门狗中断。当被 ADC 转换的模拟电压低于低阈值或者高于高阈值时,就会产生中断。
   DMA开启。

1 j+ z5 R0 K' E
微信图片_20230614113340.png

' s& w: [+ J3 }2 B7 U/ Z3 w3 i
    生成独立的文件。

* I* N! ~' D  P9 ]2 t. q
微信图片_20230614113343.png
' A' C2 t$ z, i
STM32CUBEIDE配置9 C2 F/ U3 R0 J$ b" h- [
, c4 D8 T: v4 P( W5 @
微信图片_20230614113347.png

0 {7 V# [* M* ?/ y8 E
    若需要打印浮点型,需要勾选下面的选项。

1 g( Y( J- y, ]$ G1 I' z
$ x, J$ K) V$ q
微信图片_20230614113350.png
1 }0 m0 n1 D, j3 e" `! k
串口重定向
" e5 O1 F1 ~8 l! r0 _8 M: Z% F
    在main.c中,添加头文件,若不添加会出现 identifier "FILE" is undefined报错。
  1. /* USER CODE BEGIN Includes */# z( r5 `# a% a/ z9 g
  2. #include "stdio.h"
    : `7 y8 `) p' V3 w; l/ Y+ z9 I
  3. /* USER CODE END Includes */
复制代码
) @$ S' u. g8 e7 a+ U% Z
    函数声明和串口重定向:
  1. /* USER CODE BEGIN PFP */
    5 P& q) r0 A4 P& I* f
  2. #ifdef __GNUC__                  //串口重定向
    ) X% R) _" S! s) P& M
  3. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)8 m7 `) J; n5 N8 ]
  4. #else) c8 n8 r% E& k4 E! j: Z5 h0 U
  5. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    + M% W  |, Y1 l5 M
  6. #endif
    0 j3 J6 n, H4 }9 e
  7. PUTCHAR_PROTOTYPE- O- X* W& o* u
  8. {6 z; R8 i7 I. F5 _" F# ?" N+ ]* n
  9.     HAL_UART_Transmit(&huart2 , (uint8_t *)&ch, 1, 0xFFFF);/ v+ h7 r/ c' c/ `1 m9 |9 L
  10.     return ch;
    ; J( T0 }  K0 t& R' E
  11. }
    8 r4 X9 H5 W+ Q8 B+ i
  12. /* USER CODE END PFP */
复制代码
! m2 `$ Y% k1 p

  ]  X4 T7 k/ Z# Y: P7 |5 ^代码5 e6 P& q$ r- y1 ^2 v, q8 {/ ?+ c2 W/ ]& P6 i

2 o! D$ \# G+ w  ~# m
    定义变量,存放采集到的数据。
  1. /* USER CODE BEGIN 0 */
    # a5 t( @( _3 P
  2. uint8_t i;% S+ r7 d3 W, F, b: z
  3. uint16_t adc1Buf[3];//ADC1数组
    4 t4 [2 [; `4 L1 X! p, S: i4 p8 m
  4. uint16_t adc2Buf[3];//ADC2数组# J2 L2 H4 R" E  B2 d  s) ^
  5. - n2 K! N0 j; [" C7 l% u3 F: t
  6. /* USER CODE END 0 */
复制代码
/ X3 D0 h; Q. R7 f
    使能ADC传输。
  1.   /* USER CODE BEGIN 2 */
    " G4 s+ t; q- k1 L1 L1 T8 E
  2.   HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC1_Value,30);    //使用DMA传输6 E$ `+ h1 e4 c- s4 n
  3.   /* USER CODE END 2 */
复制代码
& x1 I+ h% ~+ L: g7 P- J
    主循环。
  1.   /* USER CODE BEGIN WHILE */
    : v: M# c. G3 @5 o) b
  2.   while (1)
    ) t! I% ?& _$ i( w. p0 X$ y- N
  3.   {
    & y8 Z* H$ [$ m
  4.     /* USER CODE END WHILE */- @# b) |6 e) h- V* x$ f
  5. ; y2 M5 g$ P0 P" Z8 e6 v
  6.     /* USER CODE BEGIN 3 */: p0 V- N" V' N( W# k0 f3 J& l
  7.     if(ADC1_Flag==1)& g: E& i8 o  V# s" C
  8.     {- y) S$ y3 a9 i/ h
  9.       ADC1_Flag=0;
    ' \( _9 d1 W8 |/ k9 A
  10.       ADC1_1=0;
    - Q* u' Z1 |. D$ U
  11.       ADC1_2=0;. m7 y8 \2 ~; s: Q: T, V/ G9 L! a# ^
  12.       ADC1_3=0;
    ' A. q9 O& J' t4 ~) }% F
  13.       for(i=0;i<30;)
    5 g! e( \% y+ U& L# n& b
  14.       {
    ; e2 k) `, f; J9 i7 T# \
  15.         ADC1_1+=ADC1_Value[i++];
    - n2 O! O  p+ N* v. ?6 P
  16.         ADC1_2+=ADC1_Value[i++];
    5 \. N# L0 L( J+ g
  17.         ADC1_3+=ADC1_Value[i++];
    # `! x9 E3 w$ Q) F7 W7 k# {3 `) g
  18.       }2 n7 k, Q1 d* s, s% P+ m" ~
  19.       printf("\n");
    , x% _5 g* y  K4 f/ s
  20.       printf("adc1_IN0(PA0)=%4.0d,ADC_IN0=%1.4f\r\n",ADC1_1/10,ADC1_1/10*3.3f/4096);# l8 w' Z8 z* d
  21.       printf("adc1_IN1(PA1)=%4.0d,ADC_IN1=%1.4f\r\n",ADC1_2/10,ADC1_2/10*3.3f/4096);' d* p1 A/ f% X  f$ V
  22.       printf("adc1_IN4(PA4)=%4.0d,ADC_IN2=%1.4f\r\n",ADC1_3/10,ADC1_3/10*3.3f/4096);
    6 o/ g( f0 d& m9 t$ W% E
  23.       HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC1_Value,30);    //使用DMA传输
    & s. `; A& T! t. r! }% f$ B
  24.     }" B3 x! q# U, i$ @4 Y2 ?+ p, v
  25.     HAL_Delay(1000);
    2 [4 K3 x( C- c6 Y
  26.   }
    + ?7 k# |$ Y7 v; _) y3 M
  27.   /* USER CODE END 3 */
复制代码
: g/ v, S5 {6 K! f. R. B
    ADC回调函数。
    DMA传输的时候如果读取内存片段,会有仲裁器的问题,加了一句关闭DMA的语句HAL_ADC_Stop_DMA(&hadc1);

  1. 2 \' C% V1 j& V
  2. /* USER CODE BEGIN 4 */6 r6 w6 O. e6 {' W4 r
  3. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)/ S$ U- m, Y& e2 d
  4. {5 y9 v- T" f* c$ P0 S1 V& _
  5.   if(hadc->Instance == ADC1){; _" X+ }. ~' _( R3 f$ \) v& G
  6.     ADC1_Flag=1;" x- R/ ^) ^, J% [3 t$ `) s2 z$ ^
  7.     /*
    " |% V( I6 d& }5 I- K
  8.      * DMA传输的时候如果读取内存片段,会有仲裁器的问题,加了一句关闭DMA的语. H( ^- H; C4 W" H8 q$ o5 K
  9. 7 `) `8 J+ m" y( P- u
  10.      */( `5 e+ J3 S; a/ ]& V9 `
  11.     HAL_ADC_Stop_DMA(&hadc1);& {" w3 Z1 P1 T, |+ ?6 g% |
  12.   }
    9 D! l$ A  g5 u% ?. W  T& C
  13. }3 N: _3 X9 \7 W- D2 W& E
  14. /* USER CODE END 4 */
复制代码
8 K+ k# p1 }7 ?5 Y
测试结果8 X3 Q1 ^5 }) H3 a: v
    输入固定电压进行测试。
( ?6 r4 `0 D6 B1 l7 X1 v
. L. d1 u+ t+ R+ E* k" u9 u
微信图片_20230614113352.png

  d6 S; c' s2 p8 j- d9 T9 P5 U
$ G0 e9 d7 H2 d/ h) j" A
    Normal下测试结果如下。
( S% z* u% c" p! _  ]
微信图片_20230614113355.png
7 x1 e+ S# i, ?0 o0 r; ?4 N
    若不试用关闭DMA的语句HAL_ADC_Stop_DMA(&hadc1);
    会造成数据错乱。

9 T) ?+ Q2 t: _6 D2 h
微信图片_20230614113401.png

4 \1 x+ l/ w& D- }
    Circular可以下可以一直进行采集,不需要HAL_ADC_Stop_DMA(&hadc1)都可。
  u' U3 }, Y: ~  I% ^9 J5 f9 G, |+ ^
' I8 f; x! T6 G  W0 Q* V
转载自:记帖
如有侵权请联系删除
8 ?7 W( x. ?2 ]) D& g4 t

; r$ s1 i3 O, T
微信图片_20230614113418.png
赞 收藏 评论0 发布时间:2023-6-14 11:38

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版