【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时钟:
-
- rcu_periph_clock_enable(RCU_ADC);
-
- rcu_adc_clock_config(RCU_ADCCK_APB2_DIV16);
2. 初始化ADC通道16以及17
初始化内部温度传感器通道以及参考电压通道,校准ADC.
ADC的采样精度为12bit
- void adc_config(void)
- {
-
- adc_channel_length_config(ADC_INSERTED_CHANNEL, 2);
-
-
- adc_inserted_channel_config(0U, ADC_CHANNEL_16, ADC_SAMPLETIME_239POINT5);
-
- adc_inserted_channel_config(1U, ADC_CHANNEL_17, ADC_SAMPLETIME_239POINT5);
-
-
- adc_external_trigger_source_config(ADC_INSERTED_CHANNEL, ADC_EXTTRIG_INSERTED_NONE);
-
- adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
-
- adc_special_function_config(ADC_SCAN_MODE, 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);
-
-
- adc_oversample_mode_config(ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_8B, ADC_OVERSAMPLING_RATIO_MUL256);
- adc_oversample_mode_enable();
-
-
- adc_enable();
- delay_1ms(1U);
-
-
- adc_calibration_enable();
- }
3. 读取ADC值,计算温度
使用了软件触发方式,没1s读取一次
-
- adc_software_trigger_enable(ADC_INSERTED_CHANNEL);
-
- delay_1ms(1000);
-
-
- 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);
-
-
- int main(void)
- {
-
- systick_config();
-
- gd_eval_com_init(EVAL_COM);
-
-
- rcu_periph_clock_enable(RCU_ADC);
-
- rcu_adc_clock_config(RCU_ADCCK_APB2_DIV16);
-
- adc_config();
-
- while(1) {
-
- adc_software_trigger_enable(ADC_INSERTED_CHANNEL);
-
- delay_1ms(1000);
-
-
- temperature = ((float)((int32_t)ADC_IDATA0 - ADC_TEMP_CALIBRATION_VALUE) * 3.3f / 4095 * 1000 / 3.3f) + 30;
- vref_value = (ADC_IDATA1 * 3.3f / 4095);
-
-
- printf("Temperature data is %2.0f C\r\n", temperature);
- printf("Reference voltage data is %5.3fV \r\n", vref_value);
- }
- }
-
-
- void adc_config(void)
- {
-
- adc_channel_length_config(ADC_INSERTED_CHANNEL, 2);
-
-
- adc_inserted_channel_config(0U, ADC_CHANNEL_16, ADC_SAMPLETIME_239POINT5);
-
- adc_inserted_channel_config(1U, ADC_CHANNEL_17, ADC_SAMPLETIME_239POINT5);
-
-
- adc_external_trigger_source_config(ADC_INSERTED_CHANNEL, ADC_EXTTRIG_INSERTED_NONE);
-
- adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
-
- adc_special_function_config(ADC_SCAN_MODE, 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);
-
-
- adc_oversample_mode_config(ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_8B, ADC_OVERSAMPLING_RATIO_MUL256);
- adc_oversample_mode_enable();
-
-
- adc_enable();
- delay_1ms(1U);
-
-
- adc_calibration_enable();
- }
三、演示效果
下载程序运行,打开串口,可以看到下没1s输出一次芯片内部温度数据以及参考电压值。
我们将手放到芯片上,芯片温度将上升串口数据如下:
|