求助,现采用
STM32L051采集电压 12位ADC,启用DMA,内部参考电压1.2V 理论上可采集最小值1.2/4096=0.2mV ,但在实际测试8MV以下就检测不到了通道数据为0. 贴出代码,熟悉ADC的大神帮忙看一下,谢谢。//ADC初始化
void MX_ADC_Init(void)
{
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolu
tion, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.SamplingTime = ADC_SAMPLETIME_39CYCLES_5;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_BACKWARD;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DMAContinuousRequests = ENABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerFrequencyMode = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_6;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_7;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_8;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_9;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_VREFINT;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
//主函数
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM2_Init();
MX_ADC_Init();
HAL_ADCEx_Calibration_Start(&hadc,ADC_SINGLE_ENDED);//ADC校准
HAL_ADC_Start_DMA(&hadc,ADC_Value.ADC_ConvertedValue,ADC_NUMOFCHANNEL);
MX_USART2_UART_Init();
if(HAL_TIM_Base_Start_IT(&htim2) != HAL_OK)
{
while(1);
}
/* USER CODE BEGIN 2 */
MCU_CHG_Start;
MCU_DSG_Start;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_Delay(100);
for(uint16_t index=0; index<ADC_NUMOFCHANNEL; index++)
{
ADC_Value.ADC_ConvertedVoltage[index]=(uint32_t)(ADC_Value.ADC_ConvertedValueAVER[index]&0xFFF)*ADC_VCC/4096; // mv
}
Project_Data.NTC1Temperature = (int32_t)get_Temperature(get_Resistance(ADC_Value.ADC_ConvertedVoltage[7]));
Project_Data.NTC2Temperature = (int32_t)get_Temperature(get_Resistance(ADC_Value.ADC_ConvertedVoltage[6]));
Project_Data.NTC3Temperature = (int32_t)get_Temperature(get_Resistance(ADC_Value.ADC_ConvertedVoltage[5]));
Project_Data.NTC4Temperature = (int32_t)get_Temperature(get_Resistance(ADC_Value.ADC_ConvertedVoltage[4]));
Project_Data.Current=(ADC_Value.ADC_ConvertedVoltage[3]-ADC_Value.ADC_ConvertedVoltage[2])*1000/Current_Resistance;//MA
// HAL_IWDG_Refresh(&hiwdg);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
//定时器0.5ms一次
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
ADC_Value.ADC_Filter++;
for(uint8_t index=0; index<ADC_NUMOFCHANNEL; index++)
{
ADC_Value.ADC_ConvertedValueSum[index] += ADC_Value.ADC_ConvertedValue[index];
}
if(ADC_Value.ADC_Filter>=20)//20次滤波
{
ADC_Value.ADC_Filter = 0;
for(uint8_t index=0; index<ADC_NUMOFCHANNEL; index++)
{
ADC_Value.ADC_ConvertedValueAVER[index] = ADC_Value.ADC_ConvertedValueSum[index]/20;
ADC_Value.ADC_ConvertedValueSum[index] = 0;
}
}
}
是3.3,记混了。按3.3来算1LSB=3.3/4096=0.8MV,但ADC通道采样实际还是采集不到2MV以下的电压
采集数据不准,是指采集的通道数据跳动很大还是采集的电压值和实际值偏差很大。检查通道的实际电压是否稳定,或者尝试增加采样保持时间,若是采集的数据有波动可再软件处理上增加滤波。
我已经加了软件滤波,每次采集10次,只保留中间4次的
采集的电压值说明如下:
比如我第一次采集的是 3.30v
但是时间久了后采集的是 3.322v
电压是保持不变的
一周热门 更多>