你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32实例-内部温度传感器实验

[复制链接]
STMCU小助手 发布时间:2022-6-28 18:33
    我们介绍过了 ADC模数转换实验, 知道 ADC 内部有一个通道连接着芯片
的温度传感器,这次就来学** STM32F1 的内部温度传感器。要实现的功能是:通过芯片内部温度传感器读取温度,并将读取的温度数据打印出去,
D1 指示灯闪烁提示系统正常运行。学习时可以参考ADC 模数转换实验或者参考《STM32F10x 中文参考手册》-11 模数转换器(ADC)-11.10 章节,特别是寄存器介绍部分。

0 o+ Q4 k4 i; V; u) ^
STM32F1 内部温度传感器简介
    STM32F1 内部含有一个温度传感器,可用来测量 CPU 及周围的温度(TA)。此温度传感器与 ADC1 内部输入通道相连接,内部温度传感器连接通道框图如下图所示。它连接在ADC1_IN16 上。ADC1 可以将传感器输出的电压转换成数字值。STM32F1 的内部温度传感器支持的温度范围为:-40~125 度,精度为±1.5℃左右。
微信图片_20220627222524.png
    STM32F1 内部温度传感器的使用很简单,只要初始化下 ADC1_IN16 通道,并激活其内部温度传感器通道就差不多了。关于 ADC 的初始化,我们在上篇文章已经进行了详细的介绍,这里就不多说。接下来我们介绍一下和温度传感器设置相关的 2 个地方。
(1)要使用 STM32F1 的内部温度传感器,必须先激活 ADC 的内部通道,
这里通过 ADC_CCR 的 TSVREFE 位( bit23)设置。设置该位为 1 则启用内部温度传感器,否则关闭内部温度传感器。
(2)STM32F103ZET6的内部温度传感器固定的连接在 ADC1_IN16上, 所以,我们在设置好 ADC1 之后只要读取通道 16 的 AD 值,就知道温度传感器返回来的电压值了。根据这个值,我们就可以计算出当前温度。计算公式如下:
  1. T(℃) ={( V25 - Vsense) /Avg_Slope}+25
复制代码

