概述
常见的AVR单片机内都包含一个温度传感器,用于监测异常高温,便于通过编程为单片机提供保护。
用于Arduino主控芯片的常见的AVR单片机列表如下:
MCU | 是否内嵌温度传感器 |
---|---|
ATmega8 | No |
ATmega8L | No |
ATmega8A | No |
ATmega168 | No |
ATmega168A | Yes |
ATmega168P | Yes |
ATmega328 | Yes |
ATmega328P (Arduino UNO\MiNi\Pro MINI) | Yes |
ATmega1280 (Arduino Mega) | No |
ATmega2560 (Arduino Mega 2560) | No |
ATmega32U4 (Arduino Leonardo) | Yes |
通过上表可以看出:常用的Arduino UNO可以作为临时温度传感器使用。
今天的实验,我们就通过编程来读取ATmega328P内部温度计的读数。
实验分析
由于通电电阻的热效应,只有刚开机时AVR单片机的温度才是室温,随后随着MCU工作产热,温度会有上升。
程序里提供的温度单位是摄氏度,由串口监视窗口显出,准确性依赖于GetTemp函数里t的线性转换公式,你可以改变104.31这个数来校准读数。
实验代码
// Internal Temperature Sensor
// Example sketch for ATmega328 types.
void setup(){
Serial.begin(9600);
Serial.println(F("Internal Temperature Sensor"));
}
void loop(){
// Show the temperature in degrees Celcius.
Serial.println(GetTemp(),1);
delay(1000);
}
double GetTemp(void){
unsigned int wADC;
double t;
// The internal temperature has to be used
// with the internal reference of 1.1V.
// Channel 8 can not be selected with
// the analogRead function yet.
// Set the internal reference and mux.
ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
ADCSRA |= _BV(ADEN); // enable the ADC
delay(20); // wait for voltages to become stable.
ADCSRA |= _BV(ADSC); // Start the ADC
// Detect end-of-conversion
while (bit_is_set(ADCSRA,ADSC));
// Reading register "ADCW" takes care of how to read ADCL and ADCH.
wADC = ADCW;
// The offset of 324.31 could be wrong. It is just an indication.
t = (wADC - 104.31 ) / 1.22;
// The returned temperature is in degrees Celcius.
return (t);
}
参考文档
Atmel官方校准AVR内部温度的参考文档
一篇与本文相关的技术文档
一些测量确定偏移量和获得
内部温度传感器可以用作一个随机数种子
未完待续。。。
感谢一直关注着禾灮成长进步的朋友们。你们的信任、支持和鼓励,鞭策着我们一路走到了今天。
感谢所有的合作伙伴,我们相互促进,共同见证了彼此的成长。
感谢所有曾经在禾灮彼此倚靠、相互鼓励、携手同心、砥砺同行的兄弟姐妹。这里承载了我们的青春与热血。
禾灮,感谢有你。
未来,我们将一如既往,砥砺前行。
禾灮·小楊
2018.07.20