|
双重 ADC 模式: 在 ADC1 或 ADC2 转换事件结束时: ● 会生成一个 32 位 DMA 传输请求(如果 ADC_CCR 寄存器中的 DMA[1:0] 位等于& L- y7 C( z, j, C) h 0b10)。此请求会将存储在 ADC_CDR 32 位寄存器高位半字中的 ADC2 转换数据传输 到 SRAM,然后将存储在 ADC_CCR 低位半字中的 ADC1 转换数据传输到 SRAM。) r# g" r2 }. k ● 当 ADC1/ADC2 的规则通道全部完成转换后,会生成一个 EOC 中断(如果已在两个 ADC+ l w6 x) c# B. k/ w 接口中的一个接口上使能)。 转换示意图:0 k! f5 q0 \2 l C* m( W i* s4 R# G; U" B9 H2 p6 d" x 转æ¢ç¤ºæå¾
/ E, Z- b2 E& b( P 配置代码: $ m% e0 c" V# W4 P8 S #define ADC_CDR_ADDRESS ((uint32_t)0x40012308) //适用于双重和三重模式的 ADC 通用规则数据寄存器( ADC_CDR), y% I9 X; q7 p( o5 j& ~ 4 D5 p" [+ e% m; ^: Y % K/ B) _2 N+ ` void Init_ADC12(void)6 a" h5 V* p9 W6 ?9 q2 L. z; ~- a {8 y" r; V& v& \2 U2 W GPIO_InitTypeDef GPIO_InitStructure;2 \/ N6 z4 y1 @8 i; ~& d ADC_CommonInitTypeDef ADC_CommonInitStructure; ADC_InitTypeDef ADC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟* ?8 T5 J4 U8 Y7 o+ p( I 2 f6 R' N6 B9 O% l5 G0 O //先初始化ADC1通道 IO口2 `* X: R4 D p- r GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉& A& K: d3 Y% _ GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 5 D7 I6 L7 k* r5 O# q. o* o ' d$ n& _* r" ]; Y /*****************************************************************5 e- l4 o- v' Q6 s *************************** DMA Configuration ******************( M2 P% W. R) o/ k, P% G( p *******************************************************************/ `. L6 r8 k6 X7 B 9 i! Z3 i( c' ]( G( _( k" P . o1 p4 E. U3 w DMA_InitTypeDef DMA_InitStructure;# j+ I( u6 a8 B5 J6 M/ ~ /*首先开DMA2时钟,由407参考手册-RM0090-Reference manual% ?, ?! h' U: B *165页可知,ADC与DMA2映射,而且DMA2挂载在AHB1时钟总线上*/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); 0 t& c3 |! F, N4 Q: w DMA_DeInit(DMA2_Stream0); DMA_StructInit( &DMA_InitStructure);' F/ j, b4 _5 P# _6 G DMA_InitStructure.DMA_Channel = DMA_Channel_0; //选择Channel_08 S6 y- t( x* {1 f2 V5 B& Y DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CDR_ADDRESS; //数据传输的外设首地址,详解见上8 U' E9 Q' L% M n+ J6 a DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&adc_result; //自己定义待发送数组的首地址,要强制转换为32位 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //数据传输方向选择为内存->外设' y. B+ u j1 o+ S7 F3 x7 Q, V DMA_InitStructure.DMA_BufferSize = 2; //传输数据大小为16,单位由以下确定,大小要配合定义的数组类型和外设数据类型% _9 ~$ ^( ~* i; C0 T. v2 k DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器自动增加禁止,因为这里只用到了DR数据寄存器 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增不允许,因为只存取一个数! }1 P) }0 }# a7 y6 E& ] DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设的数据大小& g7 v! E) k+ _3 b9 j DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //这里也选Byte) B. V) O: o4 M' ]8 R8 n DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //DMA传输模式为Normal,如果为Circular,将会循环传输 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //优先级为VeryHigh DMA_InitStructure.DMA_FIFOMode=DMA_FIFOMode_Disable;; l* f; x. N2 d; f* O DMA_InitStructure.DMA_FIFOThreshold=DMA_FIFOThreshold_HalfFull;9 y" }7 k& \: _% [! r, ]1 m DMA_InitStructure.DMA_MemoryBurst=DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst=DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream0, &DMA_InitStructure);6 E: V( I: A7 W1 P 1 A# V1 X* l7 A% j // NVIC_InitTypeDef NVIC_InitStructure; // /* DMA中断配置 */3 c! n% M+ i1 }& I // NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn; //嵌套通道为DMA2_Stream0_IRQn$ b1 d1 \' Y( D7 t // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级为 1; A3 K1 `5 [$ E0 d: _" [& t // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级为 08 E- M1 A, E" s: e& O q // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能 // NVIC_Init(&NVIC_InitStructure); " y9 C6 M0 ?. ? //使能DMA2_Stream0通道, u" t" d% l3 b" z- Y! d. M DMA_Cmd(DMA2_Stream0, ENABLE);# E2 R6 D! I# g+ H7 k5 p 8 V* e4 G4 e2 ^ // /* DMA中断开 */ // DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);8 |6 `+ c& {4 e * X( B# [2 h+ C: v% N- ? /***************************************************************** *************************** ADC Configuration ******************1 J: b0 |* W2 a2 f *******************************************************************/1 }9 \5 d( X. K9 W 6 {6 N) i& ^- V8 Z, Y RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); //使能ADC2时钟2 N1 g- z/ x, b3 d* [' k 5 z, Y% |+ j' t j* p7 C ADC_DeInit();7 F% v1 [" D- g* W( d //初始化ADC Common ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟) ~2 o( O( n9 u! ^2 f ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; //DMA使能 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz % a4 C" U/ U1 D y5 x ADC_CommonInit(&ADC_CommonInitStructure);//初始化/ s: }$ g3 A( f7 d. y # t E; P0 v6 G ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式+ i. Y v: V/ J0 z2 e, ?. o& s ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式 # r% g3 M& E% t* @* Z2 l' [ ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发 d8 p7 H, T0 Q& L3 x ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐 : `# q3 U+ X* g$ F' h ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1 ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化, |; X. c% b& U( @% B ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式& B0 ~8 \4 }: q( y+ D% F* m: Q9 ` ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式 ( Y. }1 v) z$ u7 [5 q m i ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐 ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1 : a/ I$ ^6 j9 H( L! Z7 K) t ADC_Init(ADC2, &ADC_InitStructure);//ADC初始化4 p: h3 w* i. T i: P + d: f1 `7 Q" g/ W " N, g! Y% q1 G/ z" p: X# s ADC_RegularChannelConfig(ADC1, ADC_Channel_0 , 1, ADC_SampleTime_15Cycles); ! ~0 K# `& C% H. W; Y ADC_RegularChannelConfig(ADC2, ADC_Channel_1 , 1, ADC_SampleTime_15Cycles); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); ; Q, w8 j, n4 `# } /* Enable DMA request after last transfer (Multi-ADC mode) */ ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);+ R% Q6 D7 W V- o& Q! E - d+ f) h7 ]9 O f ADC_Cmd(ADC1, ENABLE);//开启AD1转换器 4 s7 y) F; x/ D% u% V ADC_Cmd(ADC2, ENABLE);//开启AD2转换器 ' I! c: b* |, b# {( H$ R |
转æ¢ç¤ºæå¾
微信公众号
手机版
! o b8 x) L$ R* V/ d4 A
内存地址自增不允许,因为只存取一个数
这句注释错了吧,明明你设置的是DMA_MemoryInc_Enable2 v3 x4 w8 M4 b- X: P" l
虽然我也不知道到底是注释错了还是代码错了
……
多看了几段,为什么注释和代码都是自相矛盾?