forked from stm32-rs/stm32h7xx-hal
-
Notifications
You must be signed in to change notification settings - Fork 1
/
temperature.rs
89 lines (71 loc) · 2.3 KB
/
temperature.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//! Example for using ADC3 to read the internal temperature sensor
//!
//! For an example of using ADC1, see examples/adc.rs
//! For an example of using ADC1 and ADC2 together, see examples/adc12.rs
#![no_main]
#![no_std]
use cortex_m_rt::entry;
#[macro_use]
mod utilities;
use stm32h7xx_hal::{
adc,
delay::Delay,
pac,
prelude::*,
signature::{TS_CAL_110, TS_CAL_30},
};
use log::info;
#[entry]
fn main() -> ! {
utilities::logger::init();
let cp = cortex_m::Peripherals::take().unwrap();
let dp = pac::Peripherals::take().unwrap();
// Constrain and Freeze power
info!("Setup PWR... ");
let pwr = dp.PWR.constrain();
let pwrcfg = example_power!(pwr).freeze();
// Constrain and Freeze clock
info!("Setup RCC... ");
let rcc = dp.RCC.constrain();
let ccdr = rcc
.sys_ck(100.mhz())
.pll2_p_ck(4.mhz()) // Default adc_ker_ck_input
.freeze(pwrcfg, &dp.SYSCFG);
info!("");
info!("stm32h7xx-hal example - Temperature");
info!("");
let mut delay = Delay::new(cp.SYST, ccdr.clocks);
// Setup ADC
#[cfg(not(feature = "rm0455"))]
let mut adc =
adc::Adc::adc3(dp.ADC3, &mut delay, ccdr.peripheral.ADC3, &ccdr.clocks);
// On RM0455 parts, the temperature sensor is on ADC2
#[cfg(feature = "rm0455")]
let mut adc = adc::Adc::adc2(
dp.ADC2,
&mut delay,
ccdr.peripheral.ADC12,
&ccdr.clocks,
);
// Set resolution
adc.set_resolution(adc::Resolution::SIXTEENBIT);
// Setup Temperature Sensor on the disabled ADC
let mut channel = adc::Temperature::new();
channel.enable(&adc);
delay.delay_us(25_u16);
let mut adc = adc.enable();
let vdda = 2.500; // Volts
loop {
let word: u32 =
adc.read(&mut channel).expect("Temperature read failed.");
// Average slope
let cal = (110.0 - 30.0)
/ (TS_CAL_110::get().read() - TS_CAL_30::get().read()) as f32;
// Calibration values are measured at VDDA = 3.3 V ± 10 mV
let word_3v3 = word as f32 * vdda / 3.3;
// Linear interpolation
let temperature =
cal * (word_3v3 - TS_CAL_30::get().read() as f32) + 30.0;
info!("ADC reading: {}, Temperature: {:.1} °C", word, temperature);
}
}