广元市网站建设_网站建设公司_会员系统_seo优化
2026/1/19 16:36:54 网站建设 项目流程

(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 端子短接片已插上

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询