SHT20温湿度传感器

目录

一、SHT20特点

二、SHT20的通信及配置

1、通信方式

2、器件命令

3、软复位时序 

4、用户寄存器配置

三、SHT20获取温湿度

四、程序设计

①IIC通信相关程序

②SHT20相关程序


传感器和控制模块的分类:

        通过电平信号来检测或者控制

        通过ADC转换获取数据

        通过通信来获取数据或者控制---->IIC SPI USART 自定义

一、SHT20特点

①通信接口:IIC

②可以测量温湿度

③分辨率可以设置

④器件地址:0x80(写)  和 0x81(读)

二、SHT20的通信及配置

1、通信方式

通过手册已经知道要用IIC通信:

IIC所有IO口初始化配置函数

IIC起始信号函数

IIC停止信号函数

IIC发送应答/不应答函数

IIC检测应答/不应答函数

IIC发送一个字节数据函数

IIC接收一个字节数据函数

在多个传感器共用一个通信方式的情况下,为了方便使用,可以单独创建一个通信文件;

当只有单个传感器用一个通信方式的情况下,可以跟这个传感器共用同一个文件

2、器件命令

主机模式:在SHT20测量过程中,SCL锁定.挂载在同一个IIC总线上的其他设备是不能通信

非主机模式:在SHT20测量过程中,SCL开放.挂载在同一个IIC总线上的其他设备是能通信

根据需求:选择用非主机模

3、软复位时序 

所以:封装一个软复位函数,调用在初始化中

4、用户寄存器配置

用户寄存器中有保留位,要配置此寄存器,先将寄存器中的所有值读出到一个变量,改变要配置的位,预留位不要动,然后再将变量写入到寄存器中.

经过分析,寄存器的值都用默认值,所以不需要配置此寄存器.

三、SHT20获取温湿度

根据时序图测量温度或湿度过程

思路:

/*发送测量命令*/

起始信号

主机发送器件地址(W)

主机检测应答/不应答信号

主机发送测温度/湿度命令

主机检测应答/不应答信号

/*等待测量完成*/

do

{

起始信号

主机发送器件地址(R)

主机检测应答/不应答信号

}while(不应答)

/*接收数字量*/

主机读高8位数据

主机发送应答信号

主机读低8位数据

主机发送不应答信号.

停止信号.

/*计算出温度或者湿度*/

//合成数据

//选择命令并且通过对应的公式转换成对应的数字量

所以:封装一个获取温度/湿度数据函数

四、程序设计

所用到的宏定义

IIC.h
//时钟线宏定义
#define IIC_SCL_L  (GPIOB->ODR &= ~(1<<8))
#define IIC_SCL_H  (GPIOB->ODR |=  (1<<8))
//数据线宏定义
//输出
#define IIC_SDA_OUT_L  (GPIOB->ODR &= ~(1<<9))
#define IIC_SDA_OUT_H  (GPIOB->ODR |=  (1<<9))
//输入
#define IIC_SDA_IN     (GPIOB->IDR & (1<<9))


SHT20.h
//声明一个共用体类型
typedef union trh
{
	float t;   //温度成员
	u8 rh;     //湿度成员
	
}TRH_n;



#define SHT20_ADDR_W  0x80
#define SHT20_ADDR_R  0x81
#define SHT20_SOFT    0xfe
#define SHT20_T       0xf3
#define SHT20_RH      0xf5

①IIC通信相关程序

/***********************************************
*函数名    :iic_IO_init
*函数功能  :IIC所用IO口初始化配置
*函数参数  :无
*函数返回值:无
*函数描述  :SCL----PB8
            SDA----PB9
************************************************/
void iic_IO_init(void)
{
	//端口时钟使能
	RCC->AHB1ENR |= (1<<1);
	//端口模式配置
	GPIOB->MODER &= ~((3<<16)|(3<<18));
	GPIOB->MODER |= ((1<<16)|(1<<18));
	//输出类型
	GPIOB->OTYPER &= ~(1<<8);         //时钟线配置位推挽输出
	GPIOB->OTYPER |= (1<<9);          //数据线配置为开漏输出
	//输出速度
	GPIOB->OSPEEDR &= ~((3<<16)|(3<<18));
	//上下拉
	GPIOB->PUPDR &= ~((3<<16)|(3<<18));
	//输出数据寄存器让时钟线和数据线处于空闲转态
	GPIOB->ODR |= ((1<<8) | (1<<9));
}


