OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3987|回复: 8

STM32H743 ADC差分输入的问题

[复制链接]

2

主题

17

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2019-5-30
在线时间
8 小时
发表于 2019-5-30 18:58:55 | 显示全部楼层 |阅读模式
10金钱
本帖最后由 爱芝麻的苹果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的正弦信号,结果如下:
untitled.jpg

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#楼]

已解决。问了学长以后学长检查了电路,是差分输入匹配的问题。参考手册上说差分输入需要信号有Vref+/2的偏置,即3.3/2=1.75V。 而之前前级差分运放没设置好,实测偏置有2.5V 。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

17

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2019-5-30
在线时间
8 小时
 楼主| 发表于 2019-5-30 18:58:56 | 显示全部楼层
已解决。问了学长以后学长检查了电路,是差分输入匹配的问题。参考手册上说差分输入需要信号有Vref+/2的偏置,即3.3/2=1.75V。
而之前前级差分运放没设置好,实测偏置有2.5V 。
回复

使用道具 举报

2

主题

17

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2019-5-30
在线时间
8 小时
 楼主| 发表于 2019-5-30 18:59:38 | 显示全部楼层
板子是STM32H743 调了好几天了 真的搞不懂哪里出了问题
回复

使用道具 举报

2

主题

17

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2019-5-30
在线时间
8 小时
 楼主| 发表于 2019-5-30 20:12:11 | 显示全部楼层
求助各位。。。。。。。。
回复

使用道具 举报

2

主题

17

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2019-5-30
在线时间
8 小时
 楼主| 发表于 2019-5-31 09:07:43 | 显示全部楼层
路过的大佬们看一看啊。。
回复

使用道具 举报

2

主题

17

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2019-5-30
在线时间
8 小时
 楼主| 发表于 2019-5-31 10:15:06 | 显示全部楼层
请问单端输入的配置和差分输入的配置有什么区别吗?仅将SingleDiff修改配置为ADC_DIFFERENTIAL_ENDED可以吗?还有校准哪里的参数也修改了
回复

使用道具 举报

2

主题

17

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2019-5-30
在线时间
8 小时
 楼主| 发表于 2019-5-31 10:16:30 | 显示全部楼层
有没有AD差分输入的例程
回复

使用道具 举报

4

主题

13

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
267
金钱
267
注册时间
2019-5-16
在线时间
94 小时
发表于 2019-9-19 15:22:38 | 显示全部楼层
差分输入需要信号有Vref+/2的偏置,即3.3/2=1.75V。这句话是什么意思?需要差分的两个输入端都偏置1.75V电压输入才行吗?遇到了差分使用的问题,求指教
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
59
金钱
59
注册时间
2019-6-4
在线时间
13 小时
发表于 2019-9-27 10:54:06 | 显示全部楼层
加个好友吧——767589994
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 22:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表