I2C协议之软件模拟(二)-- 实际应用之SHT20

软件模拟I2C实际应用之读写SHT20温湿度传感器。

一、SHT20通讯定义

(1)设备I2C地址:0x40;
(2)命令:
I2C协议之软件模拟(二)-- 实际应用之SHT20_第1张图片
测量温度和湿度都有两种模式:主机模式和非主机模式,这两种模式的区别在于测量期间(发出测量命令后需要等待一段时间才能读取)是否允许主机与别的I2C设备通信。在保持主机模式下,发出测量命令后,在测量完成之前传感器会一直拉低SCL,迫使主机进入等待状态,传感器内部处理完成会释放SCL,主机就可以读数据了。在非保持主机模式下,发出测量命令后,传感器不会拉低SCL,主机需要轮询接收数据,如果传感器内部处理未完成,不会发出ACK信号,主机需要重新启动传输时序。两种模式的时序如下图。
Hold Mater模式
I2C协议之软件模拟(二)-- 实际应用之SHT20_第2张图片
No Hold Master模式
I2C协议之软件模拟(二)-- 实际应用之SHT20_第3张图片

二、SHT20驱动代码

下面代码中i2c相关函数见I2C协议之软件模拟(一)
Hold Master模式

uint16_t sht20_read_temperature(void)
{
	uint16_t temp = 0;
	uint8_t checksum = 0;
	i2c_start();
	//发送从机地址和写位
	i2c_send(0x80);
	//发送测量温度命令,主机模式
	i2c_send(0xE3);
	i2c_start();
	//发送从机地址和读位
	i2c_send(0x81);
	//等待传感器内部处理完成
	delay_ms(100);
	//开始读温度数据的高八位
	temp = ((uint16_t)i2c_receive()) << 8;
	i2c_send_ack();
	//读温度数据的低八位
	temp |= (uint16_t)i2c_recevie();
	i2c_send_ack();
	//读校验和
	checksum = i2c_receive();
	i2c_send_no_ack();
	i2c_stop();
	return temp;
}

No Hold Master模式

uint16_t sht20_read_temperature(void)
{
	uint16_t temp = 0;
	uint8_t checksum = 0;
	i2c_start();
	//发送从机地址和写位
	i2c_send(0x80);
	//发送测量温度命令,非主机模式
	i2c_send(0xF3);
	i2c_start();
	//发送从机地址和读位,若没有ACK信号,说明传感器内部未处理完成,继续发送读时序
	while(i2c_send(0x81) == 0)
	{
		//等待传感器内部处理完成
		delay_ms(100);
	}

	//开始读温度数据的高八位
	temp = ((uint16_t)i2c_receive()) << 8;
	i2c_send_ack();
	//读温度数据的低八位
	temp |= (uint16_t)i2c_recevie();
	i2c_send_ack();
	//读校验和
	checksum = i2c_receive();
	i2c_send_no_ack();
	i2c_stop();
	return temp;
}

测量湿度同上,只需将查询命令0xE3换成0xE5,0xF3换成0xF5。
上面的驱动代码中延时100ms是因为传感器内部测量需要时间,具体需要多长时间,测量精度越高时间越久,见下图:
I2C协议之软件模拟(二)-- 实际应用之SHT20_第4张图片
注意事项:
1、如果接收到温湿度数据是0xFFFF,很可能是因为传感器内部处理完成前读取了数据,代码上处理不当—>主机未等到传感器回复ACK信号,就读取了SDA数据;
2、发送读时序(0x81)之后,传感器不会马上回应ACK信号,而是内部处理完成之后才会回应ACK。

你可能感兴趣的:(总线协议)