你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

请教下使用stm32L03xx 单片机进行adc转换首次需要23s左右才正常

[复制链接]
hpdell 提问时间:2017-12-22 12:03 /
本帖最后由 hpdell 于 2017-12-22 14:04 编辑

请教下,使用stm32L03xx 单片机进行adc转换,每次开机首次转换大概需要23s左右后才能够获得正确的值,
使用查询模式,单次转换
是怎么个情况 ???

相关配置如下:
ADC_HandleTypeDef    AdcHandle;

ADC_UserTypeDef  __adc_User;


void MX_ADC_Init(void)
{

  ADC_ChannelConfTypeDef   sConfig;

        memset(&__adc_User.aADCxConvertedData[0], 0, ADC_CONVERTED_DATA_BUFFER_SIZE);
        
        __adc_User.aADCxConverVal = 0;   // 求出平均值
        __adc_User.aADCxConverVal_H = 0;   // 求出平均值
        __adc_User.aADCxConverVal_L = 0;   // 求出平均值
        __adc_User.aADC_ConvFinishFlag = 0;       // adc 转换完成标志,=1说明转换完成,否则没有完成

        __adc_User.aAdcConvCntTime = 0;  // adc 转换计时
        __adc_User.aAdcConvCntFlag = 0;  // adc 转换标志    =1停止,=0开启        
        
        
        
  /* Configuration of ADCx init structure: ADC parameters and regular group */
  AdcHandle.Instance = ADCx;

  HAL_ADC_DeInit(&AdcHandle) ;
        
  AdcHandle.Init.OversamplingMode      = DISABLE;
  AdcHandle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV1;
  AdcHandle.Init.LowPowerFrequencyMode = ENABLE;

#if defined(ADC_LOWPOWER)
  AdcHandle.Init.LowPowerAutoWait      = ENABLE;                        /* Enable the dynamic low power Auto Delay: new conversion start only when the previous conversion (for regular group) or previous sequence (for injected group) has been treated by user software. */
  AdcHandle.Init.LowPowerAutoPowerOff  = ENABLE;                        /* Enable the auto-off mode: the ADC automatically powers-off after a conversion and automatically wakes-up when a new conversion is triggered (with startup time between trigger and start of sampling). */
#else
  AdcHandle.Init.LowPowerAutoWait      = DISABLE;
  AdcHandle.Init.LowPowerAutoPowerOff  = DISABLE;
#endif               
                        
               
  AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;
  AdcHandle.Init.SamplingTime          = ADC_SAMPLETIME_7CYCLES_5;  //ADC_SAMPLETIME_7CYCLES_5;
  AdcHandle.Init.ScanConvMode          = DISABLE;                      //非扫描模式
  AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
  AdcHandle.Init.ContinuousConvMode    = DISABLE;                                                //关闭连续转换
  AdcHandle.Init.DiscontinuousConvMode = DISABLE;
  AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
  AdcHandle.Init.EOCSelection          = DISABLE;                      //关闭EOC中断
  AdcHandle.Init.DMAContinuousRequests = DISABLE;

  HAL_ADC_Init(&AdcHandle);

  HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED);
        
  sConfig.Channel      = ADCx_CHANNELa;
  sConfig.Rank         = ADC_RANK_CHANNEL_NUMBER;

  HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
        
//        HAL_ADC_Start(&AdcHandle);
}



void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct;
//        static DMA_HandleTypeDef         DmaHandle;
        
  if(adcHandle->Instance == ADCx)
  {
                __HAL_RCC_GPIOA_CLK_ENABLE();

                ADCx_CLK_ENABLE();
                // Enable DMA1 clock //
//                __HAL_RCC_DMA1_CLK_ENABLE();

  //  PA1-CK_IN     ------> ADC_IN1

    GPIO_InitStruct.Pin = ADCx_CHANNELa_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(ADCx_CHANNELa_GPIO_PORT, &GPIO_InitStruct);
  }
}



void  ADC_Stop(void)
{
        HAL_ADC_Stop(&AdcHandle);
}



void ADC_VoltageConversion(void)
{
  uint8_t i;

        for(i=0;i<ADC_CONVERTED_DATA_BUFFER_SIZE;i++)
        {
                HAL_ADC_Start(&AdcHandle);
                HAL_ADC_PollForConversion(&AdcHandle, 5);  //
                if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)
                {
                        __adc_User.aADCxConvertedData = (uint16_t )HAL_ADC_GetValue(&AdcHandle);
                }
        }
        ADC_Stop();                  // 转换完成 后,adc 停止
        __adc_User.aADC_ConvFinishFlag = 0;
        __adc_User.aADCxConverVal_H = __adc_User.aADCxConverVal_L = 0;
        __adc_User.aADCxConverVal = BubbleSort((uint16_t *)&__adc_User.aADCxConvertedData[0], ADC_CONVERTED_DATA_BUFFER_SIZE);   // 求出平均值
        
        __adc_User.aADCxConverVal_H = __adc_User.aADCxConverVal >> 4;
        __adc_User.aADCxConverVal_L = (uint8_t)(__adc_User.aADCxConverVal & 0x000f);
        
        
        
        
        
        /*
        // 转换成实际电压值
        ConValue = (float)(COMPUTATION_DIGITAL_12BITS_TO_VOLTAGE(aADCxConverVal));
        
        sprintf((char *)&datdat[0], "ADC Voltage: %1.2fV", (float)ConValue);
        printf("ADC Voltage: %s\r\n", datdat);*
        */        
        
}









