Arduino+STM32+DS18B20溫度傳感器
DB18B20 是一個長得像三極管的溫度傳感器,平的那一面對著我們,從左到右分別是 GND、DQ、VDD 引腳。接的時候最好在 DQ 和 VDD 之間加一個 4.7K 的上拉電阻維持高電平。
一共三個文件:
ds18b20.h用于封裝 DS18B20 的庫的頭文件ds18b20.cpp用于封裝 DS18B20 的庫文件main.inoArduino 主程序
打開 Arduino IDE,在“開發板管理器”中安裝 STM32 MCU based boards,然后選擇自己的開發板對應的型號。

先選擇開發板,然后才能用它附帶的頭文件。
(1) ds18b20.h
#ifndef __DS18B20_H
#define __DS18B20_H
bool ds18b20_reset(void);
void write_bit(bool value);
bool read_bit(void);
void write_byte(uint8_t data);
uint8_t read_byte(void);
float read_temperature(void);
#endif
(2) ds18b20.cpp
注意:把下面的 PB12 換成你自已的引腳。
#include "ds18b20.h"
const int DS18 = PB12; //連接DS18B20的引腳,這里以PB12引腳為例
/* 初始化18B20,成功返回1,失敗返回0 */
bool ds18b20_reset(void){
pinMode(DS18, OUTPUT);
digitalWrite(DS18,LOW); //1、先拉低,保持480~960微秒
delayMicroseconds(480);
pinMode(DS18, INPUT_PULLUP); //2、釋放總線,上拉電阻將其拉高,保持15~60微秒
delayMicroseconds(70);
bool presence = !digitalRead(DS18); //3、18B20會拉低總線60~240微秒作為應答
delayMicroseconds(410); //此處的延時從剛才拉高開始算,至少480微秒(480-70=410)
return presence;
}
/* 往18B20寫入數據 */
void write_bit(bool value){
pinMode(DS18, OUTPUT);
digitalWrite(DS18, LOW); //1、先拉低,等待1微秒(15微秒內)
delayMicroseconds(1);
if (value){ //2、如果寫1,就把引腳拉高,否則保持低電平。然后等待60微秒
pinMode(DS18, INPUT_PULLUP);
}
delayMicroseconds(60);
pinMode(DS18, INPUT_PULLUP); //3、最后把引腳拉高
}
/* 讀取18B20的數據 */
bool read_bit(void){
pinMode(DS18, OUTPUT);
digitalWrite(DS18, LOW); //1、先拉低,等1微秒;
delayMicroseconds(1);
pinMode(DS18, INPUT_PULLUP); //2、再拉高(并釋放總線),等10微秒;
delayMicroseconds(10);
bool bit_val = digitalRead(DS18); //3、讀取引腳的值,再等60微秒左右;
delayMicroseconds(55);
return bit_val;
}
void write_byte(uint8_t data){
for (uint8_t i=0; i<8; i++){
write_bit(data & 0x01); //低位先發送
data >>= 1;
}
}
uint8_t read_byte(void){
uint8_t data = 0;
for (uint8_t i=0; i<8; i++){
data |= (read_bit() << i); //低位先接收
}
return data;
}
float read_temperature(void){
if (!ds18b20_reset()) return NAN;
write_byte(0xCC); //0xCC:跳過ROM檢測(因為只有一個設備)
write_byte(0x44); //0x44:溫度轉換命令
//等待轉換完成(12-bit精度約需750ms)
pinMode(DS18, INPUT_PULLUP);
unsigned long start = millis();
delay(700);
//18B20在轉換時會把總線拉低(表示“忙”),完成后才釋放(自動被拉高)
while (!digitalRead(DS18)){
//如果時間太久了就放棄
if (millis() - start >= 1000) return NAN;
delay(1);
}
//轉換完成后要重新建立通信!
if (!ds18b20_reset()) return NAN;
write_byte(0xCC); //0xCC:跳過ROM檢測(必需)
write_byte(0xBE); //0xBE:讀取暫存器命令
uint8_t temp_low = read_byte();
uint8_t temp_high = read_byte();
int16_t temp = (temp_high << 8) | temp_low;
return temp / 16.0; //12-bit精度要乘以0.0625
}
(3) main.ino
注意:下面的 PA10 是 RX 引腳,PA9 是 TX。
#include "ds18b20.h"
// RX TX
HardwareSerial Serial1(PA10, PA9);
void setup() {
Serial1.begin(115200);
}
void loop() {
float temperature = read_temperature();
if (!isnan(temperature)){
Serial1.print("Temperature:");
Serial1.println(temperature);
} else {
Serial1.println("ERROR");
}
delay(1000);
}
最后燒錄,打開串口監視器查看。

浙公網安備 33010602011771號