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

STM32 DMA 多通道 ADC 采集

[复制链接]
STMCU小助手 发布时间:2023-1-6 16:55

1. 本次实践目标

    a. 完成外部 ADC 的采集, 连接引脚为 PC2

    b. 完成 STM32 内置温度传感器 ADC 的采集

    c. ADC 的采集必须以 DMA 的方式工作,通过 FreeRTOS 系统中创建的一个进程读取采集结果,并打包通过网络发送至上位机


/ L+ h) r$ m# k+ e

2. 查看 datasheet

    2.1 确认 STM32 内部温度传感器 使用哪个 ADCx , 使用哪个 channel

         经确认,STM32 内部温度传感器使用 ADC1 的 channel_16。

( H0 y2 y0 K; ?2 x5 Q: D& f

20170827165319724.png


9 J4 h9 \  S4 b' \/ ~" B$ P

   2.2 查看 PC2 引脚作为 ADC 输入时,使用哪个 ADCx, 使用哪个 channel


6 H8 N2 Z! H" [. }

         经确认,STM32 的 PC2 引脚可以使用 ADC[1,2,3] 的 channel_12。

3 |4 \! K% `1 \% }% U: l5 D

20170827170131825.png

2 |' ~. |; a! |+ ?9 Q

    2.3 通过上面的分析,可以选择 ADC1,进行 DMA 多通道采集 ADC


; H/ Y- _4 R& P' _2 V

         确认,使用 STM32 的 ADC1,后需要确认使用哪个 DMAx

& B! `) _( ^& h* d9 b) L

         经过确认,ADC1 使用 DMA1

6 \7 ~# z. V; w: q/ E4 [8 r

20170827170742159.png

2 d( e& _8 D* i4 F, v4 g0 I

    2.4 确认外设的时钟源

5 Y8 F; X4 E$ M! F! E7 d/ v

          确认 ADC1 的时钟源为 APB2 时钟分枝,并且 GPIOC 的时钟源也为 APB2 时钟分枝

  N* y% d/ y( T/ M) W

20170827171400794.png

; i9 J7 s, R1 P: g

    2.5 研究 STM32 DMA 多通道采集的方法

3 c# j, d- Y3 B8 S

   2.5.1 位分辨率

- W! Q; r, d+ A4 _

   在STM32所有系列芯片中只有少部分是16位的,如:F373芯片。


) p, s+ X, X9 ]" p/ n! D, u; t: H# }

   12位分辨率意味着我们采集电压的精度可以达到:Vref /4096。


