您尚未登录。

楼主 #1 2020-05-09 18:19:38

缥缈九哥
会员
注册时间: 2020-05-09
已发帖子: 76
积分: 92

基于华芯微特SWM181CBT6的I2C的HTU21D温度湿度传感器驱动程序开发-缥缈九哥

不废话,上代码:

/********************************************************************************
 * @file     htu20d.c															*
 * @brief    The Driver code for HTU21D with SWM181CBT6							*
 * @version  1.0.0																*
 * @date     2018/08/23  01:35:35												*
 *																				*
 * @note																		*
 * Copyright (C) 2000-2018 PM9GZY by yuanxihua@21cn.com. All rights reserved.	*
 ********************************************************************************/
/* Includes --------------------------------------------------------------------*/
#include "wall.h"
/*
_________________________________________________
|	SWM181CBT6						HTU20D		|
|												|
|	SDA -	PD3			<--->		SDA			|
|	SCL -	PD2			 --->		SCL			|
|_______________________________________________|
*/
/* Private typedef -----------------------------------------------------------*/
typedef enum {START=0x01,STOP=0x02,WRD=0x04,RDA=0x08,ACK=0x10,NAK=0x20}i2c_status_t;
typedef enum {TEMP=0xF3,HUMID=0xF5,TEMPHOLD=0xE3,HUMIDHOLD=0xE5,WRUSER=0xE6,RDUSER=0xE7,RESET=0xFE}i2c_cmd_t;
/* Private define ------------------------------------------------------------*/
#define HTU20D_I2C_CLK_HZ      		100000 			/* Clock i2c speed 100KHz */
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
void I2C0Init(void)
{
	I2C_InitStructure I2C_initStruct;
	
	PORT_Init(PORTD, PIN2, FUNMUX_I2C0_SCL, 1);		//GPIOD.2配置为I2C0 SCL引脚
	PORT_Init(PORTD, PIN3, FUNMUX_I2C0_SDA, 1);		//GPIOD.3配置为I2C0 SDA引脚
	PORTD->OPEND |= (1 << PIN2)|(1 << PIN3);		//开漏
	PORTD->PULLU |= (1 << PIN2)|(1 << PIN3);		//上拉

	I2C_initStruct.Master = 1;
	I2C_initStruct.Addr7b = 1;
	I2C_initStruct.MstClk = HTU20D_I2C_CLK_HZ;
	I2C_initStruct.MstIEn = 0;
	I2C_Init(I2C0, &I2C_initStruct);
	I2C_Open(I2C0);
	//After power up, the device needs at most 15ms while SCK is high
	osDelay(20); 
}
void I2C_SEND_STATUS(I2C_TypeDef *i2c,i2c_status_t status)	
{
	uint8_t cmd=0;
	if(status & START){cmd |=  (1 << I2C_MSTCMD_STA_Pos);}	 	//set start
	if(status & STOP ){cmd |=  (1 << I2C_MSTCMD_STO_Pos);}		//set stop 
	if(status & WRD  ){cmd |=  (1 << I2C_MSTCMD_WR_Pos );}		//set write
	if(status & RDA  ){cmd |=  (1 << I2C_MSTCMD_RD_Pos );}		//set read 
	if(status & ACK  ){cmd &= ~(0 << I2C_MSTCMD_ACK_Pos);}		//set ack 
	if(status & NAK  ){cmd |=  (1 << I2C_MSTCMD_ACK_Pos);}		//set nack 
	i2c->MSTCMD=cmd;while(i2c->MSTCMD & I2C_MSTCMD_TIP_Msk){;}	//等待发送完成
}	
uint8_t I2C_SEND_DATA(I2C_TypeDef *i2c,uint8_t data,i2c_status_t status)		
{
	i2c->MSTDAT=data;
	I2C_SEND_STATUS(i2c,status);
	return (i2c->MSTCMD & I2C_MSTCMD_RXACK_Msk)?NAK:ACK;
}
uint8_t I2C_READ_DATA(I2C_TypeDef *i2c,i2c_status_t status)		
{
	I2C_SEND_STATUS(i2c,status);
	return i2c->MSTDAT;
}
void HTU20D_Soft_Reset(void)
{
	uint8_t ack;ack=ack;
	//send i2c start + address + write
	ack=I2C_SEND_DATA(I2C0,0x80,START|WRD);
	//send Soft Reset Command
	ack=I2C_SEND_DATA(I2C0,RESET,WRD|STOP);//0xFE
	//The soft reset takes less than 15ms.
	osDelay(20); 
}
uint8_t HTU20D_Read_User_Register(void)
{
	uint8_t ack;ack=ack;
   	//send i2c start + address + write
	ack=I2C_SEND_DATA(I2C0,0x80,START|WRD);
	//send Read Register Command
	ack=I2C_SEND_DATA(I2C0,RDUSER,WRD);//0xE7
	//send i2c start + address + read
	ack=I2C_SEND_DATA(I2C0,0x81,START|WRD);
	//read Register content
	uint8_t data=I2C_READ_DATA(I2C0,RDA|NAK|STOP);
	//wait i2c delay
	osDelay(20);
	return data;
}
void HTU20D_Write_User_Register(uint8_t data)
{
	uint8_t ack;ack=ack;
   	//send i2c start + address + write
	ack=I2C_SEND_DATA(I2C0,0x80,START|WRD);
	//send Write Register Command
	ack=I2C_SEND_DATA(I2C0,WRUSER,WRD);//0xE6
	//send Register Content to be written
	ack=I2C_SEND_DATA(I2C0,data,WRD|STOP);
	//wait i2c delay
	osDelay(20);
}
uint16_t HTU20D_Read_Temperature_Humidity(i2c_cmd_t cmd)
{
	uint8_t ack;ack=ack;
   	//send i2c start + address + write
	ack=I2C_SEND_DATA(I2C0,0x80,START|WRD);
	//send Read Register Command
	ack=I2C_SEND_DATA(I2C0,cmd,WRD);
	//continue measuring
	while(I2C_SEND_DATA(I2C0,0x81,START|WRD)==NAK){;}
	//read Register content MSB
	uint16_t data =I2C_READ_DATA(I2C0,RDA|ACK);
	//read Register content LSB
	data=(data<<8)+I2C_READ_DATA(I2C0,RDA|ACK);	
	//read Checksum
	uint16_t cks = I2C_READ_DATA(I2C0,RDA|NAK|STOP);
	//wait i2c delay
	osDelay(20);
	return data;
}
void HTU20D_Read(float *Temperature, float *Humidity)
{
	float temp;
	temp=HTU20D_Read_Temperature_Humidity(TEMP )&0xfffc;
//	printf("HTU20D_Read Temperature=0x%x\n\r",(int)temp);
	*Temperature=((temp*175.72)/65536)-46.85;
	temp=HTU20D_Read_Temperature_Humidity(HUMID)&0xfffc;
//	printf("HTU20D_Read Humidity   =0x%x\n\r",(int)temp);
	*Humidity=((temp*125)/65536)-6;
}
void HTU20D_test(void)
{
	float Humidity,Temperature;
	HTU20D_Soft_Reset();
	HTU20D_Write_User_Register(0x00);
	printf("HTU20D User_Registe=0x%02x\n\r",HTU20D_Read_User_Register());
	
	HTU20D_Read(&Temperature,&Humidity);
	printf("HTU20D Trigger No Hold T=%f 摄氏度 H=%f %%RH\n\r",Temperature,Humidity);
}

//代码完毕

最近编辑记录 缥缈九哥 (2020-05-09 18:26:01)

离线

#2 2020-05-09 22:10:30

微凉VeiLiang
会员
所在地: 深圳
注册时间: 2018-10-28
已发帖子: 595
积分: 525
个人网站

Re: 基于华芯微特SWM181CBT6的I2C的HTU21D温度湿度传感器驱动程序开发-缥缈九哥

nb,老哥

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn