5467|0

282

帖子

2

TA的资源

一粒金砂(高级)

楼主
 

【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输出一次芯片内部温度数据以及参考电压值。

我们将手放到芯片上,芯片温度将上升串口数据如下:

 

 

 

此帖出自GD32 MCU论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表