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

发一个STM32的MDA控制ADC采样程序

[复制链接]
sasmike 发布时间:2015-1-8 15:49
本帖最后由 sasmike 于 2015-1-8 16:00 编辑 - a8 o  T% E' e+ a- P2 h

& M6 j0 d2 R! V) I. t最近学习了STM32F0芯片,写了一个DMA控制ADC采样程序,给大家分享一下。还是新手,希望大家多提宝贵意见
. ?& x5 l; h3 x' k6 U+ F8 x. d程序在STM32F051上面测试的
: }, ?# Q- N, _% ^* Z基本内容是:
. G' f- Z# U9 ]4 Q) P1、使用ADC1的11通道每1us采集一次ADC数值) \+ F% v: w8 `) Z  @9 S$ a
2、使用DMA1的1通道对采集数据自动存储,共采集1000个数据
# I) V$ [* D- f5 l( @3 i: R4 o3、每次采集1000次数据后,在主函数中对1000次数据进行求平均值
8 Q; U# P! ]) i6 ~- G; u4、由串口1发送到电脑串口上显示/ H( d9 v' D8 ^  B
具体程序如下:$ g2 l. i9 b! x# _& J: z7 a
#include "main.h": L/ `: Y9 ~  y# n- N4 ^# Z
/* Private typedef -----------------------------------------------------------*/1 o" [+ c: p: [( O
/* Private define ------------------------------------------------------------*/
& o+ P1 p6 V" ~2 I#define ADC_DR_Address                  0x400124405 Z( X5 C& M* Q& A! B! ]
#define ADC_BUFFER_SIZE                 1000
9 |' `& P9 B  W) x, m' I
/* Private macro -------------------------------------------------------------*/
# }: R$ f4 M; J: C' x  v/* Private variables ---------------------------------------------------------*/; O$ n  N* Z2 V" V( N2 Z  n# w
__IO uint16_t ADC_Buffer[ADC_BUFFER_SIZE];9 A3 [2 J8 K* a6 Y% d) Q
__IO uint32_t ADC_ConvertedData_Sum;
5 Y7 g; J% l5 q, h  L& k8 ]% d" O__IO uint16_t ADC_ConvertedData;
% g' L7 \; F, @5 r* L- T  c__IO uint16_t ADC_ConvertedVoltage;
9 j, K: }, e& i) v0 V
/* Private functions ---------------------------------------------------------*/! A1 a  E1 w# t2 |) L& {8 ~- x$ |6 Y
void Delay(__IO uint32_t nCount);

