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号