ADC相关配置分为:时钟使能,GPIO配置,ADC功能配置,DMA功能配置以及定时触发的相关配置。
最终实现功能为:单个ADC,10个通道分别采集十路电压,DMA搬运,定时器触发,定时器中断中读取采集的数值。
main(void)
{
RCC_Configuration(); //时钟初始化
GPIO_Config(); //GPIO初始化
NVIC_Configuration(); //设置NVIC中断优先级
DMA_init(); //DMA传输初始化
IWDG_Init(6,2048); //看门狗 13.1 S
TIM3_Init(); //定时器初始化
TIM4_Init();
HY14432_Init(); //液晶显示初始化
Adc_Init(); //ADC初始化
delay_ms(50);
while(1)
{
SYS_Mainpage(SYS_Page_Num); //显示
DisPic((u8 *)LCD1_array);
IWDG_Feed(); //喂狗
delay_ms(2);
}
}
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//IO设置为模拟输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE ); //使能adc通道时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div4); //设置adc分频系数,72M/4=18M(不超过14M)
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //多通道
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //单次转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;
//定时器3触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 10; //顺序进行规则转化的ADC通道数目
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_7Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_7Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_7Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_7Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_7Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_7Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 7, ADC_SampleTime_7Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 8, ADC_SampleTime_7Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 9, ADC_SampleTime_7Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 10, ADC_SampleTime_7Cycles5 );
ADC_DMACmd(ADC1, ENABLE);//使能ADC1 DMA传输
ADC_Cmd(ADC1, ENABLE); //使能ADC1
ADC_ExternalTrigConvCmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1); // 使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待校准完成
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准完成
DMA_Cmd(DMA1_Channel1, ENABLE);//使能DMA
}
void DMA_init(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_DMACmd(ADC1, ENABLE);
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr =(u32) &(ADC1->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (u32) &AD_Value;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize =10;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;// DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
}
高速实时采集,必须使用DMA搬运,且定时器触发。如果单单只用DMA搬运,定时器中断中读取DMA缓存,若信号变化缓慢可能数据无异常,但实时性高的信号,如交流电网。会出现数据移位,同一时间多个通道采集的数据并不正确。