" l- N& D# d" b0 N% C% Y
% ]1 `1 P, y5 c1 e" v9 ~# pint main(void)3 a  w+ h, l( \+ R+ H  l1 u6 }0 `+ [
{0 S2 x* @6 j) n: t7 X
# A' Z" w3 n( {
  __IO uint16_t index;* t, v9 d3 u. L
  # p: |+ o+ _& W1 F9 F
  USART1_GPIO_Init();
* g: t7 q+ Z4 J" `* M$ p  
; L- ~9 [$ f3 H7 A7 G/ O  printf("This is a ADC DMA Demo...\n");
8 q; `0 k8 q: w4 c6 p9 f# M$ y  t* g  
/ w% {9 I( x4 C) E. P  f  ADC_DMA_Config();' ^+ l  C, E: Z0 b0 A$ z* h
  
( x7 U1 }( m3 |5 J: Y7 o  /* Infinite loop */
( m5 z2 u8 T6 v. t* M3 p9 T  d  while (1)
: d9 L! k- c. ?4 s7 t  {! _/ |" U; ?$ c
    ADC_StartOfConversion(ADC1);
) l) [0 J2 G2 `) w    , A' t7 N- t, y# w% B3 K
    while ((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == RESET)
4 `0 D+ f- z7 y( h0 s    {
! G, ^- v4 M, ]2 A3 o6 n, @    }
# k( I; t# G: B   
) y4 i) s9 Z$ P    ADC_StopOfConversion(ADC1);
9 j, O4 S+ ^/ d* K   
" |3 b  v. n* i% @! `6 H    DMA_ClearFlag(DMA1_FLAG_TC1);4 e0 @$ U. o( T% a! d5 M5 d6 f
    3 l( ^2 `- p$ R7 K4 P5 I; L
    ADC_ConvertedData_Sum = 0;
4 f+ k( T" s1 c; g! e7 ?! ^    for (index = 0; index < ADC_BUFFER_SIZE; index ++)' h( l7 e* Q' O3 x
    {" C7 L! T; i! `( g. u
      ADC_ConvertedData_Sum += ADC_Buffer[index];: b/ }+ o( Z, _8 |) m8 r6 B6 b
    }
3 I( s0 I+ b8 ~( U9 S    2 r! w- W7 N& n( A0 k
    ADC_ConvertedData = ADC_ConvertedData_Sum / ADC_BUFFER_SIZE;
1 \/ L. u4 e" m4 D" g   
4 A: O. C) f/ P* @/ W    ADC_ConvertedVoltage = (float)(ADC_ConvertedData * 2980) / 0xFFF + 0.5;3 s- A. r( \  u4 V; ]6 n' E; s7 @
    printf("------------------------------------\n");
. Y( W% O1 o! x! x    printf("ADC_ConvertedData          = %d\n", ADC_ConvertedData);% s0 d* a- k# w4 |0 u
    printf("ADC_ConvertedVoltage       = %d\n", ADC_ConvertedVoltage);) n+ |! _1 n8 d
  * |% B3 w4 n1 B0 g7 o0 ^
  Delay(5000000);, x( W  X4 ]; i. W9 U" _' V  b
  }
$ ]* }0 O# ?$ W}

) W3 K- H. g( {: x$ y9 I' w$ kvoid ADC_DMA_Config(void)
# {5 ]* {, h, T. ]7 ]( p& o6 g{
: `! z2 q$ ^) a0 v3 w2 M- U  GPIO_InitTypeDef GPIO_InitStructure;) @- N% v3 N/ q: z0 {( R
  ADC_InitTypeDef ADC_InitStructure;
% o" ?6 f+ k, I& C# q0 l7 e  DMA_InitTypeDef DMA_InitStructure;
5 F+ C, {8 m; s8 }7 V  
# v1 V1 ?- d- h4 r# I$ b  ADC_DeInit(ADC1);
2 W$ y( `( u, @. t  
  p# A$ P+ Z# A% n7 _- w- r' {  d  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);$ x1 L# g% P# A! h$ g/ `+ o& Y$ ~
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);( c8 E4 i: b" ^- N2 M: Q9 p
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
( E  A$ w& M# c  
1 }- i( a' U  L: O  GPIO_DeInit(GPIOC);
! c& w3 ~3 a+ m5 U3 a  GPIO_StructInit(&GPIO_InitStructure);* W; D) x6 O: Q% ~4 H* ~7 u
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
" g& ?. B; V& P6 O, U  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;- z% [$ j# w6 p7 M, E0 X  a- q
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
; \7 ^+ P/ N, e3 b" H8 t% {- N  GPIO_Init(GPIOC, &GPIO_InitStructure);
8 v! L2 x) s( v7 V, e3 v' G  1 Z$ u. t3 q2 f2 |6 G' _
  DMA_DeInit(DMA1_Channel1);
, b$ U/ I, g4 O  DMA_StructInit(&DMA_InitStructure);
0 _# t# p8 I! u: M  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_DR_Address;
/ _/ v0 F. J" d1 L2 b  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_Buffer;2 o  ]* t1 B( m% Q5 x
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;1 V& A/ a' f* H+ T
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;  D. u: d2 X5 r7 J% D) G) E
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;" ?- s5 O! w! t
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
! Z$ A; @0 C$ y4 {' K7 d  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;- G: O- c5 {- j2 g" m$ J1 v
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;: ?9 F/ Q# W  I7 H: e/ \
  DMA_InitStructure.DMA_BufferSize = ADC_BUFFER_SIZE;' Z/ i8 e' s0 _4 P! r+ s+ u: F
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
; }0 }8 H" J  ~# p; @  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
& A% i* @; P0 q: ?, [9 W9 s$ d  DMA_Init(DMA1_Channel1, &DMA_InitStructure);( u6 \0 N% ]8 L0 u/ x. U
  " E* e& P0 o: O, }  ^
  DMA_Cmd(DMA1_Channel1, ENABLE);
0 A. w, e" M, s: T9 A' a  
5 L9 w1 K) Q! k- J* U3 i/ \) `  ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);: `# P" }! A. D1 b* {, E* `
  3 }' ~* f1 t' r! C
  ADC_DMACmd(ADC1, ENABLE);
