
双重 ADC 模式: 在 ADC1 或 ADC2 转换事件结束时: ● 会生成一个 32 位 DMA 传输请求(如果 ADC_CCR 寄存器中的 DMA[1:0] 位等于: }' S8 x1 F5 R( O: x 0b10)。此请求会将存储在 ADC_CDR 32 位寄存器高位半字中的 ADC2 转换数据传输 到 SRAM,然后将存储在 ADC_CCR 低位半字中的 ADC1 转换数据传输到 SRAM。 ● 当 ADC1/ADC2 的规则通道全部完成转换后,会生成一个 EOC 中断(如果已在两个 ADC. A% Y; z* y, I& S$ q( D1 P 接口中的一个接口上使能)。 " ~ s' B( \! n, p. N+ c3 q 转换示意图:+ H/ {* }, U. ?0 O4 P0 b) l9 U . L" H6 c" Z8 S6 X7 L 转æ¢ç¤ºæå¾ ![]() 配置代码:+ x F+ ~6 j% i% Q9 L! G+ A! o$ U/ E ) K) s* c* [0 U* k N2 S6 z #define ADC_CDR_ADDRESS ((uint32_t)0x40012308) //适用于双重和三重模式的 ADC 通用规则数据寄存器( ADC_CDR) 1 N& Q3 @- z! N6 h" b# r; o5 n9 ` void Init_ADC12(void)5 _7 |0 m' N9 F# f+ y {6 E% U5 |! D& ^9 }1 S( ^; ? GPIO_InitTypeDef GPIO_InitStructure;0 l! I* |0 y) o! G ADC_CommonInitTypeDef ADC_CommonInitStructure;) w; Y0 i. s1 U0 {. S0 C' ? ADC_InitTypeDef ADC_InitStructure; 3 G# d: E9 G6 }& W) ~ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟 l, {3 X: g; `9 }2 t //先初始化ADC1通道 IO口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;;' c# d& M6 J4 h# L2 I GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉& O6 o$ G' @( X GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 2 l8 K' \3 L& R% H2 m ' z# T8 L/ c; K0 f8 N 7 H, w3 v4 D& [2 l j8 _, M /***************************************************************** *************************** DMA Configuration ******************7 D# _6 U: }' g/ q2 {8 D; p# x8 Y *******************************************************************/5 S# |# l9 c6 E% Y( s1 } 0 K: E, k% l( I2 G- x8 ?/ }6 b' M( X . R8 s# |) O, ?" b + R8 m5 g; P1 H. f& V) c$ ^ DMA_InitTypeDef DMA_InitStructure;) Y. y9 A/ K8 \# g/ f /*首先开DMA2时钟,由407参考手册-RM0090-Reference manual *165页可知,ADC与DMA2映射,而且DMA2挂载在AHB1时钟总线上*/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);6 b" k9 R r# E4 t" u3 A; D9 | $ v4 y4 P( d) g g2 I8 U DMA_DeInit(DMA2_Stream0); DMA_StructInit( &DMA_InitStructure);, _2 n7 @ a4 x, \4 s) l DMA_InitStructure.DMA_Channel = DMA_Channel_0; //选择Channel_04 t1 J- U# T: Y2 L. \ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CDR_ADDRESS; //数据传输的外设首地址,详解见上2 o7 \- b7 @: i4 x/ E9 a DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&adc_result; //自己定义待发送数组的首地址,要强制转换为32位' s' _+ @3 i, X9 P6 b DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //数据传输方向选择为内存->外设 DMA_InitStructure.DMA_BufferSize = 2; //传输数据大小为16,单位由以下确定,大小要配合定义的数组类型和外设数据类型1 q& @$ k) v. U6 X" `5 U5 r DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器自动增加禁止,因为这里只用到了DR数据寄存器9 n6 U( M; J" l9 g7 C, \ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增不允许,因为只存取一个数 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设的数据大小 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //这里也选Byte 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; DMA_InitStructure.DMA_FIFOThreshold=DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst=DMA_MemoryBurst_Single;6 U1 m# m6 ]& V: r' Z. }! ^& P DMA_InitStructure.DMA_PeripheralBurst=DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream0, &DMA_InitStructure); // NVIC_InitTypeDef NVIC_InitStructure;) y! F/ K2 s% u7 S% E% _ // /* DMA中断配置 */' X2 M9 Z+ | R // NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn; //嵌套通道为DMA2_Stream0_IRQn // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级为 1 // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级为 0" l5 \* m( z3 Y8 [ // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能 // NVIC_Init(&NVIC_InitStructure);" z6 j% | {1 Q/ ~( i$ _5 G. y+ W9 t * P( p- [# f% } //使能DMA2_Stream0通道 DMA_Cmd(DMA2_Stream0, ENABLE); // /* DMA中断开 */; R7 y; N# b' b' G // DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);+ r. J( H' G* d* ?2 D( [- t9 s5 v /***************************************************************** *************************** ADC Configuration ******************2 X: X ~+ r, s9 h# } *******************************************************************/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟8 A; _7 [0 a1 _1 { RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); //使能ADC2时钟6 V q0 e5 e. L' Z/ E 7 e9 X& L! ~% j+ e( ~8 a ADC_DeInit();7 _6 h5 k, m6 ]* d) q //初始化ADC Common ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult; M8 R8 ~8 F3 L( s' @# ^+ A ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟; P( l0 K6 b g& c% x3 O$ Y- D ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; //DMA使能 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz * ]: w5 }4 `- d6 z8 j3 a ADC_CommonInit(&ADC_CommonInitStructure);//初始化" F0 s2 A a9 e7 [9 y$ g3 J5 W # r+ s' p1 b$ D ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发1 a; o: {" W G# p; L' e, F ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐 ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1 & }; W8 m' x ~2 d+ W1 H - S' q* q$ y9 A9 n b ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式4 Q( k* l1 |$ K9 B" N ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止触发检测,使用软件触发 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐 ( X7 k# M: t, B& o3 H! i) g2 t, Q( g ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1 . A. `5 ~2 B( x8 G ADC_Init(ADC2, &ADC_InitStructure);//ADC初始化 . E* R9 [6 k! z, K. A ADC_RegularChannelConfig(ADC1, ADC_Channel_0 , 1, ADC_SampleTime_15Cycles); 9 d2 D7 p0 `* w* H! ~ ADC_RegularChannelConfig(ADC2, ADC_Channel_1 , 1, ADC_SampleTime_15Cycles); - `5 g* N L6 Z- d1 v ' @/ y# ^, W) S Y8 ~2 t+ `7 N /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); I- ^! W- J8 t1 A5 h9 [$ I7 b /* Enable DMA request after last transfer (Multi-ADC mode) */ ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE); ADC_Cmd(ADC1, ENABLE);//开启AD1转换器 6 I/ J: E+ C, N, w4 M' s K ADC_Cmd(ADC2, ENABLE);//开启AD2转换器 |
转æ¢ç¤ºæå¾
( t0 B! [* Z/ p9 m) c/ H. b( S" P& K
内存地址自增不允许,因为只存取一个数4 w- [: y( ]& l0 f2 O' e6 S$ j
这句注释错了吧,明明你设置的是DMA_MemoryInc_Enable; ]3 B- w- e2 t L8 B# Z3 s
虽然我也不知道到底是注释错了还是代码错了
……
多看了几段,为什么注释和代码都是自相矛盾?