/***********************************************
*函数名    :iic_star
*函数功能  :IIC起始信号函数
*函数参数  :无
*函数返回值:无
*函数描述  :         
************************************************/
void iic_star(void)
{
	//时钟线拉低    可以动数据线
	IIC_SCL_L;
	//数据线拉高    保证可以出现下降沿
	IIC_SDA_OUT_H;
	
	
	//时钟线拉高    起始信号的条件
	IIC_SCL_H;
	TIM11_delay_us(5);
	//数据线拉低    产生了起始信号
	IIC_SDA_OUT_L;
	TIM11_delay_us(5);
	
	IIC_SCL_L;//安全作用
}



/***********************************************
*函数名    :iic_stop
*函数功能  :IIC停止信号函数
*函数参数  :无
*函数返回值:无
*函数描述  :         
************************************************/
void iic_stop(void)
{
	IIC_SCL_L;
	IIC_SDA_OUT_L;
	
	IIC_SCL_H;
	TIM11_delay_us(5);
	IIC_SDA_OUT_H;
	TIM11_delay_us(5);
	
}




/***********************************************
*函数名    :iic_send_ack
*函数功能  :IIC发送应答/不应答信号函数
*函数参数  :u8 ack   
*函数返回值:无
*函数描述  :ack  传入 0   表示发送应答
            ack  传入 1   表示发送不应答
************************************************/
void iic_send_ack(u8 ack)
{
	IIC_SCL_L;
	TIM11_delay_us(3);
	
	if(ack == 0) IIC_SDA_OUT_L;
	else         IIC_SDA_OUT_H;  
	TIM11_delay_us(2);
	
	IIC_SCL_H;
	TIM11_delay_us(5); 
	
	IIC_SCL_L;//安全作用
}



/***********************************************
*函数名    :iic_get_ack
*函数功能  :IIC检测应答/不应答信号函数
*函数参数  :无   
*函数返回值:u8
*函数描述  :0    应答信号
            1    不应答信号
************************************************/
u8 iic_get_ack(void)
{
	u8 ack;
	
	/*将数据线切换位输入模式*/
	IIC_SCL_L;
	IIC_SDA_OUT_H;  
	
	/*检测应答*/
	IIC_SCL_L;      //主机帮助从机把时钟线拉低,从机才可以自动改变数据线
	TIM11_delay_us(5);
	IIC_SCL_H;      //主机拉高时钟线才可以读数据线
	TIM11_delay_us(5);
	if(IIC_SDA_IN)   ack = 1;    //不应答信号
	else             ack = 0;    //应答信号
	
	
	IIC_SCL_L;    //安全作用
	return ack;
}




/***********************************************
*函数名    :iic_send_byte
*函数功能  :IIC发送一个字节函数
*函数参数  :u8 data  
*函数返回值:无
*函数描述  :
************************************************/
void iic_send_byte(u8 data)
{
	u8 i;
	
	for(i=0;i<8;i++)
	{
		IIC_SCL_L;
		TIM11_delay_us(3);
		
		if(data & 0x80)
		{
			IIC_SDA_OUT_H;  
		}
		else 
		{
			IIC_SDA_OUT_L;
		}
		TIM11_delay_us(2);
		
		IIC_SCL_H;       //帮助从机拉高时钟线,从机才可以读这一位数据
		TIM11_delay_us(5);
		
		//下一位数据
		data = data << 1;
		
	}
	
	IIC_SCL_L;      //安全作用
	
}




/***********************************************
*函数名    :iic_rec_byte
*函数功能  :IIC接收一个字节函数
*函数参数  :无  
*函数返回值:u8
*函数描述  :
************************************************/
u8 iic_rec_byte(void)
{
	u8 i;
	u8 data;
	
	/*IO切换为输入模式*/
	IIC_SCL_L;
	IIC_SDA_OUT_H;  
	
	/*接收一个字节数据*/
	for(i=0;i<8;i++)
	{
		IIC_SCL_L;          //帮助从机拉低时钟线,从才会改变数据线
		TIM11_delay_us(5);
		
		IIC_SCL_H;          //主机可以读数据线
		TIM11_delay_us(5);
	
		data = data << 1;
		if(IIC_SDA_IN)
		{
			data |= 0x01;
		}
	}
	
	IIC_SCL_L;     //安全作用
	
	
	return data;
}

②SHT20相关程序

SHT20初始化配置函数

/***********************************************
*函数名    :sht20_init
*函数功能  :sht20初始化配置
*函数参数  :无
*函数返回值:无
*函数描述  :			
************************************************/
void sht20_init(void)
{
	//所用IIC初始化
	iic_IO_init();
	//软复位
	sht20_soft();
}

软复位函数

