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

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

[复制链接]
STMCU小助手 发布时间:2022-3-29 10:00
01. 内部温度传感器简介: e( L9 G! W4 B6 k
STM32F4 有一个内部的温度传感器,可以用来测量 CPU 及周围的温度(TA)。该温度传感器在内部和 ADC1_IN16(STM32F40xx/F41xx 系列)或 ADC1_IN18(STM32F42xx/F43xx系列)输入通道相连接,此通道把传感器输出的电压转换成数字值。 STM32F4 的内部温度传感器支持的温度范围为:-40~125 度。精度为±1.5℃左右。
* j3 d! Y8 @( `( \- m6 U, f2 h
4 V$ g* b( D8 s5 n+ q2 [02. 主要特性和框图
7 h6 M% x* B, K7 G5 r● 支持的温度范围:—40 °C 到 125 °C
4 t% x2 U; [  Y5 q& L& g1 R● 精度:±1.5 °C
  I& q- J" k3 u! ^8 [- y( J9 ~" f8 a. a; \  ^3 p& Q2 d
Y7]GOD2IRN]B)~C2}%G(MPR.png
- R7 u. l+ J& Y6 G$ F# ?. d: M" R+ x
4 x& `8 g  O; |4 G! _; K+ h读取温度, A6 Q2 h0 E) u" G
6 e$ G% X/ M: ^: H- c
要使用传感器,请执行以下操作:, p& v; q& U1 }; n2 H% s
选择 ADC1_IN16 或 ADC1_IN18 输入通道。
0 \% u3 z) r4 b7 {% d/ E$ r选择一个采样时间,该采样时间要大于数据手册中所指定的最低采样时间。
4 [; I2 p7 O  J在 ADC_CCR 寄存器中将 TSVREFE 位置 1,以便将温度传感器从掉电模式中唤醒。, K# m& q' E7 \; m& r2 f1 W
通过将 SWSTART 位置 1(或通过外部触发)开始 ADC 转换
3 V5 O( b+ F2 Q7 u! C读取 ADC 数据寄存器中生成的 V SENSE 数据3 g4 s& ~3 y* N$ M
使用以下公式计算温度:' {, e" E) E6 u$ _
温度(单位为 °C)= {(V SENSE — V 25 ) / Avg_Slope} + 25
$ ]& }+ s: d: M# w3 g1 ?, l$ P其中:+ H; Q% W. r0 T' \% c3 ]
— V 25 = 25 °C 时的 V SENSE 值
  N8 T; D/ y* _/ j9 l4 T2 G— Avg_Slope = 温度与 V SENSE 曲线的平均斜率(以 mV/°C 或 μV/°C 表示), g% E6 ~/ i9 R3 T( A
有关 V 25 和 Avg_Slope 实际值的相关信息,请参见数据手册中的电气特性一节。' p+ c; S, |4 J
温馨提示
- v6 S6 T1 y& v! `2 a5 ]+ u! Z! c4 @
& v0 Q% o4 o& b1 Z$ w传感器从掉电模式中唤醒需要一个启动时间,启动时间过后其才能正确输出 V SENSE 。 ADC 在上电后同样需要一个启动时间,因此,为尽可能减少延迟间,应同时将 ADON 和 TSVREFE位置 1
( r+ g7 Y5 t+ Y" a+ i& }4 ~. a) t- D/ `5 Y/ A- ?
温度传感器的输出电压随温度线性变化。由于工艺不同,该线性函数的偏移量取决于各个芯片(芯片之间的温度变化可达 45 °C)。
- x; M6 b% H3 g0 n, L% S$ c6 @* q% A1 {) R) _. U- p5 l; o
内部温度传感器更适用于对温度变量而非绝对温度进行测量的应用情况。如果需要读取精确温度,则应使用外部温度传感器。2 S+ Q) Y0 s# _. I" i' L4 K
% E) N8 r$ t& f. ~
03. 硬件模块0 N! ~/ F: b1 ]4 q$ ]
用到的硬件资源有:
5 V0 E( ?$ m$ h' ]+ }
5 t/ Z  E9 Q4 y, D' A1) 指示灯 DS02 ~5 T0 E2 _8 D4 `& a+ O+ o% B9 P

+ W' P: y. l7 C3 F: @' u5 L3 G2) TFTLCD 模块6 V* o8 @& {8 l! Z7 L* T

1 Q, k0 o' U( Q/ l3) ADC
" l2 r  l" F/ P/ n2 B" l! p1 V5 j5 Q# r# g
4) 内部温度传感器
/ Z% Z$ h9 e! U* m; ?, ^/ O7 U/ j- ?) w& y# Y
04. 编程步骤" {4 _6 l" _, P! _) B
① 选择ADC_IN16或者ADC_IN16输入通道。
7 D  E3 i2 g2 V. U' s! ~0 s& V! z, }
: q& p- i, Y2 l  C: ~* X② 设置采样时间大于17.1us。, N# u  G! {3 g
8 z* \/ W& v) ~3 a
③ 设置ADC_CCR的TSVREFE位,打开内部温度传感器。2 o) k# ^/ f8 b1 G8 a# I

