查看: 1619|回复: 4
收起左侧

第十一章:CH32V103应用教程——内置温度传感器

[复制链接]

  离线 

  • TA的每日心情
    慵懒
    2021-7-23 17:16
  • 签到天数: 17 天

    [LV.4]

    发表于 2021-4-23 10:43:09 | 显示全部楼层 |阅读模式

    有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    本帖最后由 草帽王子 于 2021-9-10 16:30 编辑

    本章教程使用CH32V103的内部温度传感器检测器件周围温度,并通过串口调试助手打印显示。


    1、温度传感器简介及相关函数介绍

    CH32V103内置温度传感器,连接ADC_INT16通道,通过 ADC 将传感器输出的电压转换成数字值来反馈器件周围温度,推荐设置采样时间是 17.1us。温度传感器输出的电压随温度线性变化,由于生产差异,其线性变化的曲线斜率和偏移有所不同,所以内部温度传感器更适合于检测温度的变化,而不是测量绝对的温度。如果需要测量精确的温度,应该使用一个外置的温度传感器。

    通过设置ADC_CTLR2寄存器的TSVREFE位置1,唤醒ADC内部采样通道,软件启动或者外部触发启动ADC的温度传感器通道转换,读取数据结果(mV)。其中,数字值和温度(℃)换算公式如下:

    •     温度(℃) = ((VSENSE-V25)/Avg_Slope)+25
    •     VSENSE:温度传感器的当前输出电压;
    •     V25:温度传感器在 25℃下的电压值;
    •     Avg_Slope:温度与 VSENSE曲线的平均斜率(mV/℃)
    •     参考数据手册电气特性章节中 V25和 Avg_Slope 的实际值。

        注:内部温度传感器上电(TSVREFE 位从 0 改为 1)需要一个建立时间,而 ADC 模块上电也需要一个建立时间(ADON 位从 0 改为 1),所以为了缩短等待时间,可以同时设置 ADON 和 TSVREFE 位。

    关于CH32V103内置温度传感器具体信息,可参考CH32V103应用手册。温度检测程序所用库函数在ADC教程中已介绍,在此不再赘述。


    2、硬件设计

    内置温度传感器属于其内部资源,无需进行硬件连接,只需进行软件设计即可。



    3、软件设计

    本章教程通过ADC_INT16通道读取内置温度传感器值,其程序相较于ADC,变化不大,增加了使能内部温度传感器和温度值计算,主要程序如下:

    temdet.h文件
    1. #ifndef __TEMDET_H
    2. #define __TEMDET_H

    3. #include "ch32v10x_conf.h"

    4. void adc_Init(void);
    5. u16  get_adc(u8 ch);
    6. u16  get_adc_average(u8 ch,u8 times);
    7. float get_temperature(void);

    8. #endif
    复制代码
    temdet.h文件主要是相关函数的声明。

    temdet.c文件
    1. #include "temdet.h"

    2. void adc_Init(void)
    3. {
    4.     ADC_InitTypeDef ADC_InitStructure;
    5.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );

    6.     RCC_ADCCLKConfig(RCC_PCLK2_Div6);
    7.     ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    8.     ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    9.     ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    10.     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    11.     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    12.     ADC_InitStructure.ADC_NbrOfChannel = 1;
    13.     ADC_Init(ADC1, &ADC_InitStructure);

    14.     ADC_TempSensorVrefintCmd(ENABLE);

    15.     ADC_Cmd(ADC1, ENABLE);

    16.     ADC_ResetCalibration(ADC1);

    17.     while(ADC_GetResetCalibrationStatus(ADC1));

    18.     ADC_StartCalibration(ADC1);

    19.     while(ADC_GetCalibrationStatus(ADC1));
    20. }

    21. u16 get_adc(u8 ch)
    22. {
    23.     ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );

    24.     ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    25.     while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
    26.     return ADC_GetConversionValue(ADC1);
    27. }

    28. u16 get_adc_average(u8 ch,u8 times)
    29. {
    30.     u32 temp_val=0;
    31.     u8 t;
    32.     for(t=0;t<times;t++)
    33.     {
    34.         temp_val+=get_adc(ch);
    35.         Delay_Ms(5);
    36.     }
    37.     return temp_val/times;
    38. }

    39. float get_temperature(void)
    40. {
    41.     u32 adcx;
    42.     float temperate;
    43.     adcx=get_adc_average(ADC_Channel_16,20);
    44.     temperate=(float)adcx*(3.3/4096);
    45.     temperate=(1.43-temperate)/0.0043+25;
    46.     return temperate;
    47. }

    复制代码
    temdet.c文件主要是内置温度传感器进行温度检测的相关配置,其配置流程和ADC差不多,主要增加了使能内部温度传感器和温度值计算,在此不再对流程进行介绍。

    main.c文件
    1. int main(void)
    2. {
    3.     float tem;
    4.     Delay_Init();
    5.         USART_Printf_Init(115200);
    6.         adc_Init();
    7.         while(1)
    8.     {
    9.             Delay_Ms(500);
    10.             tem=get_temperature();
    11.         printf("temp=%.2f\n",tem);
    12.         }
    13. }
    复制代码
    main.c文件主要进行相关函数初始化以及打印输出温度值。



    4、下载验证

    将编译好的程序下载到开发板并复位,串口打印情况具体如下:

    CH32V CH573单片机芯片-第十一章:CH32V103应用教程——内置温度传感器risc-v单片机中文社区(1)
    温度检测.rar附件下载
    CH32V CH573单片机芯片-第十一章:CH32V103应用教程——内置温度传感器risc-v单片机中文社区(2) 10、温度检测.rar (570.06 KB, 下载次数: 21)
    链接:https://pan.baidu.com/s/1MaHijvVBpQxuQvXYvJGgIA
    提取码:kuk7
    复制这段内容后打开百度网盘手机App,操作更方便哦








    上一篇:第十章:CH32V103应用教程——ADC
    下一篇:第十二章:CH32V103应用教程——RTC
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    回复

    使用道具 举报

      离线 

    该用户从未签到

    发表于 2023-7-9 16:11:31 | 显示全部楼层
    我发现,printf这个函数不支持“%f”输出浮点数,但是“%d”是可以的,不知道为啥。

    点评

    仔细参考下 C 库函数 - printf() C 标准库 - https://www.runoob.com/cprogramming/c-function-printf.html 32位单片机上的编译和X86有区别 #include int main() { char ch = 'A'; char str[20] = "ww  详情 回复 发表于 2023-7-10 16:21
    因printf()之类的函数,使用了半主机模式。使用标准库会导致程序无法运行,以下是解决方法: 方法1.使用微库,因为使用微库的话,不会使用半主机模式. 方法2.仍然使用标准库,在主程序添加下面代码: #pragma import(__use  详情 回复 发表于 2023-7-10 16:18
    编译器问题:在某些编译器中,printf 函数的实现可能与标准 C 语言规范不符。在这种情况下,%f格式控制符可能无法输出正确的结果。 解决方法是使用其他编译器或者尝试使用其他 printf 函数实现。 如果遇到了%f格式  详情 回复 发表于 2023-7-10 16:16
    全球首家只专注于RISC-V单片机行业应用的中文网站

      离线 

  • TA的每日心情

    2022-6-26 13:17
  • 签到天数: 4 天

    [LV.2]

    发表于 2023-7-10 16:16:19 | 显示全部楼层
    ziakalis 发表于 2023-7-9 16:11
    我发现,printf这个函数不支持“%f”输出浮点数,但是“%d”是可以的,不知道为啥。 ...

    编译器问题:在某些编译器中,printf 函数的实现可能与标准 C 语言规范不符。在这种情况下,%f格式控制符可能无法输出正确的结果。

    解决方法是使用其他编译器或者尝试使用其他 printf 函数实现。

    如果遇到了%f格式控制符不能输出的问题,可以尝试检查变量类型是否正确,是否需要强制转换为浮点数类型,以及浮点数精度是否满足要求。另外,可以尝试使用其他 printf 函数实现,例如%e、%g等格式控制符。
    全球首家只专注于RISC-V单片机行业应用的中文网站

      离线 

  • TA的每日心情

    2022-6-26 13:17
  • 签到天数: 4 天

    [LV.2]

    发表于 2023-7-10 16:18:04 | 显示全部楼层
    ziakalis 发表于 2023-7-9 16:11
    我发现,printf这个函数不支持“%f”输出浮点数,但是“%d”是可以的,不知道为啥。 ...

    因printf()之类的函数,使用了半主机模式。使用标准库会导致程序无法运行,以下是解决方法:
    方法1.使用微库,因为使用微库的话,不会使用半主机模式.
    方法2.仍然使用标准库,在主程序添加下面代码:
    #pragma import(__use_no_semihosting)
    _sys_exit(int x)
    {
    x = x;
    }
    struct __FILE
    {
    int handle;
    /* Whatever you require here. If the only file you are using is */
    /* standard output using printf() for debugging, no file handling */
    /* is required. */
    };
    /* FILE is typedef’ d in stdio.h. */
    FILE __stdout;
    全球首家只专注于RISC-V单片机行业应用的中文网站

      离线 

  • TA的每日心情

    2022-6-26 13:17
  • 签到天数: 4 天

    [LV.2]

    发表于 2023-7-10 16:21:24 | 显示全部楼层
    ziakalis 发表于 2023-7-9 16:11
    我发现,printf这个函数不支持“%f”输出浮点数,但是“%d”是可以的,不知道为啥。 ...

    仔细参考下 C 库函数 - printf()
    C 标准库 - <stdio.h>   
    https://www.runoob.com/cprogramming/c-function-printf.html

    32位单片机上的编译和X86有区别

    #include <stdio.h>
    int main()
    {
       char ch = 'A';
       char str[20] = "www.runoob.com";
       float flt = 10.234;
       int no = 150;
       double dbl = 20.123456;
       printf("字符为 %c \n", ch);
       printf("字符串为 %s \n" , str);
       printf("浮点数为 %f \n", flt);
       printf("整数为 %d\n" , no);
       printf("双精度值为 %lf \n", dbl);
       printf("八进制值为 %o \n", no);
       printf("十六进制值为 %x \n", no);
       return 0;
    }
    执行输出结果为:

    字符为 A
    字符串为 www.runoob.com
    浮点数为 10.234000
    整数为 150
    双精度值为 20.123456
    八进制值为 226
    十六进制值为 96
    全球首家只专注于RISC-V单片机行业应用的中文网站
    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

    RISC-V单片机中文网上一条 /2 下一条



    版权及免责声明|RISC-V单片机中文网 |网站地图

    GMT+8, 2024-4-23 21:17 , Processed in 0.759260 second(s), 62 queries .

    快速回复 返回顶部 返回列表