单总线协议

目录

单总线说明

dht11的单总线格式

读取dht11数据步骤

dht11单总线协议实现


单总线说明

        单总线即只有一根数据线,系统中的数据交换、控制均由单总线完成。设备(主机或从机)通过一个漏极开路或三态端口连至该数据线,以允许设备在不发送数据时能够释放总线,而让其它设备使用总线;单总线通常要求外接一个约 4.7kΩ 的上拉电阻,这样,当总线闲置时,其状态为高电平。由于它们是主从结构,只有主机呼叫从机时,从机才能应答,因此主机访问器件都必须严格遵循单总线序列,如果出现序列混乱,器件将不响应主机。

下面以DHT11温湿度传感器来介绍单总线协议:

dht11的单总线格式

数据格式

8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据 + 8bit 校验位。注:其中湿度小数部分为 0。

校验位数据
“8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据” 8bit 校验位等于
所得结果的末 8 位。

完整数据采集时序:

数据时序图

 注意主机从 DHT11 读取的温湿度数据总是前一次的测量值,如两次测间隔时间很长,请连续读两次以第二次获得的值为实时温湿度值。

读取dht11数据步骤

步骤一:DHT11 上电后(DHT11 上电后要等待 1S 以越过不稳定状态在此期间不能发送任何指令),测试环境温湿度数据,并记录数据,同时 DHT11 的 DATA 数据线由上拉电阻拉高一直保持高电平;此时 DHT11 的DATA 引脚处于输入状态,时刻检测外部信号。空闲态:高电平。

步骤二:微处理器的 I/O 设置为输出同时输出低电平,且低电平保持时间不能小于 18ms(最大不得超过 30ms),然后微处理器的 I/O 设置为输入状态,由于上拉电阻,微处理器的 I/O 即 DHT11 的 DATA 数据线也随之变高,等待 DHT11 作出回答信号,发送信号如图所示:

主机发送起始信号

步骤三:DHT11 的 DATA 引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后 DHT11 的 DATA引脚处于输出状态,输出 83 微秒的低电平作为应答信号,紧接着输出 87 微秒的高电平通知外设准备接收数据,微处理器的 I/O 此时处于输入状态,检测到 I/O 有低电平(DHT11 回应信号)后,等待 87 微秒的高电平后的数据接收,发送信号如图所示:

步骤四:由 DHT11 的 DATA 引脚输出 40 位数据,微处理器根据 I/O 电平的变化接收 40 位数据,位数据“0”的格式为: 54 微秒的低电平和 23-27 微秒的高电平,位数据“1”的格式为: 54 微秒的低电平加 68-74微秒的高电平。位数据“0”、“1”格式信号如图所示:

结束信号:DHT11 的 DATA 引脚输出 40 位数据后,继续输出低电平 54 微秒后转为输入状态,由于上拉电阻随之变为高电平。但 DHT11 内部重测环境温湿度数据,并记录数据,等待外部信号的到来。

dht11单总线协议实现

头文件:dht11.h

#ifndef _DHT11_H_
#define _DHT11_H_

#include "stm32f10x.h"

typedef struct{
	u8 humH;
	u8 humL;
	u8 temH;
	u8 temL;
}DHT11_Dat;

extern DHT11_Dat dht11_dat;

void DHT11_Init(void); //温湿度传感器初始化
u8 DHT11_ReadDat(void);//获取温湿度数据
#endif

源文件:dth11.c

#include "dht11.h"
#include "delay.h"

#define DHT11_LOW  GPIO_ResetBits(GPIOG,GPIO_Pin_11)
#define DHT11_HIG  GPIO_SetBits(GPIOG,GPIO_Pin_11)
#define DHT11_READ GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_11)

DHT11_Dat dht11_dat;

//温湿度模块初始化,PG11
void DHT11_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_Init(GPIOG,&GPIO_InitStruct);
	DHT11_HIG;
}

/*DHT11获取数据函数
参数:温湿度数据结构体指针
返回值:0响应失败;1响应成功;2校验失败
*/
u8 DHT11_ReadDat(void)
{				   // buf[0]   buf[1]    buf[2]   buf[3]    buf[4]
	u8 buff[5]={0};//湿度高8位 湿度低8位 温度高8位 温度低8位 校验位
	u8 timeout = 255;
	u8 ack=0,i,j;
	
	DHT11_LOW;
	Delay_ms(20);
	DHT11_HIG;
	
	//等待响应,高电平持续时间
	while(DHT11_READ && (timeout--))
		Delay_us(1);timeout=255;
	
	//等待响应结束
	while(!DHT11_READ && (timeout--))
		Delay_us(1);timeout=255;
	ack = DHT11_READ;
	
	for(i=0;i<5;i++)
		for(j=0;j<8;j++)
		{	
			while(DHT11_READ && (timeout--))
				Delay_us(1);timeout=255;
			
			//低电平持续时间 54us
			while(!DHT11_READ && (timeout--))
				Delay_us(1);timeout=255;
			
			Delay_us(30);//数据0高电平持续时间(23us-27us)
			
			//读取一位数据
			if(DHT11_READ == 0)
				buff[i] &= ~(0x1<<(7-j)); 
			else
				buff[i] |= (0x1<<(7-j)); 
		}
	
	if(buff[4] != buff[0]+buff[1]+buff[2]+buff[3])
	{
		return 2;//本次接收的数据不正确,放弃,重新接收数据
	}
	dht11_dat.humH = buff[0];
	dht11_dat.humL = buff[1];
	dht11_dat.temH = buff[2];
	dht11_dat.temL = buff[3];
	return ack;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值