2 X! ?* m: r" G! Q2 f④ 设置ADC_CR2的SWSTART位启动转换。1 n9 c% a. I$ V0 \: Z

, y3 V$ v1 R3 A  V8 a+ p7 n$ a- S⑤ 读取ADC结果。
# Y/ g. S, Z6 A" n& s2 p1 m7 r1 p4 Z0 \/ V( H' n1 \
⑥ 计算。# w$ j( r1 e: E/ `' W4 A7 o

5 L7 G; F# M$ y05. 程序示例
. r8 K+ B. E5 y% d3 T初始化函数
9 g4 z6 i" R8 x, P% R  b7 U$ u, s0 A
- ~& H" U8 |2 @, w5 @6 u4 ~$ a
  1. //ADC通道初始化& I" Q6 O7 s: D1 I5 K9 N+ v8 a
  2. void ADC1_Init(void)
    # P! k2 ?. \1 q0 V9 N0 r
  3. {
    # a9 X0 k  g* W) B3 P! r
  4.         GPIO_InitTypeDef GPIO_InitStructure;& ]2 W4 d4 ]4 s7 N  g- v
  5.         ADC_CommonInitTypeDef ADC_CommonInitStructure;
    ! G$ d: S2 Y9 B6 ]0 I8 B
  6.         ADC_InitTypeDef ADC_InitStructure;1 d0 K4 n' v1 \. X- e. j7 L
  7.         
    ( b7 N2 ?& }* E$ K5 i4 a
  8.         //开启GPIO时钟 PA5" c$ q7 M& f- s9 j3 H5 t
  9.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    + d, ~  i4 j& X/ \! n. [+ F$ j2 w
  10.         8 ^9 b: G) |6 l1 N/ o
  11.         //开启ADC1时钟
    ( i& l9 _2 J6 D/ I
  12.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);        
    ( g5 p2 A) f8 y; \& Y2 J
  13.         
    ( [: d( t$ `% Z6 O' o5 Z
  14.         //GPIO初始化 初始化为模拟功能9 _8 P' s8 W; m3 }6 _0 Q4 `8 x
  15.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    + \: V: Z/ q: p9 H0 k/ q: U( W
  16.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;7 [5 L$ m& H. L' o
  17.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    + c# j* `% f; V0 t( V2 S3 c
  18.         GPIO_Init(GPIOA, &GPIO_InitStructure);+ L& E' L1 @2 g
  19.         8 F# B: G% p1 y7 O# L5 N
  20.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);          //ADC1复位
    ! k& K! ]( T; O
  21.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);        //复位结束        9 }! M/ Q* ]$ U8 g) x* Q" `
  22.         
    ' {, a- T/ r( Q0 ?9 @6 \/ O
  23. $ l( n8 |  w3 b' ~
  24.         //使能内部温度传感器7 {' M2 F! F8 K0 p( o7 T/ }' N
  25.         ADC_TempSensorVrefintCmd(ENABLE);
    ; g/ {5 W* ]0 ]9 |7 K
  26.         
    ) [$ G. i: g9 z3 ^3 W1 }. ]
  27.         //初始化ADC_CCR寄存器
    / \' X! n. t( C
  28. 6 J# W+ T+ ^* f6 |9 K; D3 t- G
  29.         ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
      L/ g* A% l* p7 |) `6 t
  30.         ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
    - P) m6 k. M7 d6 ^3 A
  31.         ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
    0 [) |! T7 G4 U$ J2 S- x2 B
  32.         ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;) S  J; l! y4 U- ~
  33.         ADC_CommonInit(&ADC_CommonInitStructure);
    6 d, P+ I( w4 x/ B) U  B
  34.         , R; b# n7 c1 {% J3 F
  35. / P: D" g6 C6 V+ M
  36.         //初始化ADC1
    3 k* }1 q: `  \
  37.         ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ( V  f- x6 ~# b4 ^
  38.         ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    : ^% Y( n; V  b% V, i: H4 p" d
  39.         ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    6 [2 R' i  I. M
  40.         ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    + k7 X1 F/ L5 S/ v3 F
  41.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    9 h# v; p3 ~  X$ Q/ R) C
  42.         ADC_InitStructure.ADC_NbrOfConversion = 1;
    4 X. i- w* d+ z* u7 E! ^6 e
  43. # I) o7 x, T! F$ f% W" s
  44.         ADC_Init(ADC1, &ADC_InitStructure);% U% O% }, s0 a" P* d7 X  t

  45. 7 r* l9 B$ \0 @( e
  46. ) U$ n. N/ y) ?& H
  47.         //设置ADC规则组通道 一个序列 采样时间4 L- D" i* O1 f/ m1 P. h7 B
  48.         ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_480Cycles);
    9 k% c! t9 A+ K. Q( @
  49.         ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_480Cycles);2 ]  T/ K! C* F2 j$ A
  50. ; Z5 O- h- C* ]
  51. : O5 ]+ y. c5 k2 Y/ L% I" a  x
  52.         //使能ADC
    " H) {4 N8 j2 h/ s+ V
  53.         ADC_Cmd(ADC1, ENABLE);
    3 R6 o% O- }9 b4 U, F4 L4 _, k* |
  54. }
