1、单总线只有一根数据线,设备(主机或从机)通过一个漏极开路或三态端口,连接至该数据线,这样允许设备在不发送数据时释放数据总线,以便总线被其它设各所使用。单总线端口为漏极开路,其内部等效电路下图所示:
单总线电路外接一个约5K的上拉电阻,由于设置的单片机引脚是开漏输出,所以当单总线处于空闲状态时为高电平,如果总线保持低电平超过480us,总线上的所有器件将复位。另外,在寄生方式供电时,为了保证单总线器件在某些工作状态下(如温度转换期间、EEPROM写入等)具有足够的电源电流,必须在总线上提供强上拉。
2、配置端口为开漏输出
c
#ifndef __DRIVER_DS18B20_H__
#define __DRIVER_DS18B20_H__
#include <stdint.h>
/*******修改这部分可更换ds18b20引脚**********/
#define DS18B20_GPIO_PORT GPIOC
#define DS18B20_GPIO_PIN GPIO_PIN_3
//单总线的复位功能:
uint8_t one_wire_reset(void);
//单总线发送一个bit的功能:
void one_wire_send1Bit(uint8_t bit);
//单总线发送一个字节的功能:
void one_wire_write1Byte(uint8_t byte);
//单总线上读取一个bit功能:
uint8_t one_wire_recv1Bit(void);
//单总线上读取一个字节的功能:
uint8_t one_wire_read1Byte(void);
//从ds18b20芯片上读取温度:
float get_DS18B20_Temp(void);
#endif
c
#include "driver_ds18b20.h"
#include "gpio.h"
#include "tim2Udelay.h"
#include "FreeRTOS.h"
// 单总线的复位功能:
uint8_t one_wire_reset(void)
{
// 主机主动拉低单总线电平为低电平:
HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_RESET);
// 维持480us:
tim2_u_delay(480);
// 释放单总线:
HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_SET);
tim2_u_delay(60);
GPIO_PinState status = HAL_GPIO_ReadPin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN);
tim2_u_delay(480);
return status == GPIO_PIN_RESET;
}
// 单总线发送一个bit的功能:
void one_wire_send1Bit(uint8_t bit)
{
if (bit == 1)
{
HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_RESET);
tim2_u_delay(2);
HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_SET);
tim2_u_delay(60);
}
else
{
HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_RESET);
tim2_u_delay(60);
HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_SET);
tim2_u_delay(2);
}
}
// 单总线发送一个字节的功能:
void one_wire_write1Byte(uint8_t byte)
{
for (int i = 0; i < 8; i++)
{
one_wire_send1Bit(byte & 0x01);
byte = byte >> 1;
}
}
// 单总线上读取一个bit功能:
uint8_t one_wire_recv1Bit(void)
{
// 发起读取标记:
HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_RESET);
tim2_u_delay(2);
// 主机释放单总线:
HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_SET);
tim2_u_delay(12);
uint8_t bit = HAL_GPIO_ReadPin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN);
tim2_u_delay(50);
return bit;
}
// 单总线上读取一个字节的功能:
uint8_t one_wire_read1Byte(void)
{
uint8_t data = 0;
for (int i = 0; i < 8; i++)
{
data = data >> 1;
if (one_wire_recv1Bit())
{
data |= 0x80;
}
}
return data;
}
// 从ds18b20芯片上读取温度:
float get_DS18B20_Temp(void)
{
//1.复位单总线:
one_wire_reset();
//2.发送跳过ROM的命令
one_wire_write1Byte(0xcc);
//3.开启温度转换:
one_wire_write1Byte(0x44);
//4.等待数据转换(750ms)
HAL_Delay(750);
//vTaskDelay(750);
//5.再次复位
one_wire_reset();
//6.发送跳过ROm的命令
one_wire_write1Byte(0xcc);
//7.发送读取读暂存寄存器的命令
one_wire_write1Byte(0xbe);
//8.读取暂存寄存器的低八位与高八位,两个字节
uint8_t temp_LSB = one_wire_read1Byte();
uint8_t temp_MSB = one_wire_read1Byte();
uint16_t temp = temp_MSB << 8 | temp_LSB;
//9.把ds18b20的数据转换为浮点值:
if((temp & 0xf800) > 0)//负温度
{
temp = temp & 0x7ff;
return -temp * 0.0625;
}
//正温度:
temp = temp & 0x7ff;
return temp * 0.0625;
}
3、红外遥控器

原理,使用定时器的输入捕获功能,记录两个下降沿的之间的周期,1120us就是0,2250us代表1,这样就能得到32位的数据
使能中断