收藏 1 评论14 发布时间:2017-12-22 12:03

举报

14个回答
hpdell 回答时间:2017-12-25 09:35:48
本帖最后由 hpdell 于 2017-12-25 09:37 编辑
Inc_brza 发表于 2017-12-22 15:25
程序问题居多~
排版太糟糕了,看不下去~

你好,我重新截图了,另外我外部ad口的分压电阻使用的是两个 470K, 为了省电,所以电阻值选择的有点大
333.png

333-1.png

333-2.png

333-3.png
Inc_brza 回答时间:2017-12-22 15:25:25
程序问题居多~
排版太糟糕了,看不下去~
wudianjun2001 回答时间:2018-2-8 09:16:20
外部采集的是什么信号,是不是外部的信号23秒后才稳定的,可以直接加一个固定的电平试试,如果还不正常的话就要检查程序问题了

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

Angel_YY_ST 回答时间:2018-2-8 09:54:20
提示: 作者被禁止或删除 内容自动屏蔽
feixiang20 回答时间:2018-2-8 10:23:07
时间太长了,你用一个校准电压直接尝试结果是否一样,然后重新检查程序中对于时间的控制是否正确,是否有循环异常,蚕食是否设置的对,主要针对延时

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

无薪税绵 回答时间:2018-2-8 10:40:05
正常情况下ADC是很快的。

不知道你的 ADC_CONVERTED_DATA_BUFFER_SIZE 是多大。
看你的程序,你是一次采样 ADC_CONVERTED_DATA_BUFFER_SIZE 次,
然后才进行平均值,这样的话,会导致采样时间内,什么都做不了。

建议进行分时采样,然后计算采样次数,足够后再进行平均值计算,
这样,就不会出现你这种情况了。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

wenyangzeng 回答时间:2018-2-8 10:49:13
官方的例程可以参考。事半功倍:
ADC.rar (278.82 KB, 下载次数: 18)

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

hello_bug 回答时间:2018-2-8 11:22:27
本帖最后由 hello_bug 于 2018-2-8 11:24 编辑

觉得你描述的不完整:
23s以后正常,比如你采外部1V电压信号,刚上电采的是0.5,0.6不停乱变,然后23s后变成1V左右?还是说外部信号一直在变化,刚上电,采样计算的电压与外部电压始终差的多,23s后才跟着外部信号一起变?
先固定一个信号,然后采样看下,上电采样的信号多大,差多少;23s后是多大;建议持续工作半天,甚至一天,看看是不是还有没发现的其他异常。
采样那有保护吧,给个小电压信号,先试试先上电,再给电压信号;再试一直给电压信号,再上电,看看有什么不同;目前感觉电阻有所影响,越过电阻试试采样。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

hello_bug 回答时间:2018-2-8 11:27:44
还一个是软件取平均数这里,你开辟了一个数组给瞬时采样值,求平均的时候,肯定是数组里相加除以个数;会不会刚上电,数组里的数未被填满或取的数据总是滞后,导致有所差异;23s稳定了就OK了。
zhjb1 回答时间:2018-2-8 11:28:30
楼主:您好!470K的电阻分压大了点,如果你接有电容,其积分时间常数将会比较大,这是一个原因此外前边几位网友的回答以很到位了。先试试外部固定电压看看结果如何,再调试程序;实际上官方提供的代码通常直接出结果,改改再己用。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

Stm32McuLover 回答时间:2018-2-8 12:08:15
楼上提了这么多意见,我的建议是换个芯片试试,说不定芯片或者板子的毛病,先排除硬件故障。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

zero99 回答时间:2018-2-8 13:05:23
楼上回答了这么多,等楼主分享问题原因了啊
中山无雪 回答时间:2018-2-8 18:55:07
一般这样的问题是由外部电路引起的,先查一下吧

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

海鱼 回答时间:2018-2-9 13:56:14
采样电阻有点大了 要不然你可以加运放去提高输入阻抗  首先排除应该问题你应该直接测量一个基准电压 例如上面网友收的1节1.5V的干电池看看程序是否有问题
再着调试功能性的东西先直接打印ADC值吧 之后才去考虑软件滤波的问题~~

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版