复制代码

, h6 ^, j( f4 K: N3 ^/ Q获取温度值的函数
/ J' w! r; U# K4 ]
7 e1 u: K: c; t: ^$ d. E
  1. //获取温度值
    * k) W2 V7 x& `- Z2 q
  2. s16 Get_Temperature(void)+ X' _, I$ n  m, @3 ]. }
  3. {, ~' o8 g+ }+ i5 _% @( r3 E7 z, `
  4.         u32 value = 0;
    6 n( n5 h  v' q4 ~
  5.         s16 result = 0;8 Z& e1 Z* w4 f0 I$ u( v
  6.         double temperature = 0;! d  Q& E. e) ]% d% U
  7.         
    ! L1 F! c$ p, K" u3 C
  8.         //读取通道16内部温度传感器的值
    , h9 w' W7 P7 i0 ~& S# h
  9.         value = Get_Adc_Average(ADC_Channel_16, 10);
    & b5 D5 D# f3 t* \
  10.         + z) e3 r6 J) B7 A5 k; X9 n
  11.         //转化为电压值
    + y- X1 b; q3 D1 A. `% f
  12.         temperature = (float)value * (3.3 / 4096);
    + [' a( }8 v4 `/ x7 w
  13.         + D% o9 ?2 R: b  O5 ?; z1 A) w
  14.         //转化为温度值  I! N  {  f3 [. y  Z" d
  15.         temperature = (temperature - 0.76) / 0.0025 + 25;
    / ]4 E" n' `% X) p
  16.         temperature *= 100;
    & M- |% Z/ R; a! X; r- A
  17.         result = temperature;
    9 b+ b$ I: t6 F6 K) i! }7 g" {
  18.         3 c! F% ]2 y8 ^5 v  L* y/ m( K( f
  19.         return result;+ B" t  x, U& [- K2 P
  20. }
复制代码
; P  {( e- \! M3 n3 [
主函数
6 `  B3 q. x+ Y! W. l: U: P& u
9 `8 \# H% @: U5 D! k
  1. #include "sys.h"
    . F9 O# f/ `2 I# {9 P% O
  2. #include "delay.h"8 ~: A0 e/ M  ]. V3 I
  3. #include "usart.h"2 u2 Z( X: D4 C- [/ {3 i
  4. #include "led.h"( v% R* m( A0 U/ a. `) K
  5. #include "beep.h"
    + c4 z3 e, f. c; ?" p) p! i
  6. #include "key.h") b8 h3 ]2 V' u: ^% ]# u( o; E% j
  7. #include "usmart.h"
    3 `3 B0 m( g1 B' z0 x3 q) e( ]: e
  8. #include "lcd.h"
    1 [9 V2 ~  E7 t3 J0 ]0 ~$ I# Q
  9. #include "rtc.h") d3 }0 L6 k4 R  Y8 q
  10. #include "rng.h"
    8 S: D& ?3 s- _$ q3 a2 h- o' v
  11. #include "key.h"
    7 |. B! K" o, N# v: P/ {
  12. #include "wkup.h". u% S2 z2 T% h4 R& a. ]: U; D
  13. #include "adc.h"
    # B, ^7 ^) c+ \' y
  14. ! g/ h4 T/ M: J1 E0 a4 V5 q5 b
  15. int main(void)
    6 g& T& T# m0 C5 p: W
  16. { 8 U. z" c$ l* m, o8 g% I% M! i+ }
  17.         //u16 value = 0;+ l& |1 `& t# L8 \# Q& A
  18.         
    ' f% w/ X3 @, |/ p6 q5 [
  19.         s16 temp = 0;! {' D$ a, Z4 O, u5 s8 W3 Q

  20. : w# |# A, T; {9 g9 C: W
  21.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2& A0 F6 C$ Y" ?
  22.         2 o2 Q- p  K2 G& N0 E! C8 }4 w
  23.         delay_init(168);
    ' m! S# s& {3 @# M
  24.         , Q) l% s8 `) U" j
  25.         uart_init(115200);. B, X! H0 s) w: E  O6 N
  26.         
    0 t- H) ]0 m7 K; `0 Y% r
  27.         //usmart_dev.init(84);, C  P6 \) W4 W+ |) I4 x. g  L

  28. 7 V  l: B1 z$ w* T0 v
  29.         / f* o. d% Z% }* }& F
  30.         LED_Init();; p/ ]6 R; N+ k0 \: L1 N
  31.         
    ) @9 c' g9 U) k, X! A6 u1 m4 V# ?  o
  32.         
    5 W' E6 k# `" F/ _! t; t& T& w
  33.         LCD_Init();
    4 J* f, h8 @5 D* N9 y, q4 Q: @  K

  34. 9 G. i1 E9 `) V# J$ }7 X" y( A$ @
  35.         ADC1_Init();* V7 y' w% d; k: v3 |
  36.         , J: F3 M" e6 i, B( \
  37.                
    . s% t8 c% L8 B; J$ z+ }4 e
  38.         POINT_COLOR = RED;6 h1 o( {: o! E$ ]' v% y
  39.         ! W+ h# M9 K+ Y0 K: M
  40.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        ' G) W" ]% W6 I, _+ d
  41.         LCD_ShowString(30,70,200,16,16,"Temperature TEST");        
    / @0 ]( O) D5 V2 Q
  42.         LCD_ShowString(30,90,200,16,16,"ATOM@tom");! g' h1 l. \: \  s6 e
  43.         LCD_ShowString(30,110,200,16,16,"2020/09/13");         
    ) S9 ~; g$ ?+ P$ m3 f( h: @
  44.         1 Z/ m3 l- W- Q" s) a3 U4 H  j
  45.         //设置字体为蓝色
    7 u! n. L7 a8 R( U
  46.         POINT_COLOR = BLUE;
    9 ^5 s, W+ s: y9 e3 l$ b5 {
  47.         LCD_ShowString(30,140,200,16,16,"Temperate:00.00C");         
    0 M* A$ k. I1 C" v# O, {, m
  48.                 8 S& C3 d# i/ E
  49.         while(1)
    ' O, y8 T* N9 d1 z+ R
  50.         {
    4 \; w) m2 l% L9 g; ~
  51.                 //得到温度值
    7 d$ M8 F7 l& M: P0 ]
  52.                 temp = Get_Temperature();5 K0 P0 P1 N6 k  V; ?( v
  53.                
    & T' ]2 T! X! o2 s8 L+ N  W0 C
  54. 3 ^' o0 x+ x% U7 V& w6 [2 k
  55.                 printf("temperature: %f\r\n", (float)temp / 100);
    ! Q) j6 _3 [7 l- w8 P( N# ^
  56.                 2 H' P; [0 O: ^  d
  57.                 LED1 = !LED1;- P! q/ j. x4 K% d) C2 Y
  58.                 2 ?+ D  W$ Y# O7 }
  59.                 delay_ms(250);7 ~! F7 W# c# C4 |' {3 Y
  60.         }! ^& Z1 ]/ ^, W4 y+ d: a/ W1 J# s7 ^0 e
  61. }
    5 B8 |+ y4 S# h8 q! ?. P3 \
复制代码

/ _0 o/ U( h, ^. R9 a
$ t$ G7 Z3 ~: q0 M' D, R' Z4 f* d7 X& b6 S

) N: |: h# i5 V6 d
赞 收藏 评论0 发布时间:2022-3-29 10:00

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版