Arduino+STM32+DS18B20温度传感器

DB18B20 是一个长得像三极管的温度传感器,平的那一面对着我们,从左到右分别是 GND、DQ、VDD 引脚。接的时候最好在 DQ 和 VDD 之间加一个 4.7K 的上拉电阻维持高电平。

一共三个文件:

  • ds18b20.h 用于封装 DS18B20 的库的头文件
  • ds18b20.cpp 用于封装 DS18B20 的库文件
  • main.ino Arduino 主程序

打开 Arduino IDE,在“开发板管理器”中安装 STM32 MCU based boards,然后选择自己的开发板对应的型号。

我用的是5块钱包邮的STM32F103 C6T6

先选择开发板,然后才能用它附带的头文件。

(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);
}

最后烧录,打开串口监视器查看。

posted @ 2025-04-28 22:08  Hemmelfort  阅读(195)  评论(0)    收藏  举报