当前位置: 首页 > news >正文

【普中STM32F1xx开发攻略--标准库版】-- 第 29 章 内部温度传感器实验

(1)实验平台:普中STM32F103朱雀、玄武开发板


上一章我们介绍了 ADC 模数转换实验, 知道 ADC 内部有一个通道连接着芯片的温度传感器, 这一章我们就来学习下 STM32F1 的内部温度传感器。 本章要实现的功能是: 通过芯片内部温度传感器读取温度, 并将读取的温度数据打印出去, DS0 指示灯闪烁提示系统正常运行。 学习本章可以参考上一章 ADC 模数转换实验或者参考《STM32F10x 中文参考手册》 -11 模数转换器(ADC) -11.10 章节, 特别是寄存器介绍部分。 本章分为如下几部分内容:

29.1 STM32F1 内部温度传感器介绍

29.1.1 STM32F1 内部温度传感器简介

29.2 内部温度传感器配置步骤

29.3 硬件设计

29.4 软件设计

29.4.1 内部温度传感器初始化函数

29.4.2 温度读取函数

29.4.3 主函数

29.5 实验现象


29.1 STM32F1 内部温度传感器介绍

29.1.1 STM32F1 内部温度传感器简介

STM32F1 内部含有一个温度传感器, 可用来测量 CPU 及周围的温度(TA)。此温度传感器与 ADC1 内部输入通道相连接, 如下图所示。 它连接在 ADC1_IN16上。 ADC1 可以将传感器输出的电压转换成数字值。 STM32F1 的内部温度传感器支持的温度范围为: -40~125 度, 精度为±1.5℃左右。

STM32F1 内部温度传感器的使用很简单, 只要初始化下 ADC1_IN16 通道, 并激活其内部温度传感器通道就差不多了。 关于 ADC 的初始化, 我们在上一章已经进行了详细的介绍, 这里就不多说。 接下来我们介绍一下和温度传感器设置相关的 2 个地方。

(1) 要使用 STM32F1 的内部温度传感器, 必须先激活 ADC 的内部通道,这里通过 ADC_CCR 的 TSVREFE 位( bit23) 设置。 设置该位为 1 则启用内部温度传感器, 否则关闭内部温度传感器。

(2) STM32F103ZET6 的内部温度传感器固定的连接在 ADC1_IN16 上, 所以,我们在设置好 ADC1 之后只要读取通道 16 的 AD 值, 就知道温度传感器返回来的电压值了。 根据这个值, 我们就可以计算出当前温度。 计算公式如下:

T(℃) ={( Vsense - V25) /Avg_Slope}+25

公式中:

V25=Vsense 在 25 度时的数值(典型值为: 1.43V) 。

Avg_Slope=温度与 Vsense 曲线的平均斜率(单位为 mv/℃或 uv/℃) (典型值为 4.3mV/℃) 。

通过上面公式, 我们就能非常方便的计算出当前内部温度传感器测试的温度。

29.2 内部温度传感器配置步骤

接下来我们介绍下如何使用库函数对内部温度传感器进行配置。 这个也是在编写程序中必须要了解的。 具体步骤如下:(ADC 相关库函数在 stm32f10x_adc.c和 stm32f10x_adc.h 文件中)

(1) 初始化 ADC1_IN16 相关参数, 开启内度温度传感器

ADC1_IN16 的初始化步骤与上一章介绍 AD 模数转换实验一样, 这里我们只需要开启内部温度传感器即可, 调用的库函数为:

ADC_TempSensorVrefintCmd(ENABLE);//打开 ADC 内部温度传感器

(2) 读取 ADC1_IN16 AD 值, 将其转换为对应温度

上一步配置好后, 我们就可以读取温度传感器的电压值, 根据温度计算公式,可以求出对应电压值的温度, 具体方法与上一章一样。

29.3 硬件设计

本实验使用到硬件资源如下:

(1) DS0 指示灯

(2) 串口 1

(3) 内部温度传感器

DS0 指示灯、 串口 1 电路在前面章节都介绍过, 这里就不多说, 至于内部温度传感器它属于 STM32F1 芯片内部的资源, 连接的是 ADC1_IN16 通道。

29.4 软件设计

本章所要实现的功能是: 通过芯片内部温度传感器读取温度, 并将读取的温度数据打印出去, DS0 指示灯闪烁提示系统正常运行。 程序框架如下:

