单总线编程介绍(用于DS18B20)

本文详细介绍了单总线(1-Wire BUS)通信协议的工作原理,包括其电路规范、时序结构以及C语言实现的主机发送和接收函数。单总线仅需一根线即可实现双向传输,简化了硬件设计。通过主机拉低总线不同时间长度来区分发送0和1,并通过从机的响应进行数据交互。
摘要由CSDN通过智能技术生成

单总线介绍

单总线(1-Wire BUS)是由Dallas公司开发的一种通用数据总线
一根通信线:DQ
异步、半双工
单总线只需要一根通信线即可实现数据的双向传输,当采用寄生供电时,还可以省去设备的VDD线路,此时,供电加通信只需要DQ和GND两根线

单总线的电路规范

设备的DQ均要配置成开漏输出模式(与I2C总线相似)
DQ添加一个上拉电阻,阻值一般为4.7KΩ左右(与I2C总线相似)
若此总线的从机采取寄生供电,则主机还应配一个强上拉输出电路

单总线时序结构

初始化:

主机将总线拉低至少480us,然后释放总线,等待15 ~ 60us后,存在的从机会拉低总线60 ~ 240us以响应主机,之后从机将释放总线

在这里插入图片描述

sbit OneWire_DQ = P3^7;		//DS18B20d
/**
  * @brief单总线初始化
  * @param无
  * @retval返回从机应答值,0为应答,1为不应答
  */
unsigned char OneWire_Init()
{
	unsigned char i;
	unsigned char AckBit;
	OneWire_DQ = 1;
	OneWire_DQ = 0;
	i = 247;while (--i);	//使用STC-ISP生成的500us延时
	OneWire_DQ = 1;
	i = 47;while (--i);		//延时100us
	AckBit = OneWire_DQ;
	i = 247;while (--i);	//延时500us
	return AckBit;
}

发送一位:

主机将总线拉低60 ~ 120us,然后释放总线,表示发送0;主机将总线拉低1~15us,然后释放总线,表示发送1。从机将在总线拉低30us后(典型值)读取电平,整个时间片应大于60us

想发送0则按左边的时序,想发送1则按右边的时序

在这里插入图片描述

/**
  * @brief 主机发送一位
  * @param 要发送的数据位
  * @retval无
  */
void OneWier_SendBit(unsigned char Bit)
{
	unsigned char i;
	OneWire_DQ = 0;
	i = 4;while (--i);		//延时10us
	OneWire_DQ = Bit;
	i = 24;while (--i);		//延时50us
	OneWire_DQ = 1;
}

接收一位:

主机将总线拉低1~15us,然后释放总线,并在拉低后15us内读取总线电平(尽量贴近15us的末尾),读取为低电平则为接收0,读取为高电平则为接收1 ,整个时间片应大于60us

在这里插入图片描述

/**
  * @brief主机接收一位
  * @param无
  * @retval返回接收到的位
  */
unsigned char OneWire_ReceiveBit()
{
	unsigned char i;
	unsigned char Bit;
	OneWire_DQ = 0;			//先将总线拉低
	i = 2;while (--i);		//延时5us
	OneWire_DQ = 1;			//释放总线
	i = 2;while (--i);		//延时5us
	Bit = OneWire_DQ;		//读取总线
	i = 24;while (--i);		//延时50us
	return Bit;
}

解释:

主机接收0:主机拉低总线几us后,释放总线,如果从机立马拉低总线,则表示从机想发送0,主机应该在15us的末尾读取总线状态0

主机接收1:主机拉低总线后,释放总线,从机并没有拉低总线,则表示从机想发送1,主机在15us末尾读取总线状态1

发送一个字节:

连续调用8次发送一位的时序,依次发送一个字节的8位(低位在前)

在这里插入图片描述

/**
  * @brief 发送一个字节
  * @param要发送的数据
  * @retval无
  */
void OneWire_SendByte(unsigned char Data)
{
	unsigned char i;
	for(i = 0; i < 8; i++)
	{
		OneWier_SendBit(Data & (0x01<<i));
	}
}

接收一个字节:

连续调用8次接收一位的时序,依次接收一个字节的8位(低位在前)

在这里插入图片描述

/**
  * @brief 接收一个字节
  * @param无
  * @retval返回接收到的数据
  */
unsigned char OneWire_ReceiveByte()
{
	unsigned char i;
	unsigned char Data = 0x00;
	for(i = 0; i < 8; i++)
	{
		if(OneWire_ReceiveBit()){Data|=(0x01<<i);}
	}
	return Data;
}
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值