【GD32L233C-START评测】10. ADC读取芯片内部温度
[复制链接]
【GD32L233C-START评测】1.开箱
【GD32L233C-START评测】2.手把手创建新工程
【GD32L233C-START评测】3.移植FreeRTOS到GD32L233
【GD32L233C-START评测】4. 移植RT-Thread到GD32L233
【GD32L233C-START评测】5. IIC驱动OLED
【GD32L233C-START评测】6. 获取RTC时间并通过OLED显示
【GD32L233C-START评测】7. PWM驱动LED
【GD32L233C-START评测】8. TRNG真随机数生成
【GD32L233C-START评测】9. CRC检验
本帖讲解如何使用GD32L233C的ADC读取芯片内部的温度。
一. 查看数据手册
查看数据手册的第13章模数转换器(ADC)。
ADC模块使用了双时钟域架构(APB 时钟和 ADC 时钟),所以APH时钟和ADC时钟都要设置。
我们可以知道该系列的芯片ADC一共有20个通道,其中16个外部通道和4个内部通道,内部通道有:
我们需要使用的是内部温度传感通道和内部参考电压输入通道
然后查看13.4.12. 温度传感器和内部参考电压 温度传感器和内部参考电压 V REFINT 章节。
我们可以知道:
1. 内部温度传感器连接的是ADC的输入通道16;
2. 内部参考电压连接的是ADC的输入通道17;
3. 温度传感器的使用发方式;
4. 温度计算公式等重要信息。
温度计算公式:温度(°C) = ((D temperature – D 30 ) / Avg_Slope) + 30:
D30的存储地址为: 0x1FFFF7F8,在数据手册中有描述,如下图。
Avg_Slope = 3.3。
二. 代码编辑
1. 初始化ADC时钟:
/* enable ADC clock */
rcu_periph_clock_enable(RCU_ADC);
/* config ADC clock */
rcu_adc_clock_config(RCU_ADCCK_APB2_DIV16);
2. 初始化ADC通道16以及17
初始化内部温度传感器通道以及参考电压通道,校准ADC.
ADC的采样精度为12bit
void adc_config(void)
{
/* ADC channel length config */
adc_channel_length_config(ADC_INSERTED_CHANNEL, 2);
/* ADC temperature sensor channel config */
adc_inserted_channel_config(0U, ADC_CHANNEL_16, ADC_SAMPLETIME_239POINT5);
/* ADC internal reference voltage channel config */
adc_inserted_channel_config(1U, ADC_CHANNEL_17, ADC_SAMPLETIME_239POINT5);
/* ADC trigger config */
adc_external_trigger_source_config(ADC_INSERTED_CHANNEL, ADC_EXTTRIG_INSERTED_NONE);
/* ADC data alignment config */
adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
/* ADC SCAN function enable */
adc_special_function_config(ADC_SCAN_MODE, ENABLE);
/* ADC temperature and Vrefint enable */
adc_channel_16_to_19(ADC_TEMP_CHANNEL_SWITCH, ENABLE);
adc_channel_16_to_19(ADC_INTERNAL_CHANNEL_SWITCH, ENABLE);
adc_external_trigger_config(ADC_INSERTED_CHANNEL, ENABLE);
/* 64 times sample, 6 bits shift */
adc_oversample_mode_config(ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_8B, ADC_OVERSAMPLING_RATIO_MUL256);
adc_oversample_mode_enable();
/* enable ADC interface */
adc_enable();
delay_1ms(1U);
/* ADC calibration and reset calibration */
adc_calibration_enable();
}
3. 读取ADC值,计算温度
使用了软件触发方式,没1s读取一次
/* ADC software trigger enable */
adc_software_trigger_enable(ADC_INSERTED_CHANNEL);
/* delay 1000ms to read ADC value */
delay_1ms(1000);
/* value convert */
value = (int32_t)ADC_TEMP_CALIBRATION_VALUE;
temperature = ((float)((int32_t)ADC_IDATA0 - value) * 3.3f / 4095 * 1000 / 3.3f) + 30;
vref_value = (ADC_IDATA1 * 3.3f / 4095);
4.完整代码如下:
#define ADC_TEMP_CALIBRATION_VALUE REG16(0x1FFFF7F8)
float temperature;
float vref_value;
void adc_config(void);
/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
int main(void)
{
/* configure systick */
systick_config();
/* USART configuration */
gd_eval_com_init(EVAL_COM);
/* enable ADC clock */
rcu_periph_clock_enable(RCU_ADC);
/* config ADC clock */
rcu_adc_clock_config(RCU_ADCCK_APB2_DIV16);
/* ADC configuration */
adc_config();
while(1) {
/* ADC software trigger enable */
adc_software_trigger_enable(ADC_INSERTED_CHANNEL);
/* delay 1000ms to read ADC value */
delay_1ms(1000);
/* value convert */
temperature = ((float)((int32_t)ADC_IDATA0 - ADC_TEMP_CALIBRATION_VALUE) * 3.3f / 4095 * 1000 / 3.3f) + 30;
vref_value = (ADC_IDATA1 * 3.3f / 4095);
/* value print */
printf("Temperature data is %2.0f C\r\n", temperature);
printf("Reference voltage data is %5.3fV \r\n", vref_value);
}
}
/*!
\brief configure the ADC peripheral
\param[in] none
\param[out] none
\retval none
*/
void adc_config(void)
{
/* ADC channel length config */
adc_channel_length_config(ADC_INSERTED_CHANNEL, 2);
/* ADC temperature sensor channel config */
adc_inserted_channel_config(0U, ADC_CHANNEL_16, ADC_SAMPLETIME_239POINT5);
/* ADC internal reference voltage channel config */
adc_inserted_channel_config(1U, ADC_CHANNEL_17, ADC_SAMPLETIME_239POINT5);
/* ADC trigger config */
adc_external_trigger_source_config(ADC_INSERTED_CHANNEL, ADC_EXTTRIG_INSERTED_NONE);
/* ADC data alignment config */
adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
/* ADC SCAN function enable */
adc_special_function_config(ADC_SCAN_MODE, ENABLE);
/* ADC temperature and Vrefint enable */
adc_channel_16_to_19(ADC_TEMP_CHANNEL_SWITCH, ENABLE);
adc_channel_16_to_19(ADC_INTERNAL_CHANNEL_SWITCH, ENABLE);
adc_external_trigger_config(ADC_INSERTED_CHANNEL, ENABLE);
/* 64 times sample, 6 bits shift */
adc_oversample_mode_config(ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_8B, ADC_OVERSAMPLING_RATIO_MUL256);
adc_oversample_mode_enable();
/* enable ADC interface */
adc_enable();
delay_1ms(1U);
/* ADC calibration and reset calibration */
adc_calibration_enable();
}
三、演示效果
下载程序运行,打开串口,可以看到下没1s输出一次芯片内部温度数据以及参考电压值。
我们将手放到芯片上,芯片温度将上升串口数据如下:
|