| 
 
| DMA方式3通道AD转换 : 代码如下:
 
 #include <adcc.h>
 #include <stm32f4xx_adc.h>
 #include <stm32f4xx.h>
 void Init_adc(void){
 ADC_InitTypeDef ADC_InitStruct;
 ADC_CommonInitTypeDef ADC_CommonInitTStruct;
 GPIO_InitTypeDef GPIO_InitTStruct;
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
 GPIO_InitTStruct.GPIO_Mode=GPIO_Mode_AN;
 GPIO_InitTStruct.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_4|GPIO_Pin_6;
 GPIO_InitTStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
 GPIO_Init(GPIOA,&GPIO_InitTStruct);                                  //配置 &nbspA5 &nbspA4 &nbspA6 为  模拟输入
 
 ADC_CommonInitTStruct.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled; //DMA模式禁止
 ADC_CommonInitTStruct.ADC_Mode=ADC_Mode_Independent;         // ADC独立 模式
 ADC_CommonInitTStruct.ADC_Prescaler=ADC_Prescaler_Div4;  // //分频系数
 ADC_CommonInitTStruct.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;//两个采样阶段的延时周期数
 ADC_CommonInit(&ADC_CommonInitTStruct);                      // 配置 ADC 时钟 模式
 
 ADC_InitStruct.ADC_ContinuousConvMode=ENABLE;                //连续转换
 ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;   //右对齐
 ADC_InitStruct.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;
 ADC_InitStruct.ADC_NbrOfConversion=3;               // 2个转换在规则序列中
 ADC_InitStruct.ADC_Resolution=ADC_Resolution_12b;  // 12位 转换模式
 ADC_InitStruct.ADC_ScanConvMode=ENABLE;                       //扫描模式
 ADC_Init(ADC1,&ADC_InitStruct);                                 //配置
 //        ADC_Cmd(ADC1,ENABLE);                                                              // 使能 ADC转换
 }
 u32 data2[4];
 void INit_dma(void){
 DMA_InitTypeDef       DMA_InitStructure;
 Init_adc();
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);  //开启外设时钟
 DMA_InitStructure.DMA_Channel = DMA_Channel_0; //设置DMA通道
 DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_BASE+0x4C;; //外设的地址
 DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)data2;  //数据内存的地址
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;  //读取数据的模式是从外设到内存
 DMA_InitStructure.DMA_BufferSize = 3;                  //有  3个转换通道, ADC 采集3次
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址不变
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;    //内存地址增长
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //数据宽度为 16 位
 DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word;                   //数据宽度为 32 位         只有这样才不会错位//如果数据宽度为 16 位将u32data2改成u16
 DMA_InitStructure.DMA_Mode =  DMA_Mode_Circular   ;  //循环转换
 DMA_InitStructure.DMA_Priority = DMA_Priority_High;  //设置DMA的优先级别
 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable ;
 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
 DMA_InitStructure.DMA_MemoryBurst =  DMA_MemoryBurst_INC4 ;  //内存地址增长的方式
 DMA_InitStructure.DMA_PeripheralBurst =  0 ; //外设内存增长的方式
 DMA_Init(DMA2_Stream0, &DMA_InitStructure);    //配置
 DMA_Cmd(DMA2_Stream0, ENABLE);               //使能 DMA
 // 转换优先级
 ADC_RegularChannelConfig(ADC1,4, 1, ADC_SampleTime_144Cycles );
 ADC_RegularChannelConfig(ADC1,5, 2, ADC_SampleTime_144Cycles );
 ADC_RegularChannelConfig(ADC1,6, 3, ADC_SampleTime_144Cycles );
 ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);  // 源数据变化时开启DMA传输
 ADC_DMACmd(ADC1, ENABLE);  //使能 ADC1 的 DMA功能
 ADC_ContinuousModeCmd(ADC1, ENABLE);       // adc连续转换模式
 ADC_Cmd(ADC1,ENABLE);                                      // 使能 ADC1
 ADC_SoftwareStartConv(ADC1);               //开始转换规则通道
 }
 
 
 
 附加:
 搞了一天都只有第一个转换的数据是正确,最后发现是红色部分有问题(原本2个数据位一样就会出错),修改就没事了。。。不过发现网上好多人都那样写也没事。我也是无语了。
 
 
 
 DMA 方式 DAC(PA4)转换 :
 
 代码如下:
 
 #include <dac.h>
 #include <stm32f4xx_dac.h>
 u32 data_dac;
 void Dac_DMA(void){
 DMA_InitTypeDef       DMA_InitStructure;
 DMA_DeInit(DMA1_Stream5); //复位
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);  //开启外设时钟
 DMA_InitStructure.DMA_Channel = DMA_Channel_7 ; //设置DMA通道
 DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)&(DAC->DHR12R1); //DHR12R1的地址
 DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)&data_dac ;  //数据内存的地址
 DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;  //读取数据的模式是从外设到内存
 DMA_InitStructure.DMA_BufferSize = 1;                  //有  1个转换通道, 采集1次
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址不变
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;    //内存地址不变
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //数据宽度为 32 位
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;                   //数据宽度为 32 位
 DMA_InitStructure.DMA_Mode =  DMA_Mode_Circular   ;  //循环转换
 DMA_InitStructure.DMA_Priority = DMA_Priority_High;  //设置DMA的优先级别
 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable ;
 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
 DMA_InitStructure.DMA_MemoryBurst =  DMA_MemoryBurst_Single ;  //内存地址不加
 DMA_InitStructure.DMA_PeripheralBurst =  0 ; //外设内存不加
 DMA_Init(DMA1_Stream5, &DMA_InitStructure);    //配置
 DMA_Cmd(DMA1_Stream5, ENABLE);               //使能 DMA
 }
 void Dac_Init(void){
 GPIO_InitTypeDef GPIO_InitTStruct;
 DAC_InitTypeDef DAC_InitStruct;
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
 GPIO_InitTStruct.GPIO_Mode=GPIO_Mode_AN;        // 模拟输入  会映射成到DA
 GPIO_InitTStruct.GPIO_Pin=GPIO_Pin_4;
 GPIO_InitTStruct.GPIO_PuPd=GPIO_PuPd_DOWN;
 GPIO_Init(GPIOA,&GPIO_InitTStruct);
 DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;// 不用波形发生器
 DAC_InitStruct.DAC_WaveGeneration=DAC_WaveGeneration_None;
 DAC_InitStruct.DAC_OutputBuffer=DAC_OutputBuffer_Disable;       //使用设置缓冲
 DAC_InitStruct.DAC_Trigger=DAC_Trigger_T2_TRGO;              // 定时器2 TRGO模式
 DAC_Init(DAC_Channel_1,&DAC_InitStruct);
 Dac_DMA();                               // DMA 配置
 DAC_Cmd(DAC_Channel_1,ENABLE);           // 使能 DA1 方式
 DAC_DMACmd(DAC_Channel_1,ENABLE);                 // 使能 DA1 DMA方式
 }
 
 void INIT_timer2(void)
 {
 TIM_TimeBaseInitTypeDef TIM_Typetim2;
 NVIC_InitTypeDef NVIC_InitTIM2;
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
 TIM_Typetim2.TIM_CounterMode=TIM_CounterMode_Up;
 TIM_Typetim2.TIM_ClockDivision =TIM_CKD_DIV1;
 TIM_Typetim2.TIM_Prescaler=8400;
 TIM_Typetim2.TIM_Period=50;
 TIM_TimeBaseInit(TIM2,&TIM_Typetim2);
 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
 NVIC_InitTIM2.NVIC_IRQChannel=TIM2_IRQn;
 NVIC_InitTIM2.NVIC_IRQChannelCmd=ENABLE;
 NVIC_InitTIM2.NVIC_IRQChannelPreemptionPriority=0x02;
 NVIC_InitTIM2.NVIC_IRQChannelSubPriority=0x02;
 NVIC_Init(&NVIC_InitTIM2);
 TIM_Cmd(TIM2,ENABLE);
 TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update); //选择更新事件作为触发输出 (TRGO)。
 | 
 |