; k9 Y, Y( K1 p

   采集电压 = Vref * ADC_DR / 4096;

$ L" c/ U8 I8 ?

   Vref:参考电压

2 y. A2 R% Z- [" j

   ADC_DR:读取到ADC数据寄存器的值


2 s# O" w$ v$ V. X& }; q


7 T2 ?0 u, B7 D

   由于寄存器是32位的,在配置的时候分左对齐和右对齐,一般我们使用右对齐,也就是对低12位数据为有效数据。

3 V; |% g. ^- r& l

   2.5.2 转换模式

) f& Q: c2 [4 W( ^$ `

   A.单次和连续转换

# a+ O1 h: |* }7 v; ]# W) z; Z% m

   单次:单通道单次转换、多通道单次(分多次)转换;


8 d' r, Z. `% E- d8 p

   连续:单通道连续转换、多通道连续(循环)转换;

# t1 ^) @+ ]+ X$ f( G2 D

   B.双ADC模式


! m/ E; Q6 B  G3 A: k/ e0 P& q4 R% ?2 ^

   也就是使用到了两个ADC,比如:ADC1和ADC2同时使用也就是双ADC模式。在该模式下可以配置为如下一些模式:同步规则模式、同步注入模式、独立模式等。


. l7 Y9 p/ ?8 {) b# M2 R


" h6 _# h' S+ a

     2.5.3 引脚配置

3 ]/ s* y: j6 }: J* Y8 N- d

20170827172512722.png


* D% h6 x/ L$ J1 x+ k5 d

     2.5.4 ADC 配置


+ J- x$ S$ O, S/ {

20170827172911002.png

& I6 @0 e3 ^8 o0 M0 W

    A.初始化基本参数:

' F( d( D  a0 `; F& x0 K

    DMA_PeripheralBaseAddr = ADC1_DR_Address;

- b6 j' X0 x) }1 p" h  Y9 p; p1 _

        #define ADC1_DR_Address    ((u32)0x40012400+0x4c)

        #define ADC1_BUF_SIZE       2

        #define TOTAL_CONVERT_CH_NUM  2

2 C" S2 `+ x* {9 H$ T) R" E, [

        vu16 ADC_Buf[2];

! t' Z% z6 x' n# }

    其中 ADC1_DR_Address 可从数据手册中查得

$ ~# W$ l5 ?1 c, F5 }: Q; n

20170827175202411.png

. q/ W, a% f1 ]7 L, N+ r# V& s" V+ Z

20170827175222394.png


4 o) y* h' k5 }8 {- I" T$ `

    第一个参数 DMA_PeripheralBaseAddr 用来设置 DMA 传输的外设基地址,比如要进行ADC采集,那么外设基地址 ADC1 数据存储器 ADC1->DR 的地址,表示方法为 (u32) & ADC1->DR,当然也可以通过数据手册直接算出外设的地址。

    第二个参数 DMA_MemoryBaseAddr 为内存基地址,也就是我们存放DMA传输数据的内存地址 = (u32)ADC_Buf。

    第三个参数 DMA_DIR 设置数据传输方向,决定是从外设读取数据到内存还送从内存读取数据发送到外设,也就是外设是源地还是目的地,这里我们设置为从外设地址读取数据,所以外设是源地了,所以选择值为DMA_DIR_PeripheralSRC。

    第四个参数 DMA_BufferSize 设置一次传输数据量的大小,我们需要采集两个通道的数据 所以设置为 ADC1_BUF_SIZE

    第五个参数 DMA_PeripheralInc 设置传输数据的时候外设地址是不变还是递增。设置为DMA_PeripheralInc_Disable;

    第六个参数 DMA_MemoryInc 设置传输数据时候内存地址是否递增,由于我们是多通道采集,因此需要递增

    第七个参数 DMA_PeripheralDataSize 用来设置外设的的数据长度是为字节传输(8bits),半字传输(16bits)还是字传输(32bits),这里我们是 16 位半字传输,所以值设置为 DMA_PeripheralDataSize_HalfWord

    第八个参数 DMA_MemoryDataSize 是用来设置内存的数据长度,同样设置为半字传输 DMA_PeripheralDataSize_HalfWord。

    第九个参数 DMA_Mode用来设置DMA模式是否循环采集。

    第十个参数是设置 DMA 通道的优先级,有低,中,高,超高三种模式,这里我们设置优先级别为高级,所以值为DMA_Priority_High。因为开启多个通道,这个值非常重要。

    第十一个参数 DMA_M2M 设置是否存储到存储器模式传输设置为 DMA_M2M_Disable。


7 h4 J/ }9 J" v& ~

    工作模式:ADC_Mode = ADC_Mode_Independent;


  @9 u9 t% C; i2 v0 {$ S& G

    总共有10种,主要都是针对双ADC下使用。针对初学者这里不多描述,感兴趣的朋友可以先自行研究一下各个模式的使用。


% |, A% P( z$ k! J

) K6 Y7 M# L& s, V8 g

    浏览模式:ADC_ScanConvMode = ENABLE;

. G" R/ d5 q0 T2 s

    主要是针对多条通道而言,也就是说你是否有多条通道。


7 l  r% H! `9 V, @! o3 N4 \

    多通道:ENABLE;

2 z8 z7 ^+ G' a! K

    单通道:DISABLE;

. z+ M. W" T, K0 X5 U6 I7 _; k: L


$ x9 Q4 U* L/ I) V' z* G

    转换模式:ADC_ContinuousConvMode =ENABLE;

* x9 T' g3 J; K0 M# c( U

    这里是配置是否需要连续转换。


# \# l  F  M5 Q; t& O- \% a

    连续转换ENABLE:也就是只需要启动(触发)转换一次,后面就不用再次启动(触发)就可以连续工作了。

! V6 Q9 f& u  v8 K


& f( ~8 p) S! s$ o

    单次转换DISABLE:也就是根据一次转换完后需要再次启动(触发)才能工作。


& P1 F  t. S7 O3 h


: c" A% t! x/ a' T, e4 J" W

    触发方式:ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;


# e9 }8 r! p- w. y) Z$ U. f

    触发方式也就是使用什么方法触发ADC转换。哟定时器、外部触发、软件触发,一般常用软件触发。这里有很多种触发方式,详情可以参考其参数。


, ]6 c1 f/ u' Q: G4 `  Q


; J0 X7 K. o9 y. a2 C1 Y. w# f

    对其方式:ADC_DataAlign = ADC_DataAlign_Right;

  i( Q& h! C5 i- Y* B, w; n

    右对齐:低12位数据为有效位(常用);


6 u8 q/ Z: U8 p+ q% b  f+ x

    左对齐:高12为数据为有效位;


" }5 g& Q6 L3 V1 ~

3 S" X: C) u1 K8 y% _. F3 p8 H" K

    通道数:ADC_NbrOfChannel =TOTAL_CONVERT_CH_NUM;

, S5 ?3 b) l5 X) B  e: H

    这个参数比较简单,我们定义工作的通道数量。


1 P8 @- g1 \* A# V! ^& g$ Y


. _2 S! R; Y% d8 \6 @5 }! ?7 z

    B.设置规则组通道:


9 k$ {1 c" J% F

    ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_55Cycles5);

' \) @4 A& Y7 I9 B  z

    ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_239Cycles5);


( g8 |" V9 X  f5 p9 B6 S

    我们定义通道12的转换顺序为第1、通道16的转换顺序为第2;


& x5 l# q7 `% h, ]

    至于为什么 ADC_Channel_16 的采集周期要设置为 ADC_SampleTime_239Cycles5,是因为 STM32 的内部温度传感器要求的,现在 ADC1 的时钟源为 APB2 时钟分枝 8 分频,即 72MHz/8 = 9MHz。而要求采样周期 ≥ 17.1us, 所以 17.1 * 9 = 153.9,而最接近的也就是 ADC_SampleTime_239Cycles5

! q; a& q: W/ ^0 L4 a: m( h

20170827173635398.png


- s' t1 e% O4 L6 d

     2.5.4 读取采集结果

" [2 \- U: u3 k/ c% d! m( r! D

20170827181215133.png

7 r: r$ x9 y* i; P' [% s

转载自:xqhrs232


1 o$ o8 S3 h8 C: |2 F! f) p1 ^
: ^" i+ b% X) f4 c9 Q  \5 Z" i/ P
收藏 评论0 发布时间:2023-1-6 16:55

举报

0个回答

所属标签

相似分享

官网相关资源

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