(1) 初始化内部温度传感器(初始化 ADC1_IN16, 开启温度传感器)

(2) 编写温度读取函数

(3) 编写主函数

前面介绍内部温度传感器配置步骤时, 就已经讲解如何初始化内部温度传感器。 下面我们打开“\4--实验程序\1--基础实验\21-内部温度传感器实验” 工程,在 APP 工程组中可以看到添加了 adc_temp.c 文件(里面包含了内部温度传感器驱动程序) , 在 StdPeriph_Driver 工程组中添加了 stm32f10x_adc.c 库文件。ADC 操作的库函数都放在 stm32f10x_adc.c 和 stm32f10x_adc.h 文件中, 所以使用到 ADC 就必须加入 stm32f10x_adc.c 文件, 同时还要包含对应的头文件路径。

这里我们分析几个重要函数, 其他部分程序大家可以打开工程查看。

29.4.1 内部温度传感器初始化函数

要使用内部温度传感器, 我们必须先对它进行配置。 初始化代码如下:

/******************************************************************************* * 函 数 名 : ADC_Temp_Init * 函数功能 : ADC_Temp初始化函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void ADC_Temp_Init(void) { ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div6); //分频因子6时钟为72M/6=12MHz ADC_TempSensorVrefintCmd(ENABLE);//打开ADC内部温度传感器 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//禁止触发检测,使用软件触发 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; //1个转换在规则序列中 也就是只转换规则序列1 ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化 ADC_Cmd(ADC1, ENABLE);//开启AD转换器 ADC_ResetCalibration(ADC1);//重置指定的ADC的校准寄存器 while(ADC_GetResetCalibrationStatus(ADC1));//获取ADC重置校准寄存器的状态 ADC_StartCalibration(ADC1);//开始指定ADC的校准状态 while(ADC_GetCalibrationStatus(ADC1));//获取指定ADC的校准程序 ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能或者失能指定的ADC的软件转换启动功能 }

该函数功能很简单, 初始化 ADC1_IN16 通道, 并且调用ADC_TempSensorVrefintCmd 函数开启内部温度传感器。 初始化过程与上一章 ADC模数转换实验一模一样。

29.4.2 温度读取函数

当初始化内部温度传感器后, 就可以读取温度值, 代码如下:

/******************************************************************************* * 函 数 名 : Get_ADC_Temp_Value * 函数功能 : 获取通道ch的转换值,取times次,然后平均 * 输 入 : ch:通道编号 times:获取次数 * 输 出 : 通道ch的times次转换结果平均值 *******************************************************************************/ u16 Get_ADC_Temp_Value(u8 ch,u8 times) { u32 temp_val=0; u8 t; //设置指定ADC的规则组通道,一个序列,采样时间 ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5); //ADC1,ADC通道,239.5个周期,提高采样时间可以提高精确度 for(t=0;t<times;t++) { ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能指定的ADC1的软件转换启动功能 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束 temp_val+=ADC_GetConversionValue(ADC1); delay_ms(5); } return temp_val/times; } /******************************************************************************* * 函 数 名 : Get_Temperture * 函数功能 : 获取温度值 * 输 入 : 无 * 输 出 : 温度值(扩大了100倍,单位:℃) *******************************************************************************/ int Get_Temperture(void) { u32 adc_value; int temp; double temperture; adc_value=Get_ADC_Temp_Value(ADC_Channel_16,10); //读取通道16内部温度传感器通道,10次取平均 temperture=(float)adc_value*(3.3/4096); //电压值 temperture=(1.43-temperture)/0.0043+25; //转换为温度值 temp=temperture*100; //扩大100倍. return temp; }

温度读取函数代码比较简单, 首先读取 ADC1_IN16 通道的 AD 值, 然后将其转换为电压值, 根据温度计算公式就可以得到对应的温度值, 最后将其放大 100倍作为函数值返回, 温度值有正负, 所以返回值类型为 int。

29.4.3 主函数

编写好内部温度传感器初始化和温度读取函数后, 接下来就可以编写主函数了, 代码如下:

#include "system.h" #include "SysTick.h" #include "led.h" #include "usart.h" #include "adc_temp.h" /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ int main() { u8 i=0; int temp=0; SysTick_Init(72); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组 LED_Init(); USART1_Init(115200); ADC_Temp_Init(); while(1) { i++; if(i%20==0) { LED1=!LED1; } if(i%50==0) { temp=Get_Temperture(); if(temp<0) { temp=-temp; printf("内部温度检测值为:-"); } else { printf("内部温度检测值为:+"); } printf("%.2f°C\r\n",(float)temp/100); } delay_ms(10); } }

主函数实现的功能很简单, 首先调用之前编写好的硬件初始化函数, 包括SysTick 系统时钟, 中断分组, LED 初始化等。 然后调用我们前面编写的ADC_Temp_Init 函数, 最后进入 while 循环, 间隔 500ms 读取一次温度, 判断读取的温度是正温度还是负温度, 最后打印温度数据, 在输出温度数据时, 要记得除以 100, 因为读取的温度值是放大了 100 倍的。 DS0 指示灯会间隔 200ms 闪烁,提示系统正常运行。

29.5 实验现象

将工程程序编译后下载到开发板内, 可以看到 DS0 指示灯不断闪烁, 表示程序正常运行。 串口不断打印读取的温度数据, 如果想在串口调试助手上看到输出信息, 可以打开“\5--开发工具\4-常用辅助开发软件\串口调试助手\串口调试助手(丁丁)” 内串口调试助手。 实验现象如下: (前提一定要连接好线路, USB线一端连接电脑, 另一端连接开发板“USB 转串口模块” 上的 USB 下载口, 并且在“USB 转 TTL&电源” 模块上 P4 端子短接片已插上

实验现象说明: 由于芯片工作会发热, 所以内部温度传感器检测的温度通常会高于实际温度, 这也是不使用芯片内部温度传感器来检测环境温度的原因。

http://www.jsqmd.com/news/268372/

相关文章:

  • 手搓HTML解析器:500行代码实现完整的DOM树构建
  • 三招速查本机端口占用
  • 护照阅读器:爱达魔都号邮轮的高效登船助力
  • 【读书笔记】《日常生活中的自我呈现》
  • 小程序毕设项目推荐-基于微信小程序的文化娱乐购票系统基于springboot+微信小程序的话剧票务管理系统【附源码+文档,调试定制服务】
  • 马斯克狂砸16亿「买」他五年!揭秘特斯拉2号人物,那个睡工厂的狠人
  • 双目摄像头:让人脸登录更安全可靠
  • 【读书笔记】《傅雷家书》
  • R8240数字电子计
  • 纽约时报:OpenAI或将在18个月内现金流枯竭
  • 手机也能跑AI?用DeepSeek-R1-Distill-Qwen-1.5B打造边缘计算助手
  • 盘点便宜好用的古籍识别OCR:6款古籍识别网站
  • 英文文献检索技巧与高效策略:提升学术文献检索效率的实用指南
  • 一个星期又赚了4387元
  • AI 智能体工具与模型上下文协议 (MCP) 深度解析
  • Unsloth镜像免配置优势解析:10分钟完成Qwen微调部署
  • 2026年山东土工格栅厂家实力榜:塑料土工格栅、玻纤土工格栅、钢塑土工格栅、高分子复合材料与生态护坡解决方案五家企业凭技术与工程应用脱颖而出 - 海棠依旧大
  • 从文本到语音的极致加速|Supertonic ONNX Runtime性能实测
  • CV-UNet问题排查:常见错误及解决方案大全
  • 避坑指南:Open Interpreter本地AI编程常见问题全解
  • 微信小程序毕设项目:基于springboot+微信小程序的话剧票务管理系统(源码+文档,讲解、调试运行,定制等)
  • 宽电压输入升降压线性电源模块 低纹波可调正负输出
  • NotaGen问题排查:解决生成失败的常见错误
  • 超详细版:Elasticsearch内存模型K8s部署实践
  • 2026年十大雅思培训机构排行专题报道:精准提分引领行业趋势 - 速递信息
  • 2026年护栏厂商权威推荐榜:道路交通/小区/市政/阳台/波形护栏生产厂家及源头厂家精选
  • C++ 析构函数:企业级项目中的核心设计与工程化实践
  • php日志报错child exited with code 0 after seconds from start
  • 立体库全周期成本管控:从投入到运维的优化指南与立体库厂家参考 - 品牌评测官
  • 成人出国雅思英语学习培训机构哪家好?2026 全国优质雅思辅导机构口碑排名与深度测评 - 老周说教育