本帖最后由 爱芝麻的苹果Z 于 2019-5-31 09:13 编辑
使用STM32板载ADC,均采用差分输入模式,引脚是PA6、7和PC4、5,查手册后选择了ADC1 的3通道和ADC2的4通道,分别差分输入。
现象为:
测量值在1.2V以上时都是正确的,0-1.2V间是固定的测不准,且是周期性的出现。在1.2V、0.8V、0.4V这几个点之间出现跳变。
测负电压是对应的,也就是说测-3到-1.2V之间都是正确的,在-1.2V到0V间都是错的。
采样低电平0V高电平3V的正弦信号,结果如下:
ADC代码配置如下:
ADC_HandleTypeDef ADC1_Handler;//ADC¾ä±ú
ADC_HandleTypeDef ADC2_Handler;//ADC¾ä±ú
u8 ch_flag=0;
//3õê¼»ˉADC
//ch: ADC_channels
//í¨μàÖμ 0~16è¡Öμ·¶Î§Îa£oADC_CHANNEL_0~ADC_CHANNEL_16
void MY_ADC_Init(void)
{
//ADCÄ£ê½3õê¼»ˉ
ADC1_Handler.Instance=ADC1;
ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4; //4·ÖÆ죬ADCCLK=PER_CK/4=64/4=16MHZ
ADC1_Handler.Init.Resolution=ADC_RESOLUTION_16B; //16λÄ£ê½
ADC1_Handler.Init.ScanConvMode=DISABLE; //é¨ÃèÄ£ê½
ADC1_Handler.Init.EOCSelection=ADC_EOC_SINGLE_CONV; //1رÕEOCÖD¶ÏADC_EOC_SINGLE_CONV
ADC1_Handler.Init.LowPowerAutoWait=DISABLE; //×Ô¶ˉμí1|oÄ1رÕ
ADC1_Handler.Init.ContinuousConvMode=DISABLE; //á¬Dø×a»»
ADC1_Handler.Init.NbrOfConversion=1; //2¸ö×a»»Ôú1æÔòDòáDÖD
ADC1_Handler.Init.DiscontinuousConvMode=DISABLE; //½ûÖ12»á¬Dø2éÑùÄ£ê½
ADC1_Handler.Init.NbrOfDiscConversion=0; //2»á¬Dø2éÑùí¨μàêyÎa0
ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START; //èí¼t′¥·¢
ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE; //ê1óÃèí¼t′¥·¢
ADC1_Handler.Init.BoostMode=ENABLE; //BOOTÄ£ê½1رÕ
ADC1_Handler.Init.Overrun=ADC_OVR_DATA_OVERWRITTEN; //óDDÂμÄêy¾YμÄËàoóÖ±½ó¸2¸Çμô¾éêy¾Y
ADC1_Handler.Init.OversamplingMode=DISABLE; //1y2éÑù1رÕ
ADC1_Handler.Init.ConversionDataManagement=ADC_CONVERSIONDATA_DR; //1æÔòí¨μàμÄêy¾Y½ö½ö±£′æÔúDR¼Ä′æÆ÷àïÃæ
HAL_ADC_Init(&ADC1_Handler); //3õê¼»ˉ
HAL_ADCEx_Calibration_Start(&ADC1_Handler,ADC_CALIB_OFFSET,ADC_DIFFERENTIAL_ENDED); //ADCD£×¼
ADC2_Handler.Instance=ADC2;
ADC2_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4; //4·ÖÆ죬ADCCLK=PER_CK/4=64/4=16MHZ
ADC2_Handler.Init.Resolution=ADC_RESOLUTION_16B; //16λÄ£ê½
ADC2_Handler.Init.ScanConvMode=DISABLE; //é¨ÃèÄ£ê½
ADC2_Handler.Init.EOCSelection=ADC_EOC_SINGLE_CONV; //1رÕEOCÖD¶ÏADC_EOC_SINGLE_CONV
ADC2_Handler.Init.LowPowerAutoWait=DISABLE; //×Ô¶ˉμí1|oÄ1رÕ
ADC2_Handler.Init.ContinuousConvMode=DISABLE; //á¬Dø×a»»
ADC2_Handler.Init.NbrOfConversion=1; //2¸ö×a»»Ôú1æÔòDòáDÖD
ADC2_Handler.Init.DiscontinuousConvMode=DISABLE; //½ûÖ12»á¬Dø2éÑùÄ£ê½
ADC2_Handler.Init.NbrOfDiscConversion=0; //2»á¬Dø2éÑùí¨μàêyÎa0
ADC2_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START; //èí¼t′¥·¢
ADC2_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE; //ê1óÃèí¼t′¥·¢
ADC2_Handler.Init.BoostMode=ENABLE; //BOOTÄ£ê½1رÕ
ADC2_Handler.Init.Overrun=ADC_OVR_DATA_OVERWRITTEN; //óDDÂμÄêy¾YμÄËàoóÖ±½ó¸2¸Çμô¾éêy¾Y
ADC2_Handler.Init.OversamplingMode=DISABLE; //1y2éÑù1رÕ
ADC2_Handler.Init.ConversionDataManagement=ADC_CONVERSIONDATA_DR; //1æÔòí¨μàμÄêy¾Y½ö½ö±£′æÔúDR¼Ä′æÆ÷àïÃæ
HAL_ADC_Init(&ADC2_Handler); //3õê¼»ˉ
HAL_ADCEx_Calibration_Start(&ADC2_Handler,ADC_CALIB_OFFSET,ADC_DIFFERENTIAL_ENDED); //ADCD£×¼
}
//ADCμ×2ãÇy¶ˉ£¬òy½ÅÅäÖã¬ê±Öóê1Äü
//′Ëoˉêy»á±»HAL_ADC_Init()μ÷óÃ
//hadc:ADC¾ä±ú
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_ADC12_CLK_ENABLE(); //ê1ÄüADC1/2ê±Öó
__HAL_RCC_GPIOC_CLK_ENABLE(); //¿aÆôGPIOCê±Öó
__HAL_RCC_GPIOA_CLK_ENABLE(); //¿aÆôGPIOAê±Öó
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP); //ADCíaéèê±ÖóÑ¡Ôñ
GPIO_Initure.Pin=GPIO_PIN_4|GPIO_PIN_5; //PC4 5
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //Ä£Äa
GPIO_Initure.Pull=GPIO_NOPULL; //2»′øéÏÏÂà-
HAL_GPIO_Init(GPIOC,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_6|GPIO_PIN_7; //PA6 7
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //Ä£Äa
GPIO_Initure.Pull=GPIO_NOPULL; //2»′øéÏÏÂà-
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
}
//»ñμÃADCÖμ
//ch: í¨μàÖμ 0~16£¬è¡Öμ·¶Î§Îa£oADC_CHANNEL_0~ADC_CHANNEL_16
//·μ»ØÖμ:×a»»½á1û
u16 Get_Adc1(u32 ch,u32 rank)
{
ADC_ChannelConfTypeDef ADC1_ChanConf;
ADC1_ChanConf.Channel=ch; //í¨μà
ADC1_ChanConf.Rank=rank; //1¸öDòáD ADC_REGULAR_RANK_1
ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_64CYCLES_5; //2éÑùê±¼ä
ADC1_ChanConf.SingleDiff=ADC_DIFFERENTIAL_ENDED; //2î·Ö2é¼ˉADC_DIFFERENTIAL_ENDED
ADC1_ChanConf.OffsetNumber=ADC_OFFSET_NONE;
ADC1_ChanConf.Offset=0;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //í¨μàÅäÖÃ
HAL_ADC_Start(&ADC1_Handler); //¿aÆôADC
HAL_ADC_PollForConversion(&ADC1_Handler,10); //ÂÖÑˉ×a»»
return (u16)HAL_ADC_GetValue(&ADC1_Handler); //·μ»Ø×î½üò»′ÎADC11æÔò×éμÄ×a»»½á1û
}
u16 Get_Adc2(u32 ch,u32 rank)
{
ADC_ChannelConfTypeDef ADC2_ChanConf;
ADC2_ChanConf.Channel=ch; //í¨μà
ADC2_ChanConf.Rank=rank; //1¸öDòáD ADC_REGULAR_RANK_1
ADC2_ChanConf.SamplingTime=ADC_SAMPLETIME_64CYCLES_5; //2éÑùê±¼ä
ADC2_ChanConf.SingleDiff=ADC_DIFFERENTIAL_ENDED; //2î·Ö2é¼ˉADC_DIFFERENTIAL_ENDED
ADC2_ChanConf.OffsetNumber=ADC_OFFSET_NONE;
ADC2_ChanConf.Offset=0;
HAL_ADC_ConfigChannel(&ADC2_Handler,&ADC2_ChanConf); //í¨μàÅäÖÃ
HAL_ADC_Start(&ADC2_Handler); //¿aÆôADC
HAL_ADC_PollForConversion(&ADC2_Handler,10); //ÂÖÑˉ×a»»
return (u16)HAL_ADC_GetValue(&ADC2_Handler); //·μ»Ø×î½üò»′ÎADC11æÔò×éμÄ×a»»½á1û
}
大家可以看到我用的很笨的办法来实现 就是怕出现问题 但是仍然无法成功。
定时器是10ms触发一次,通过定时器进行采样。中断服务程序为:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==(&TIM3_Handler))
{
adcx1=Get_Adc1(ADC_CHANNEL_3,ADC_REGULAR_RANK_1);//»ñè¡í¨μà19μÄ×a»»Öμ
adcx2=Get_Adc2(ADC_CHANNEL_4,ADC_REGULAR_RANK_1);//»ñè¡í¨μà19μÄ×a»»Öμ
temp1=(float)(3300*((2.0*adcx1/65536.0)-1.0)); //»ñ衼ÆËãoóμÄ′øD¡êyμÄêμ¼êμçÑ1Ö죬±èèç3.1111
temp2=(float)(3300*((2.0*adcx2/65536.0)-1.0)); //»ñ衼ÆËãoóμÄ′øD¡êyμÄêμ¼êμçÑ1Ö죬±èèç3.1111
}
}
求助各位大佬。万分感谢
而之前前级差分运放没设置好,实测偏置有2.5V 。
一周热门 更多>