/***********************************************
*函数名    :sht20_soft
*函数功能  :sht20软复位
*函数参数  :无
*函数返回值:无
*函数描述  :			
************************************************/
void sht20_soft(void)
{
	u8 ack;
	
	iic_star();
	iic_send_byte(SHT20_ADDR_W);
	ack = iic_get_ack();
	if(ack == 1)
	{
		iic_stop();
		return;
	}
	iic_send_byte(SHT20_SOFT);
	ack = iic_get_ack();
	if(ack == 1)
	{
		iic_stop();
		return;
	}
	
	iic_stop();
	tim11_delay_ms(15);
}

获取温度或湿度函数

根据时序获取

将获取到的两个八位数据和成一个十六位数据

带入到公式中计算出温度或者湿度

返回

/***********************************************
*函数名    :sht20_rec_val
*函数功能  :获取温度或者湿度函数
*函数参数  :u8 cmd
*函数返回值:TRH_n
*函数描述  :			
************************************************/
TRH_n sht20_rec_val(u8 cmd)
{
	u8 ack;
	u8 temp_h,temp_l;
	u16 temp;
	
	TRH_n val;
	
	
	
	/*接收数字量*/
	iic_star();
	iic_send_byte(SHT20_ADDR_W);
	ack = iic_get_ack();
	
	iic_send_byte(cmd);
	ack = iic_get_ack();
	
	//等待测量完成
	//TIM11_delay_ms(85);
	do
	{
		iic_star();
		iic_send_byte(SHT20_ADDR_R);
		ack = iic_get_ack();
		
	}while(ack!=0);
	
	
	//读数据
	temp_h = iic_rec_byte();
	iic_send_ack(0);
	temp_l = iic_rec_byte();
	iic_send_ack(1);
	iic_stop();
	
	
	/*计算出温度或者湿度*/
	//合成数据
	temp = (temp_h<<8) | temp_l;
	
	
	if(cmd == SHT20_T)
	{
		//计算温度
		val.t = -46.85+175.72 * temp / 65536;
			
	}
	else if(cmd == SHT20_RH)
	{
		//计算湿度
		val.rh = -6 + 125 * temp / 65536;
	
	}

	return val;
	
}

### FPGA 驱动 SHT-20 传感器 #### 硬件连接说明 SHT-20 是一款温湿度传感器,通常通过 I²C 接口与外部设备通信。为了使 FPGA 能够成功驱动 SHT-20 传感器,硬件连接如下: | SHT-20 Pin | 连接至 | |------------|--------| | VDD | FPGA 的电源引脚 (通常是 3.3V) | | GND | 地线 | | SDA | FPGA 的双向数据线 | | SCL | FPGA 的时钟线 | 确保在电路设计中加入上拉电阻到 SDA 和 SCL 线路,这有助于稳定信号传输[^1]。 #### VHDL 实现 I²C 主控制器模块 下面是一个简单的 VHDL 代码片段用于实现 I²C 协议中的主控端逻辑,该逻辑可以用来读取来自 SHT-20 的温度和湿度数据: ```vhdl library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity i2c_master is Port ( clk : in STD_LOGIC; -- System Clock reset_n : in STD_LOGIC; -- Active Low Reset start_cond : out STD_LOGIC; -- Start Condition Signal stop_cond : out STD_LOGIC; -- Stop Condition Signal scl_out : inout STD_LOGIC := 'Z'; -- Serial Clock Line Output sda_out : inout STD_LOGIC := 'Z' -- Serial Data Line Output ); end entity i2c_master; architecture Behavioral of i2c_master is begin process(clk, reset_n) begin if reset_n = '0' then -- Initialization code here... elsif rising_edge(clk) then -- Implement the state machine to handle I2C protocol states. -- This includes generating START/STOP conditions, -- sending address and data bytes over SDA line while toggling SCL. end if; end process; end architecture Behavioral; ``` 此代码仅为框架结构展示,并未完全实现具体功能;实际应用时需根据需求完善状态机的设计以及处理各种可能的状态转换情况[^2]。 #### Verilog 版本的 I²C 发送函数 对于偏好使用 Verilog 编程语言的人来说,这里提供了一个简化版的发送字节给从器件的功能单元定义: ```verilog module i2c_send_byte( input wire clk, input wire rstn, output reg sda, output reg scl, input [7:0] byte_to_send, output reg done_flag ); // Internal signals declaration... always @(posedge clk or negedge rstn) begin if (!rstn) begin // Reset actions... end else begin case(state) IDLE: /* Wait until there's something to send */; SEND_START: /* Generate a start condition on bus */; TRANSMIT_BYTE: /* Shift bits onto SDA line controlled by SCL pulses */; GENERATE_STOP: /* Send STOP signal after all bits are sent */; DONE: /* Set flag indicating transmission complete */; endcase end end endmodule ``` 这段代码同样只是一个模板性质的例子,在真实项目里还需要补充详细的内部寄存器声明、状态转移机制等内容来完成整个I²C协议的操作流程[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值