完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
请教下,使用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 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: %srn", datdat);* */ } |
|
相关推荐
15个回答
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
外部采集的是什么信号,是不是外部的信号23秒后才稳定的,可以直接加一个固定的电平试试,如果还不正常的话就要检查程序问题了
|
|
|
|
|
|
首先判断是硬件问题还是软件问题,外部采集不用分压电阻,直接采集1.5V干电池的电压,如果此时还是很长时间才稳定,可以排除外部信号问题。然后软件获取到AD值后直接数据,不经过转成电压算法,查看稳定性,排除转换电压算法问题。如果还是没有找到问题,建议换芯片试试。
|
|
|
|
|
|
|
|
|
|
|
|
正常情况下ADC是很快的。
不知道你的 ADC_CONVERTED_DATA_BUFFER_SIZE 是多大。 看你的程序,你是一次采样 ADC_CONVERTED_DATA_BUFFER_SIZE 次, 然后才进行平均值,这样的话,会导致采样时间内,什么都做不了。 建议进行分时采样,然后计算采样次数,足够后再进行平均值计算, 这样,就不会出现你这种情况了。 |
|
|
|
|
|
官方的例程可以参考。事半功倍:
|
|
|
|
|
|
本帖最后由 hello_bug 于 2018-2-8 11:24 编辑
觉得你描述的不完整: 23s以后正常,比如你采外部1V电压信号,刚上电采的是0.5,0.6不停乱变,然后23s后变成1V左右?还是说外部信号一直在变化,刚上电,采样计算的电压与外部电压始终差的多,23s后才跟着外部信号一起变? 先固定一个信号,然后采样看下,上电采样的信号多大,差多少;23s后是多大;建议持续工作半天,甚至一天,看看是不是还有没发现的其他异常。 采样那有保护吧,给个小电压信号,先试试先上电,再给电压信号;再试一直给电压信号,再上电,看看有什么不同;目前感觉电阻有所影响,越过电阻试试采样。 |
|
|
|
|
|
还一个是软件取平均数这里,你开辟了一个数组给瞬时采样值,求平均的时候,肯定是数组里相加除以个数;会不会刚上电,数组里的数未被填满或取的数据总是滞后,导致有所差异;23s稳定了就OK了。
|
|
|
|
|
|
楼主:您好!470K的电阻分压大了点,如果你接有电容,其积分时间常数将会比较大,这是一个原因此外前边几位网友的回答以很到位了。先试试外部固定电压看看结果如何,再调试程序;实际上官方提供的代码通常直接出结果,改改再己用。
|
|
|
|
|
|
楼上提了这么多意见,我的建议是换个芯片试试,说不定芯片或者板子的毛病,先排除硬件故障。
|
|
|
|
|
|
楼上回答了这么多,等楼主分享问题原因了啊
|
|
|
|
|
|
一般这样的问题是由外部电路引起的,先查一下吧
|
|
|
|
|
|
采样电阻有点大了 要不然你可以加运放去提高输入阻抗 首先排除应该问题你应该直接测量一个基准电压 例如上面网友收的1节1.5V的干电池看看程序是否有问题
再着调试功能性的东西先直接打印ADC值吧 之后才去考虑软件滤波的问题~~ |
|
|
|
|
|
看着还很不错的样子
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
STM32F405驱动DS1302时钟模块,输出时间错乱该怎么排查?
2810 浏览 2 评论
stm32f405rgt6驱动DS1302ZN出现时间错乱问题
2420 浏览 1 评论
stm32用fsmc读取ad7606采集数据,数据不变,只有开发版复位才更新数据
2288 浏览 0 评论
2404 浏览 1 评论
1643 浏览 1 评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 07:37 , Processed in 1.004766 second(s), Total 102, Slave 84 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
3377