请教下使用stm32L03xx 单片机进行adc转换首次需要23s左右才正常
本帖最后由 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, 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);
}
}
voidADC_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, 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, "ADC Voltage: %1.2fV", (float)ConValue);
printf("ADC Voltage: %s\r\n", datdat);*
*/
}
本帖最后由 hpdell 于 2017-12-25 09:37 编辑
Inc_brza 发表于 2017-12-22 15:25
程序问题居多~
排版太糟糕了,看不下去~
你好,我重新截图了,另外我外部ad口的分压电阻使用的是两个 470K, 为了省电,所以电阻值选择的有点大
程序问题居多~
排版太糟糕了,看不下去~ 外部采集的是什么信号,是不是外部的信号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了。
页:
[1]
2