7 [" F8 U) x) x* b& m" a( J  + E& k% ~  t4 U4 n9 r. N& N  \; v
  ADC_StructInit(&ADC_InitStructure);* p! l2 ]* _: l  G
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;( R) c' g  f3 E! f
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;! i9 X1 i, Y1 M# O1 m8 p
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
5 U3 R5 x' Z0 [: |' n! ^1 l  ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
" d  R) o% C. L* d7 {2 C+ _  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
1 g8 H) \( q$ y+ {) z( W  ADC_Init(ADC1,&ADC_InitStructure);2 _! _4 y1 y! {
  
; D& O# R; d4 l  ADC_ChannelConfig(ADC1, ADC_Channel_11, ADC_SampleTime_239_5Cycles);
$ k. \( G; X- M" P' x, _' h7 N) Y- i- j  ADC_GetCalibrationFactor(ADC1);8 k+ l" v4 d5 E' F
  * D7 X7 k- c7 G% V. R! l" x1 J9 e2 j/ l
  ADC_Cmd(ADC1, ENABLE);
$ U4 j/ T  P$ l  
5 P8 R+ R& j7 ?  Q3 `  j6 S  while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)). f) H& J% U7 L; U! g
  {
0 A7 V# X. Z! G0 g6 Q" f, ]  }4 f# v: i* C- d' \6 j3 E4 I; M
}
8 `& `9 Q2 S( `4 c5 r7 Y0 R, O% b
最后附上源程序: STM32F0xx-ADC1000_DMA.rar (2.26 MB, 下载次数: 270)
收藏 2 评论22 发布时间:2015-1-8 15:49

举报

22个回答
mengqiqq 回答时间:2015-1-8 22:15:02
非常好!!" v  G6 X- X4 {+ X, Y1 B6 E% Z
楼主能否解释一下DMA配置的部分,刚学,总是整不好。
, I! p3 R! p' c5 M& o" @  B. \  DMA_DeInit(DMA1_Channel1);
$ n5 a" b0 V( C$ T5 r- B  DMA_StructInit(&DMA_InitStructure);
& u5 ]- }0 T) T, n- W" T+ {% B! F  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_DR_Address;( M- {* o, Y/ z: x: m
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_Buffer;  ]. R& k7 P$ [5 H/ h- F5 h
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  e& n. H6 g4 c7 G* v# _4 U7 L
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;; V$ j! q; v: G- r* i. A, k3 I
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
. Y; ]& a( ^9 W  [- ~) I4 U  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
- i6 x" f: ^& ^1 t6 }3 ~6 ?  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
0 D& A# I$ ~$ p8 a6 @, K  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  m' d; c1 j# }# [  DMA_InitStructure.DMA_BufferSize = ADC_BUFFER_SIZE;
) s8 d1 I2 k1 Y8 J  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
* l6 m/ ?( d: G9 i. ]! X  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
$ |, o) j) a. m/ q  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
nmgbtzyf 回答时间:2019-2-20 04:16:09
ADC_SampleTime_239_5Cycles,这个地方看不明白,不是应该这样吗?239.5Cycles,还有这样设置,怎么弄实现1us的速度
nmgbtzyf 回答时间:2019-2-20 04:15:41
ADC_SampleTime_239_5Cycles,这个地方看不明白,不是应该这样吗?239.5Cycles,还有这样设置,怎么弄实现1us的速度
mmo 回答时间:2015-1-8 15:54:12
学习了,谢谢分享
安雪尽 回答时间:2015-1-8 17:09:09
收藏了,谢谢楼主
dongqingchen196 回答时间:2015-1-8 20:51:01
多谢楼主分享,正要使用DMA控制ADC
STM32LEARN 回答时间:2015-1-8 21:18:29
楼主的程序很清楚啊,多谢!
sasmike 回答时间:2015-1-8 21:59:35
dongqingchen196 发表于 2015-1-8 20:51
! L. N+ ~2 X% r4 k多谢楼主分享,正要使用DMA控制ADC

  \4 A9 P5 n' W' ~9 |能用上就好,多交流啊
aderson 回答时间:2015-1-8 22:09:36
楼主也不喜欢CUBE库么。
hl1980 回答时间:2015-1-8 22:25:47
学习哈
sasmike 回答时间:2015-1-8 23:31:17
adersonl 发表于 2015-1-8 22:09
3 b) e. d% t! M* [; Q7 X$ O2 F) N楼主也不喜欢CUBE库么。
, ^, K: E" e& H& P) K$ F9 T. i
以前用的标准库用多了,这个还没有仔细研究
sasmike 回答时间:2015-1-9 09:38:09
hl1980 发表于 2015-1-8 22:25
# o4 Z& m6 c" h( P4 M学习哈

* V3 _  F. l% |) J8 u! H% w6 e共同学习
stmike 回答时间:2015-1-9 09:56:02
有点意思,对于mda不太熟悉,谢了!
naruto945 回答时间:2015-1-9 10:07:12
这个采样感觉精度不是太高啊!
nomoreheracles 回答时间:2015-1-9 10:19:41
学习了,希望代码代码更完善一些!
lkl0305 回答时间:2015-1-9 11:25:28
不错,不知精度如何?
12下一页

所属标签

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