8 J) v) {& D3 d3 U$ E  V
    公式中:V25=Vsense 在 25 度时的数值(典型值为:1.43V)。
    Avg_Slope=温度与 Vsense 曲线的平均斜率(单位为 mv/℃或 uv/℃)(典型值为4.3mV/℃)。通过上面公式,我们就能非常方便的计算出当前内部温度传感器测试的温度。

, R9 [( G0 j1 I( z, Z) N
内部温度传感器配置步骤
    接下来我们介绍下如何使用库函数对内部温度传感器进行配置。这个也是在编写程序中必须要了解的。具体步骤如下:(ADC 相关库函数在stm32f10x_adc.c和 stm32f10x_adc.h 文件中)
(1)初始化 ADC1_IN16相关参数,开启内度温度传感器
    ADC1_IN16 的初始化步骤与上一章介绍 AD 模数转换实验一样,这里我们只需要开启内部温度传感器即可,调用的库函数为:
  1. ADC_TempSensorVrefintCmd(ENABLE);//打开 ADC 内部温度传感器
复制代码
5 L1 U7 ~  w" @/ x) @  R- d% E
(2)读取 ADC1_IN16 AD值,将其转换为对应温度
8 l. \+ q* t  H: Y" I$ {9 e
    上一步配置好后, 我们就可以读取温度传感器的电压值, 根据温度计算公式,可以求出对应电压值的温度,具体方法与上一篇ADC文章介绍的一样。
    本实验使用到硬件资源如下:
(1)D1 指示灯
(2)串口 1
(3)内部温度传感器
    D1 指示灯、串口 1 电路在前面章节都介绍过,这里就不多说,至于内部温度传感器它属于 STM32F1芯片内部的资源,连接的是 ADC1_IN16通道。
    要实现的功能是:通过芯片内部温度传感器读取温度,并将读取的温度数据打印出去,D1 指示灯闪烁提示系统正常运行。程序框架如下:
(1)初始化内部温度传感器(初始化 ADC1_IN16,开启温度传感器)
(2)编写温度读取函数
(3)编写主函数
    前面介绍内部温度传感器配置步骤时, 就已经讲解如何初始化内部温度传感器。下面我们打开“内部温度传感器实验”工程,在 APP工程组中可以看到添加了 adc_temp.c 文件(里面包含了内部温度传感器驱动程序),在 StdPeriph_Driver 工程组中添加了 stm32f10x_adc.c 库文件。
    ADC 操作的库函数都放在stm32f10x_adc.c 和 stm32f10x_adc.h文件中,所以使用到 ADC 就必须加入 stm32f10x_adc.c 文件,同时还要包含对应的头文件路径。
    这里我们分析几个重要函数,其他部分程序大家可以打开工程查看。
内部温度传感器初始化函数
: B" G+ _- D% C0 K
    要使用内部温度传感器,我们必须先对它进行配置。初始化代码如下:
  1. /****************************************************************, b0 i0 Y. H: v
  2. * 函 数 名 : ADC_Temp_Init
    , V5 r9 J2 I0 S# I# m% r
  3. * 函数功能 : ADC_Temp 初始化函数
    + e; k$ b# D& q' ]
  4. * 输 入 : 无$ A- u- O1 u) n: o3 g: B
  5. * 输 出 : 无% a) N' r' N8 F: }
  6. *****************************************************************/$ R) m2 q5 z$ n( X) w/ q
  7. void ADC_Temp_Init(void)
    5 }  v, i4 u  Q4 S0 I! u
  8. {8 E, v! i" I( Q4 a$ |
  9.   ADC_InitTypeDef ADC_InitStructure;0 t% H; B( U/ i5 v
  10.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
    , L) S% v. G! u7 A- L
  11.   RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 分 频 因 子 6 时 钟 为72M/6=12MHz
    / L* j8 S& |6 Z! p5 E: O% F0 D
  12.   ADC_TempSensorVrefintCmd(ENABLE);//打开 ADC 内部温度传感器; Y3 T. I( k! [: B
  13.   ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC 工作模式:ADC1 和 ADC2 工作在独立模式- Z- J3 N) H/ |( u3 K6 q5 d' r; H4 t
  14.   ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式
    6 G+ x! M. z5 l  L; x$ B
  15.   ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换
    * Y% n" f9 t  j
  16.   ADC_InitStructure.ADC_ExternalTrigConv =; J1 ~' f0 v0 Y. m" t$ h
  17.   ADC_ExternalTrigConv_None;//禁止触发检测,使用软件触发" H3 }5 u* J. X% M# P
  18.   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐$ {$ G4 T/ V# {! o4 I# ?+ r# d
  19.   ADC_InitStructure.ADC_NbrOfChannel = 1; //1 个转换在规则序列中 也就是只转换规则序列1
    $ x" w/ t) v/ Q1 ?
  20.   ADC_Init(ADC1, &ADC_InitStructure);//ADC 初始化0 x( m8 Y- }* D, Q# |* \
  21.   ADC_Cmd(ADC1, ENABLE);//开启 AD 转换器4 I5 {+ O8 E% r* O, m4 e8 }$ x
  22.   ADC_ResetCalibration(ADC1);//重置指定的 ADC 的校准寄存器- x) Q% n) @! ^7 A( y( x. o' g6 q
  23.   while(ADC_GetResetCalibrationStatus(ADC1));//获取 ADC 重置校准寄存器的状态: S( t0 T' {6 }% s! j; w3 y5 B
  24.   ADC_StartCalibration(ADC1);//开始指定 ADC 的校准状态" ]4 }6 `7 t) T/ y( R& r
  25.   while(ADC_GetCalibrationStatus(ADC1));//获取指定 ADC的校准程序
    # ~0 W' p& W2 t1 _- [1 p+ ?
  26.   ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能或者失能指定的ADC的软件转换启动功能4 O% I0 n4 W4 i$ |+ v
  27. }
复制代码

! V" d$ N5 R- R0 |) v2 C8 O1 A
    该 函 数 功 能 很 简 单 , 初 始 化 ADC1_IN16 通 道 , 并 且 调 用ADC_TempSensorVrefintCmd 函数开启内部温度传感器, 初始化过程与ADC模数转换实验几乎一模一样。
温度读取函数
    当初始化内部温度传感器后,就可以读取温度值,代码如下:
  1. /****************************************************************
    ; V! B: m' k7 t: H$ F
  2. * 函 数 名 : Get_Temperture: ~7 S$ {; p8 ]% S
  3. * 函数功能 : 获取温度值
    6 k6 `' A4 X6 O4 C$ x& R, d
  4. * 输 入 : 无+ c+ K1 F$ c$ K5 @- C% Q
  5. * 输 出 : 温度值(扩大了 100 倍,单位:℃)- M4 ?7 Z  S' k- _, Z/ }1 Z# ~
  6. *****************************************************************/  k7 I% f( g) ~, Y# D1 a( m
  7. int Get_Temperture(void)
    $ ^  T1 M5 W: z! C
  8. {
    ! ^: ~. b. o( ~" _  l7 {
  9.   u32 adc_value;+ z4 x4 A! d  N  p$ l  A' G6 @
  10.   int temp;
    $ e( P8 _3 Z9 Y# j6 k; W
  11.   double temperture;' U! C" T- |: z1 I: X& f& u
  12.   adc_value=Get_ADC_Temp_Value(ADC_Channel_16,10); //读取通道 16内部温度传感器通道,10次取平均
    ' E$ P4 K. F  O- K3 D5 t" y6 B
  13.   temperture=(float)adc_value*(3.3/4096); //电压值/ f( `1 F  @4 P/ N
  14.   temperture=(1.43-temperture)/0.0043+25; //转换为温度值
    ( y& n( V" @4 l6 t, g
  15.   temp=temperture*100; //扩大 100 倍.
    ( E0 p) m& ^; e* M( o
  16.   return temp;' l+ \  X! A7 s; r( ]
  17. }
复制代码
1 J3 b7 O* G& U3 p& c
    温度读取函数代码比较简单,首先读取 ADC1_IN16 通道的AD 值,然后将其转换为电压值,根据温度计算公式就可以得到对应的温度值,最后将其放大100倍作为函数值返回,温度值有正负,所以返回值类型为 int。

8 B! W; {: D8 f7 S: D8 n! K  R4 o
主函数
    编写好内部温度传感器初始化和温度读取函数后, 接下来就可以编写主函数了,代码如下:
  1. /****************************************************************
    8 ^& Q$ D$ p, ~
  2. * 函 数 名 : main
    ( B. m5 Y) |! M5 w
  3. * 函数功能 : 主函数$ t6 S# L' W- M* ~5 S, E. X+ R
  4. * 输 入 : 无" ]6 ?- d% M6 w) W4 t9 K+ ~
  5. * 输 出 : 无  `0 A0 i) l. i8 Q& @0 m
  6. *****************************************************************/  i' _& {/ J: ?
  7. int main()
      M$ E8 B# `8 y% L: A5 j+ @
  8. {
    & k* F0 \- S3 Q- ]
  9.   u8 i=0;
    2 u& f  q! f2 y) I/ }+ u
  10.   int temp=0;( u' o+ s! v; ]2 i3 d; ?% |/ l6 p
  11.   SysTick_Init(72);) a& b1 N# Q& Y! A0 Z
  12.   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组5 k0 z2 N% ^6 ~3 d
  13.   LED_Init();+ Z" y" A: F+ `6 G2 y
  14.   USART1_Init(9600);
    3 _+ o' ]' T  Z
  15.   ADC_Temp_Init();
    0 b) J' t& ~" k* X( v- l
  16.   while(1)) n3 S) g) G. {7 h2 n9 i8 f' A8 u
  17.   {
    % R2 w5 q7 m8 v% H
  18.     i++;
    ! P5 q: l7 Q0 |; }
  19.     if(i%20==0)6 d% p7 O- G, ?$ E1 u) K; W+ x! w
  20.     {6 Q8 U( Z) ^9 X, m/ R/ y
  21.       led1=!led1;7 H4 G7 x" w; r" D: o
  22.     }! s# `+ l/ r" i5 f6 x
  23.     if(i%50==0)! `; [. F0 g8 C
  24.     {
    0 y% r" E& H- F) e8 v2 A; t7 N) z
  25.       temp=Get_Temperture();6 f2 C6 W. {8 ?6 ^2 U
  26.       if(temp<0)7 g* N8 I! s/ y8 O7 }
  27.       {: |, {2 z; u0 g5 Y
  28.         temp=-temp;, ]: n% K& q) F1 p
  29.         printf("内部温度检测值为:-");
    & \  B1 q- o. o
  30.       }$ _: s9 @* n3 {- S
  31.       else
    8 ~2 e2 ^. X" a' h* x# i/ \
  32.       {
    ; e8 n9 d( q& w; j) Z; J, \
  33.         printf("内部温度检测值为:+");
    2 ?9 Y" r) U1 H  W
  34.       }8 |* _+ O9 I+ G% m# x
  35.       printf("%.2f°C\r\n",(float)temp/100);
    - S) L0 V0 ~7 c
  36.     }
    # ]2 D9 o2 _/ T# ?" B2 E3 o
  37.     delay_ms(10);
    5 X* I1 H. {! i7 @( r& U9 G8 y' I4 q
  38.   }
    2 k! {* u& G0 H2 o
  39. }
复制代码
9 Y. j- |7 i* H: @; W3 |
    主函数实现的功能很简单,首先调用之前编写好的硬件初始化函数,包括SysTick 系统时钟,中断分组,LED 初始化等。然后调用我们前面编写的
ADC_Temp_Init 函数,最后进入 while 循环,间隔 500ms读取一次温度,判断读取的温度是正温度还是负温度,最后打印温度数据,在输出温度数据时,要记得除以 100,因为读取的温度值是放大了 100 倍的。D1 指示灯会间隔200ms闪烁,提示系统正常运行。
    将工程程序编译后下载到开发板内,可以看到 D1 指示灯不断闪烁,表示程序正常运行。串口不断打印读取的温度数据,如果想在串口调试助手上看到输出信息,可以打开“串口调试助手”,首先勾选下标号 1 DTR 框,然后再取消勾选。这是因为此串口助手启动时会把系统复位住,通过 DTR 状态切换下即可。然后设置好波特率等参数后,串口助手上即会收到 printf 发送过来的信息。(串口助手上先勾选下标号 1 DTR 框,然后再取消勾选)如下图所示:
微信图片_20220627222516.png

& y" d# w# c9 @0 F1 S2 B
    注:由于芯片工作会发热,所以内部温度传感器检测的温度通常会高于实际温度,这也是不使用芯片内部温度传感器来检测环境温度的原因。

4 h+ U7 h+ ?' q: a2 ^
收藏 评论0 发布时间:2022-6-28 18:33

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版