本帖最后由 lugl4313820 于 2022-5-9 15:59 编辑
为了验证ADC的精度如何,今天做了个电压表:
电压输入IO选择为GPIOB1,从datasheet上查到为通道9:
1、初始化ADC时钟:
void rcu_config(void)
{
/* enable GPIOC clock */
rcu_periph_clock_enable(RCU_GPIOB);
/* enable ADC clock */
rcu_periph_clock_enable(RCU_ADC);
/* config ADC clock */
rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);
}
2、初始化IO:PB1
void gpio_config(void)
{
/* config the GPIO as analog mode */
gpio_mode_set(GPIOB, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);
}
3、ADC配置:
void adc_config(void)
{
/* ADC data alignment config */
adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
/* ADC channel length config */
adc_channel_length_config(ADC_REGULAR_CHANNEL, 1U);
/* ADC trigger config */
adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
/* ADC external trigger config */
adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
/* enable ADC interface */
adc_enable();
delay_1ms(1U);
/* ADC calibration and reset calibration */
adc_calibration_enable();
}
4、转换函数:
/*!
\brief ADC 转换函数
\param[in] 通道数
\param[out]
\retval ADC值
*/
uint16_t ADC_Get_Channel(uint8_t channel)
{
/* ADC regular channel config */
adc_regular_channel_config(0U, channel, ADC_SAMPLETIME_7POINT5);
/* ADC software trigger enable */
adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
/* wait the end of conversion flag */
while(!adc_flag_get(ADC_FLAG_EOC));
/* clear the end of conversion flag */
adc_flag_clear(ADC_FLAG_EOC);
/* return regular channel sample value */
return (adc_regular_data_read() & 0xfff);
}
5、多次采样,取平均值:
//channel参数为ADC通道:ADC_CHANNEL_x x = 0...15
uint16_t adc_Channel_Average(uint8_t channel)
{
uint32_t adc_raw = 0;
int i;
uint8_t degree = 3; //读的次数的幂 2^3
for(i = 0;i < (1 << degree);i++)
{
//读取ADC次数
adc_raw += ADC_Get_Channel(channel);
delay_1ms(2);
}
//这里循环8次读取,因此 >>3位就是除以8
adc_raw >>= degree;
return adc_raw;
}
6、主函数、获取平均ADC值,显示到LCD上:
adc_value = adc_Channel_Average(ADC_CHANNEL_9);
vref_value = (float)adc_value*3.3f/4096.0f;
sprintf(show_adc_str,"%.4fV",vref_value);
LCD_ShowString(18,36,show_adc_str,WHITE,BLUE,32,0);
7、为了验证采样的精度如何,我用了标准的数据电源、福禄克45、福禄克18B+进行了对比显示:
E3640A |
0.00V |
1.00V |
2.00V |
3.00V |
3.30V |
GD32F310 |
0..0000V |
0.9894V |
2.0029V |
3.0043 |
3.2992V |
福禄克45 |
0.89mV |
1.0016V |
2.0040V |
3.0071 |
3.308V |
福禄克18+ |
0.000V |
0.996V |
1.994V |
2.992 |
3.291V |
平均差值 |
|
0.0094 |
-0.0039 |
-0.0047 |
0.0003 |
(差值计算公式为:(福禄克45+福禄克18)/2-GD32F310)
0.00V图片:
1.00V截图
2.0V截图
3.0V截图
3.30V截图
【总结】经过测评,GD32的ADC可以说非常让人佩服,相比我用过的其他32位的12ADC表现出不错的成绩。如果采用高精度的分压电阻,可以实现4位的电压电流表是木得问题的。
|