第一个为非DMA模式的多通道采集 void ADC_DMA_Config(void) { ADC_InitTypeDef ADC_InitStructure;
RCC_HSICmd(ENABLE); while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); ADC_DeInit(ADC1); ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b; ADC_InitStructure.ADC_ScanConvMode = DISABLE; //禁止扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续转换 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1,&ADC_InitStructure); /*没有采用中断和DMA方式,这样采样得到的数据很容易丢失,因为规则通道公用一个数据寄存器,因此需要在一个转换周期内读出数据,紧接着读取下一个通道的数据。*/ ADC_DelaySelectionConfig(ADC1, ADC_DelayLength_Freeze);//推迟到转换后的数据被读取
ADC_PowerDownCmd(ADC1, ADC_PowerDown_Idle_Delay, ENABLE);//在延迟和空闲阶段ADC是关闭的
/* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Wait until the ADC1 is ready */ while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS) == RESET) { }
} uint16_t GetADCValue(uint32_t CH_Data )//获取通道数据 { unsigned char i; for(i=0; i<3; i++) { AD_Value[i] = 0xFF; switch (i) { case 0: ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_9Cycles); break; case 1: ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_9Cycles); break; default: ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_9Cycles); break; } ADC_Cmd(ADC1, ENABLE); // ADC_TempSensorVrefintCmd(ENABLE); ADC_SoftwareStartConv(ADC1); while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET) AD_Value[i] = ADC_GetConversionValue(ADC1); ADC_ClearFlag(ADC1, ADC_FLAG_EOC); ADC_SoftwareStartConv(ADC1); ADC_Cmd(ADC1, DISABLE); } return AD_Value[CH_Data]; }
第二个为dma多通道采样与注入采样 __IO uint16_t ADC_ConvertedValue[2];//内存缓存adc通道数据
void ADC1_Mode_Config(void) { DMA_InitTypeDef DMA_InitStructure; ADC_InitTypeDef ADC_InitStructure;
/* DMA channel1 configuration */ DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//ADC地址 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;//内存地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 2; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址固定 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址后移 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//半字 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE);
/* ADC1 configuration */ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立ADC模式 ADC_InitStructure.ADC_ScanConvMode = ENABLE ; //开扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软件触发 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 2;//转换通道数目 ADC_Init(ADC1, &ADC_InitStructure);
ADC_TempSensorVrefintCmd(ENABLE); ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 1, ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_55Cycles5);
ADC_InjectedSequencerLengthConfig(ADC1, 1); //注入通道与其长度 ADC_InjectedChannelConfig(ADC1,ADC_Channel_11,1,ADC_SampleTime_7Cycles5); // ADC_SetInjectedOffset(ADC1, ADC_InjectedChannel_1, 1000);//设置偏置电压值
ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);
ADC_ExternalTrigConvCmd(ADC1, DISABLE); //禁止外部触发 ADC_ExternalTrigInjectedConvCmd(ADC1, DISABLE); //ADC_AutoInjectedConvCmd(ADC1,ENABLE); //规则通道自动转换到注入通道 /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); ADC_SoftwareStartConvCmd(ADC1, ENABLE); }
由下面代码可以得到注入通道ad值 ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);//启动adc注入通道 while(RESET ==ADC_GetFlagStatus(ADC1,ADC_FLAG_JEOC));//等待转换完成 value=ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);//得到第一组的值
终于把ADC的非DMA的多通道采集完成,也是参考的网上的例子,学会了很多。其中要根据自己需求注意ADC是扫描模式,ADC是单次转换还是连续转换,还有ADC的模式也要注意。觉得ADC很博大精深,自己还得好好研究一番。
|