STM32 一通道单次转换
之前弄过ADC连续转换,还配了DMA传输,项目上不希望这样做,因为有其他设备用到DMA传输,就会不停的抢占优先级,效率低。
按照需求改成ADC单次转换,非连续,用的时候只需调下函数执行一次转换即可。
GPIO配置:
1 /**********************************************************************************************/ 2 //ADC 配置 3 //PA3 - ADC123_IN3 可以使用ADC1的通道3、ADC2的通道3或ADC3的通道3,这里选择ADC1 4 //单通道和多通道转换时需修改几个地方 5 //ADC_InitStructure.ADC_NbrOfConversion = N;//N=1.2.3...N=1时,1个转换通道,N=2,2个通道连续转换 6 //ADC_InitStructure.ADC_ScanConvMode = DISABLE单通道扫描,ENABLE多通道扫描 7 //The total conversion time:Tconv = Sampling time + 12 cycles(固定值) 8 //Tconv = (ADC_SampleTime_84Cycles + 12) * ADCCLK = (84+12) * 1/15 = 6.4us ,ADCCLK = ADC_Prescaler_Div4 = 60M/4 = 15M 9 /*********************************************************************************************/ 10 #include "ADC_DMA.h" 11 #define SIZE 1 12 #define ADC1_DR_Address ((u32)0x4001204C) //外设地址 13 14 void ADC_Config(void) 15 { 16 GPIO_InitTypeDef GPIO_InitStructure; 17 ADC_InitTypeDef ADC_InitStructure; 18 ADC_CommonInitTypeDef ADC_CommonInitStructure; 19 20 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 21 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); 22 23 /* Configure ADC1 Channel 3 (PA3)pin as analog input ******************************/ 24 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; 25 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; 26 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; 27 GPIO_Init(GPIOA, &GPIO_InitStructure); 28 29 /* ADC Common Init **********************************************************/ 30 ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; 31 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; //60M/4=15M max value is 30MHz 32 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; 33 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; 34 ADC_CommonInit(&ADC_CommonInitStructure); 35 36 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12bit 37 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //扫描模式 38 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //非连续转换 39 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //软件触发 40 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐 41 ADC_InitStructure.ADC_NbrOfConversion = SIZE; //通道数量 42 ADC_Init(ADC1, &ADC_InitStructure); 43 44 // The total conversion time:Tconv = Sampling time + 12 cycles(固定值) 45 // Tconv = (84 + 12) * ADCCLK = 96 * 1/15 = 6.4us ,ADCCLK = ADC_Prescaler_Div4 = 60M/4 = 15M 46 ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_84Cycles); //采样时间,时间越长,数据越稳定 47 // ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); /* Enable DMA request after last transfer (Single-ADC mode) */ 48 // ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 DMA */ 49 // ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 */ 50 51 }
单次转换函数:
1 /****************************************************/ 2 //参数: number,转换次数 3 //功能: 获取ADC单次转换累加后的均值 4 //返回值:ADC转换后的均值 5 /****************************************************/ 6 uint16_t Get_ADC_Convert_Average_Result(uint8_t number) 7 { 8 uint8_t i = number; 9 uint16_t adc_ConversionValue = 0; 10 11 while(i--) 12 { 13 ADC_Cmd(ADC1, ENABLE); 14 ADC_ClearFlag(ADC1, ADC_FLAG_EOC); 15 ADC_SoftwareStartConv(ADC1); 16 while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)); 17 adc_ConversionValue += ADC_GetConversionValue(ADC1); 18 ADC_Cmd(ADC1, DISABLE); 19 } 20 21 adc_ConversionValue = adc_ConversionValue/number; 22 return adc_ConversionValue; 23 }
获得转换值后,在进行数据转换,转换电压形式格式:
1 uint16_t ADC_Value = Get_ADC_Convert_Average_Result(ADC_Convert_Number); 2 float adc_voltage_value = (ADC_Value/4096.0)*3.3; 3 printf("ADC_value = %d ,V = %4.4fV \r\n",ADC_Value,adc_voltage_value);
经测试OK,已放置在项目上使用。