
本帖最后由 sasmike 于 2015-1-8 16:00 编辑 - a8 o T% E' e+ a- P2 h 最近学习了STM32F0芯片,写了一个DMA控制ADC采样程序,给大家分享一下。还是新手,希望大家多提宝贵意见 ![]() 程序在STM32F051上面测试的 基本内容是: 1、使用ADC1的11通道每1us采集一次ADC数值) \+ F% v: w8 `) Z @9 S$ a 2、使用DMA1的1通道对采集数据自动存储,共采集1000个数据 3、每次采集1000次数据后,在主函数中对1000次数据进行求平均值 4、由串口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 ------------------------------------------------------------*/ #define ADC_DR_Address 0x400124405 Z( X5 C& M* Q& A! B! ] #define ADC_BUFFER_SIZE 10009 |' `& P9 B W) x, m' I /* Private macro -------------------------------------------------------------*/ /* 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; __IO uint16_t ADC_ConvertedData; __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); int 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(); printf("This is a ADC DMA Demo...\n"); ADC_DMA_Config();' ^+ l C, E: Z0 b0 A$ z* h /* Infinite loop */ while (1) {! _/ |" U; ?$ c ADC_StartOfConversion(ADC1); , A' t7 N- t, y# w% B3 K while ((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == RESET) { } ADC_StopOfConversion(ADC1); 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; 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 } 2 r! w- W7 N& n( A0 k ADC_ConvertedData = ADC_ConvertedData_Sum / ADC_BUFFER_SIZE; ADC_ConvertedVoltage = (float)(ADC_ConvertedData * 2980) / 0xFFF + 0.5;3 s- A. r( \ u4 V; ]6 n' E; s7 @ printf("------------------------------------\n"); 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 } } void ADC_DMA_Config(void) { GPIO_InitTypeDef GPIO_InitStructure;) @- N% v3 N/ q: z0 {( R ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure; ADC_DeInit(ADC1); 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); GPIO_DeInit(GPIOC); GPIO_StructInit(&GPIO_InitStructure);* W; D) x6 O: Q% ~4 H* ~7 u GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;- z% [$ j# w6 p7 M, E0 X a- q GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); 1 Z$ u. t3 q2 f2 |6 G' _ DMA_DeInit(DMA1_Channel1); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_DR_Address; 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; 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; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure);( u6 \0 N% ]8 L0 u/ x. U " E* e& P0 o: O, } ^ DMA_Cmd(DMA1_Channel1, ENABLE); ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);: `# P" }! A. D1 b* {, E* ` 3 }' ~* f1 t' r! C ADC_DMACmd(ADC1, ENABLE); + 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; ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_Init(ADC1,&ADC_InitStructure);2 _! _4 y1 y! { ADC_ChannelConfig(ADC1, ADC_Channel_11, ADC_SampleTime_239_5Cycles); 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); while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)). f) H& J% U7 L; U! g { }4 f# v: i* C- d' \6 j3 E4 I; M }8 `& `9 Q2 S( `4 c5 r7 Y0 R, O% b 最后附上源程序: ![]() |
楼主能否解释一下DMA配置的部分,刚学,总是整不好。
DMA_DeInit(DMA1_Channel1);
DMA_StructInit(&DMA_InitStructure);
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;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = ADC_BUFFER_SIZE;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
能用上就好,多交流啊
以前用的标准库用多了,这个还没有仔细研究
共同学习