需要用STM32F407,有一个12路光敏我需要用三个ADC去采集,也就是每个ADC在独立模式下去采集其中的四个光敏的电压值,然后用DMA2去转运数据,但是,这里我按照单个ADC去采集和DMA2去转运的逻辑,同样去配置另外两个ADC,但是结果却有一组ADC采集的值却上下大幅度波动,这里不知道哪里配置有问题,这里我又看三个ADC采集互不干扰,所以一直被这个问题困扰。
DMA_InitTypeDef DMA_InitStructure1;
ADC_CommonInitTypeDef ADC_CommonInitStructure1;
ADC_InitTypeDef ADC_InitStructure1;
/*DMA_InitTypeDef DMA_InitStructure2;*/
ADC_CommonInitTypeDef ADC_CommonInitStructure2;
ADC_InitTypeDef ADC_InitStructure2;
/*DMA_InitTypeDef DMA_InitStructure3;*/
ADC_CommonInitTypeDef ADC_CommonInitStructure3;
ADC_InitTypeDef ADC_InitStructure3;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
DMA_InitStructure1.DMA_Mode = DMA_Mode_Circular; //循环采集
DMA_InitStructure1.DMA_Channel = DMA_Channel_0; //通道
DMA_InitStructure1.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到内存
DMA_InitStructure1.DMA_Priority = DMA_Priority_High; //数据流优先级
DMA_InitStructure1.DMA_BufferSize = 12; //设定待传输数据通道 高16位
DMA_InitStructure1.DMA_FIFOMode = DMA_FIFOMode_Disable; //失能FIFO模式
DMA_InitStructure1.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//FIFO阈值,全部使用,由于上面失能该模式,故该设置无效
DMA_InitStructure1.DMA_Memory0BaseAddr = (uint32_t)&ADC_Value[0];
DMA_InitStructure1.DMA_MemoryBurst = DMA_MemoryBurst_Single; //ADC是直接传输,要选单次模式
DMA_InitStructure1.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //储存器数据宽度
DMA_InitStructure1.DMA_MemoryInc = DMA_MemoryInc_Enable; //地址自增 与 DMA_BufferSize 联系,1 --> 不自增
DMA_InitStructure1.DMA_PeripheralBaseAddr = (u32)&ADC1->DR; //ADC1地址基地址 + ADC1数据寄存器偏移地址
DMA_InitStructure1.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //ADC是直接传输,要选单次模式
DMA_InitStructure1.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //外设数据宽度
DMA_InitStructure1.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //无需设置为储存地址自增模式
DMA_Init(DMA2_Stream0,&DMA_InitStructure1);
DMA_Cmd(DMA2_Stream0,ENABLE);
/*DMA_InitStructure3.DMA_Mode = DMA_Mode_Circular; //循环采集
DMA_InitStructure3.DMA_Channel = DMA_Channel_2; //通道
DMA_InitStructure3.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到内存
DMA_InitStructure3.DMA_Priority = DMA_Priority_High; //数据流优先级
DMA_InitStructure3.DMA_BufferSize = 4; //设定待传输数据通道 高16位
DMA_InitStructure3.DMA_FIFOMode = DMA_FIFOMode_Disable; //失能FIFO模式
DMA_InitStructure3.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//FIFO阈值,全部使用,由于上面失能该模式,故该设置无效
DMA_InitStructure3.DMA_Memory0BaseAddr = (uint32_t)&ADC_Value[0];
DMA_InitStructure3.DMA_MemoryBurst = DMA_MemoryBurst_Single; //ADC是直接传输,要选单次模式
DMA_InitStructure3.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //储存器数据宽度
DMA_InitStructure3.DMA_MemoryInc = DMA_MemoryInc_Enable; //地址自增 与 DMA_BufferSize 联系,1 --> 不自增
DMA_InitStructure3.DMA_PeripheralBaseAddr = (u32)&ADC3->DR; //ADC1地址基地址 + ADC1数据寄存器偏移地址
DMA_InitStructure3.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //ADC是直接传输,要选单次模式
DMA_InitStructure3.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //外设数据宽度
DMA_InitStructure3.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //无需设置为储存地址自增模式
DMA_Init(DMA2_Stream1,&DMA_InitStructure3);
DMA_Cmd(DMA2_Stream1,ENABLE);
DMA_InitStructure2.DMA_Mode = DMA_Mode_Circular; //循环采集
DMA_InitStructure2.DMA_Channel = DMA_Channel_1; //通道
DMA_InitStructure2.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到内存
DMA_InitStructure2.DMA_Priority = DMA_Priority_High; //数据流优先级
DMA_InitStructure2.DMA_BufferSize = 4; //设定待传输数据通道 高16位
DMA_InitStructure2.DMA_FIFOMode = DMA_FIFOMode_Disable; //失能FIFO模式
DMA_InitStructure2.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//FIFO阈值,全部使用,由于上面失能该模式,故该设置无效
DMA_InitStructure2.DMA_Memory0BaseAddr = (uint32_t)&ADC_Value[8];
DMA_InitStructure2.DMA_MemoryBurst = DMA_MemoryBurst_Single; //ADC是直接传输,要选单次模式
DMA_InitStructure2.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //储存器数据宽度
DMA_InitStructure2.DMA_MemoryInc = DMA_MemoryInc_Enable; //地址自增 与 DMA_BufferSize 联系,1 --> 不自增
DMA_InitStructure2.DMA_PeripheralBaseAddr = (u32)&ADC2->DR; //ADC1地址基地址 + ADC1数据寄存器偏移地址
DMA_InitStructure2.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //ADC是直接传输,要选单次模式
DMA_InitStructure2.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //外设数据宽度
DMA_InitStructure2.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //无需设置为储存地址自增模式
DMA_Init(DMA2_Stream2,&DMA_InitStructure2);
DMA_Cmd(DMA2_Stream2,ENABLE);
*/
ADC_CommonInitStructure1.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_CommonInitStructure1.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //两个采样阶段之间的延迟x个时钟
ADC_CommonInitStructure1.ADC_DMAAccessMode = ADC_DMAAccessMode_1; //DMA使能(DMA传输下要设置使能)
ADC_CommonInitStructure1.ADC_Prescaler = ADC_Prescaler_Div4; //预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz
ADC_CommonInit(&ADC_CommonInitStructure1); //初始化
ADC_InitStructure1.ADC_Resolution = ADC_Resolution_12b; //12位模式
ADC_InitStructure1.ADC_ScanConvMode =ENABLE; //扫描(开启DMA传输要设置扫描)
ADC_InitStructure1.ADC_ContinuousConvMode = ENABLE; //开启连续转换(开启DMA传输要设置连续转换)
ADC_InitStructure1.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //禁止触发检测,使用软件触发
ADC_InitStructure1.ADC_DataAlign = ADC_DataAlign_Right; //右对齐
ADC_InitStructure1.ADC_NbrOfConversion = 4; //有几个通道传输就写几 (DMA传输下要设置为通道数)
ADC_Init(ADC1, &ADC_InitStructure1); //ADC初始化
ADC_CommonInitStructure2.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_CommonInitStructure2.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //两个采样阶段之间的延迟x个时钟
ADC_CommonInitStructure2.ADC_DMAAccessMode = ADC_DMAAccessMode_1; //DMA使能(DMA传输下要设置使能)
ADC_CommonInitStructure2.ADC_Prescaler = ADC_Prescaler_Div4; //预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz
ADC_CommonInit(&ADC_CommonInitStructure2); //初始化
ADC_InitStructure2.ADC_Resolution = ADC_Resolution_12b; //12位模式
ADC_InitStructure2.ADC_ScanConvMode =ENABLE; //扫描(开启DMA传输要设置扫描)
ADC_InitStructure2.ADC_ContinuousConvMode = ENABLE; //开启连续转换(开启DMA传输要设置连续转换)
ADC_InitStructure2.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //禁止触发检测,使用软件触发
ADC_InitStructure2.ADC_DataAlign = ADC_DataAlign_Right; //右对齐
ADC_InitStructure2.ADC_NbrOfConversion = 4; //有几个通道传输就写几 (DMA传输下要设置为通道数)
ADC_Init(ADC2, &ADC_InitStructure2);
ADC_CommonInitStructure3.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_CommonInitStructure3.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //两个采样阶段之间的延迟x个时钟
ADC_CommonInitStructure3.ADC_DMAAccessMode = ADC_DMAAccessMode_1; //DMA使能(DMA传输下要设置使能)
ADC_CommonInitStructure3.ADC_Prescaler = ADC_Prescaler_Div4; //预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz
ADC_CommonInit(&ADC_CommonInitStructure3); //初始化
ADC_InitStructure3.ADC_Resolution = ADC_Resolution_12b; //12位模式
ADC_InitStructure3.ADC_ScanConvMode =ENABLE; //扫描(开启DMA传输要设置扫描)
ADC_InitStructure3.ADC_ContinuousConvMode = ENABLE; //开启连续转换(开启DMA传输要设置连续转换)
ADC_InitStructure3.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //禁止触发检测,使用软件触发
ADC_InitStructure3.ADC_DataAlign = ADC_DataAlign_Right; //右对齐
ADC_InitStructure3.ADC_NbrOfConversion = 4; //有几个通道传输就写几 (DMA传输下要设置为通道数)
ADC_Init(ADC3, &ADC_InitStructure3);
ADC_RegularChannelConfig(ADC3, ADC_Channel_0, 1, ADC_SampleTime_56Cycles); //配置ADC采集通道
ADC_RegularChannelConfig(ADC3, ADC_Channel_1, 2, ADC_SampleTime_56Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_2, 3, ADC_SampleTime_56Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_3, 4,ADC_SampleTime_56Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_56Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 5, ADC_SampleTime_56Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 6, ADC_SampleTime_56Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 7, ADC_SampleTime_56Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_8, 8, ADC_SampleTime_56Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_9, 9,ADC_SampleTime_56Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_10,10, ADC_SampleTime_56Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_11,11, ADC_SampleTime_56Cycles);
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_DMARequestAfterLastTransferCmd(ADC2, ENABLE);
ADC_DMACmd(ADC2, ENABLE);
ADC_Cmd(ADC2, ENABLE);
ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);
ADC_DMACmd(ADC3, ENABLE);
ADC_Cmd(ADC3, ENABLE);
ADC_SoftwareStartConv(ADC1);
ADC_SoftwareStartConv(ADC2);
ADC_SoftwareStartConv(ADC3);
看下管脚定义,对照原理图进行检查。