本帖最后由 dirty 于 2024-6-11 09:11 编辑
本篇讲述GD32H759I ADC测温与板载ADC电路电压测量。
一.硬件原理
开发板板载ADC可调电路,如下图1,VR1为可调电阻。通过芯片手册ADC部分如下图2,可知ADC2为12bit ADC;内部自带温度传感器ADC2 Channel18.这里跳线帽JP76短接,VREF+参考电压3.3V.
图1:ADC电路
二.代码准备
1.ADC配置初始化。这里测温度部分用到ADC2 Channel18, 侧外部板载可调电阻ADC接口电压使用到ADC2 Channel0.
void adc_config(void)
{
/* reset ADC */
adc_deinit(ADC2);
/* ADC clock config */
adc_clock_config(ADC2, ADC_CLK_SYNC_HCLK_DIV6);
/* ADC contineous function enable */
adc_special_function_config(ADC2, ADC_CONTINUOUS_MODE, DISABLE);
/* ADC scan mode enable */
adc_special_function_config(ADC2, ADC_SCAN_MODE, ENABLE);
/* ADC resolution config */
adc_resolution_config(ADC2, ADC_RESOLUTION_12B);
/* ADC data alignment config */
adc_data_alignment_config(ADC2, ADC_DATAALIGN_RIGHT);
/* ADC channel length config */
adc_channel_length_config(ADC2, ADC_INSERTED_CHANNEL, 2);
/* ADC temperature sensor channel config */
adc_inserted_channel_config(ADC2, 0, ADC_CHANNEL_18, 480);
/* ADC internal reference voltage channel config */
adc_inserted_channel_config(ADC2, 1, ADC_CHANNEL_0, 480);
/* enable ADC temperature channel */
adc_internal_channel_config(ADC_CHANNEL_INTERNAL_TEMPSENSOR, ENABLE);
/* enable internal reference voltage channel */
adc_internal_channel_config(ADC_CHANNEL_INTERNAL_VREFINT, ENABLE);
/* ADC trigger config */
adc_external_trigger_config(ADC2, ADC_INSERTED_CHANNEL, EXTERNAL_TRIGGER_DISABLE);
/* enable ADC interface */
adc_enable(ADC2);
/* wait for ADC stability */
delay_1ms(1);
/* ADC calibration mode config */
adc_calibration_mode_config(ADC2, ADC_CALIBRATION_OFFSET);
/* ADC calibration number config */
adc_calibration_number(ADC2, ADC_CALIBRATION_NUM1);
/* ADC calibration and reset calibration */
adc_calibration_enable(ADC2);
/* ADC software trigger enable */
adc_software_trigger_enable(ADC2, ADC_INSERTED_CHANNEL);
}
2.内部通道温度计算使用到了校准值计算斜率,然后根据内部实际采样值取点线性计算。为与实际环境温度温和,这里计算公式做了下修正。
temperature_value_25 = ADC_TEMP_CALIBRATION_VALUE_25 & 0x0FFF;
temperature_value_minus40 =ADC_TEMP_CALIBRATION_VALUE_MINUS40 & 0x0FFF;
avg_slope = -(temperature_value_25 - temperature_value_minus40) / (25.0f + 40.0f);
/* value convert */
temperature = (temperature_value_25 - (int32_t)ADC_IDATA0(ADC2))*3.3f/4096/avg_slope*1000 + 20 ;//25
3.main函数实现温度与ADC电路电压串口打印。这里参考电压3.3V,12bitadc,所以公式为 vres_value = (ADC_IDATA1(ADC2) * 3.3f / 4096);。代码如下
int main(void)
{
/* enable the CPU cache */
cache_enable();
/* peripheral clocks configuration */
rcu_config();
/* configure systick */
systick_config();
/* USART configuration */
gd_eval_com_init(EVAL_COM);
printf("UART Init\r\n");
/* ADC configuration */
adc_config();
printf("ADC Init\r\n");
temperature_value_25 = ADC_TEMP_CALIBRATION_VALUE_25 & 0x0FFF;
temperature_value_minus40 =ADC_TEMP_CALIBRATION_VALUE_MINUS40 & 0x0FFF;
avg_slope = -(temperature_value_25 - temperature_value_minus40) / (25.0f + 40.0f);
while(1) {
/* ADC software trigger enable */
adc_software_trigger_enable(ADC2, ADC_INSERTED_CHANNEL);
/* delay a time in milliseconds */
delay_1ms(3000);
/* value convert */
temperature = (temperature_value_25 - (int32_t)ADC_IDATA0(ADC2))*3.3f/4096/avg_slope*1000 + 20 ;//25
vres_value = (ADC_IDATA1(ADC2) * 3.3f / 4096);
/* value print */
printf(" the temperature data is %2.0f degrees Celsius\r\n", temperature);
printf(" the reference voltage data is %5.3fV \r\n", vres_value);
printf(" \r\n");
}
}
三.测验
编译烧录后,可看到温度基本稳定为环境温度。旋转调节VR1分压阻值,可看到往一个方向旋时电压递减或递增,且范围在0--3.3V之间。ADC测试日志如下:
图3:ADC测试
至此,实现开发板ADC功能。