-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mcu temperature sensor #163
Comments
From the Reference manual, section 15.3.30: *The temperature sensor is internally connected to the ADC1_IN16 input channel which is used to convert the sensor’s output voltage to a digital value. * . So, what you said applies broadly to the 303 family. The instructions, from the RM:
From the reference manual, we find V25 is typically 1.43, and avg slope is 4.3. Minimum sampling time is 2.2µs. This gives a reasonable reading on my end, but needs a qc. /// Check the temperature of the MCU. Output in voltage.
/// See reference manual, 15.3.30
pub fn read_mcu_temp(adc1_2: &mut pac::ADC1_2, adc: &mut pac::ADC1) -> f32 {
// 1. Select the ADC1_IN16 input channel (with the appropriate sampling time).
adc.cr.modify(|_, w| w.aden().enable());
// while adc.isr.read().adrdy().is_not_ready() {}
adc.sqr1.modify(|_, w|
unsafe { w.sq1().bits(16) }
);
// 2. Program with the appropriate sampling time (refer to electrical characteristics section of
// the STM32F3xx datasheet). Required sampling time: >= 2.2μs. Given common ADC
// frequencies in the 12 - 48Mhz range, using the minimum sample time of 1.5 clock
// cycles is adqeuate.
adc.smpr2.modify(|_, w| w.smp16().bits(0b000));
// 3. Set the TSEN bit in the ADC1_CCR register to wake up the temperature sensor from
// power-down mode.
adc1_2.ccr.modify(|_, w| w.tsen().enabled());
// 4. Start the ADC conversion.
adc.cr.modify(|_, w| w.adstart().start());
// while adc.isr.read().eos().is_not_complete() {}
adc.isr.modify(|_, w| w.eos().clear());
// 5. Read the resulting VTS data in the ADC data register.
let vts = adc.dr.read().rdata().bits();
// 6. Calculate the actual temperature using the following formula:
// Temperature (in °C) = {(V25 – VTS) / Avg_Slope} + 25
// Where:
// – V25 = VTS value for 25° C
// – Avg_Slope = average slope of the temperature vs. VTS curve (given in mV/°C or
// µV/°C)
((1.43 - vts as f32) / 4.3) + 25.
} To call it: let t = read_mcu_temp(&mut dp.ADC1_2, &mut dp.ADC1); You may be able to use the existing If this works for you, please submit it as a PR. |
@David-OConnor I'm a newbie so may be doing something simple wrong, but when I try your code in a loop I get 25.332558 C and no sensitivity to an increase if I put my finger on the processor to warm it up. I changed the code as below and see that the vts value is always zero. (I also had to remove some characters in comments and strings that the compiler did not like on my system. I don't think I changed any code.) Any idea what I'm doing wrong, or what I should try to debug it?
|
I probably missed one or more steps in ADC setup. The fact I had to comment out those while loops should have been the red flag! |
There does not seem to be any way to connect to the mcu temperature sensor. (On Discovery-stm32f303 I think this uses an internal connection to ADC1 on channel 16,) In stm32f1xx-hal this is done by having a special method
.read_temp()
and in stm32f4xx-hal it is done by having a structureTemperature
which takes the place of a channel attached to a pin in method.read(&mut Temperature)
, but I don't see any mechanism in stm32f3xx-hal.The text was updated successfully, but these errors were encountered: