HDC1080 驱动程序代码(C语言版)

在列出 HDC1080温湿度传感器驱动程序核心代码 之前,请允许我先多说几句:

  1. CSDN上有关HDC1080驱动代码的高阅读量博客只有两篇,且两篇博客内都不提供代码!而是在其中附上了需要积分才能下载代码的链接。吐了。
  2. GitHub上有关HDC1080驱动代码的STM32版只有两篇。一篇代码使用STM32的HAL库写的,在I2C的使用上封装程度太高,看不到通信中的关键细节。另一篇代码使用了大量的OLED界面操作,整体代码过于冗余,并且在HDC1080的I2C驱动上写的不清晰。
  3. TI公司的HDC1080官方芯片手册,在HDC1080驱动步骤中的第二步和第三步上写的及其令人费解,以至于我花了两天不断思考这两步究竟是要做什么操作。

下面进入正文。

温湿度数据

温湿度数据通过串口助手显示结果如下,temp温度在25℃左右,humi湿度在51%RH。当我将手指放在HDC1080表面时,temp温度逐渐升高至27℃左右,而humi湿度显示为0,这可能是由于HDC1080表面探测湿度的 金色元件 被我的手指完全遮挡所导致。之后,当我将手指移出HDC1080,temp温度和humi湿度逐渐回归正常数值。
请添加图片描述

驱动代码 HDC1080.h

首先,我使用的是 STM32F103C8T6 芯片,采用 Keil 5 编程软件,通过软件 I2C 协议和HDC1080 芯片进行通信。软件I2C中,SCL = PB0,SDA = PB1。在 HDC1080.h 中我做了如下三部分定义:

  1. HDC1080 软件 I2C 的接口定义
  2. HDC1080 各寄存器地址
  3. 软件 I2C 函数和 HDC1080 相关读取函数

代码如下:

#ifndef __HDC1080_H__
#define __HDC1080_H__
#include "sys.h"

// HDC1080 sensor port: PB0 - PB1
#define HDC1080_PORT	GPIOB	

#define HDC1080_SCL		GPIO_Pin_0
#define HDC1080_SDA		GPIO_Pin_1	

#define HDC1080_SCL_H          HDC1080_PORT->BSRR = HDC1080_SCL //set to 1
#define HDC1080_SCL_L          HDC1080_PORT->BRR  = HDC1080_SCL //reset to 0
#define HDC1080_SDA_H          HDC1080_PORT->BSRR = HDC1080_SDA
#define HDC1080_SDA_L          HDC1080_PORT->BRR  = HDC1080_SDA

#define HDC1080_SCL_Status     HDC1080_PORT->IDR  & HDC1080_SCL //IDR是查看引脚电平状态
#define HDC1080_SDA_Status     HDC1080_PORT->IDR  & HDC1080_SDA

// The Chip parameters we use.
#define HDC1080_TempAddress         0x00
#define HDC1080_HumiAddress         0x01
#define HDC1080_Configuration       0x02
#define HDC1080_ManufactID          0xFE
#define HDC1080_DeviceID            0xFF

#define HDC1080_Write_Address		0x80
#define HDC1080_Read_Address        0x81


// I2C initial 
void HDC1080_I2C_GPIO_Configuration(void);

void I2C4_delay(void);

int  I2C4_Start(void);
void I2C4_Stop(void);

void I2C4_SDA_IN(void);
void I2C4_SDA_OUT(void);

static void I2C4_Ack(void);
static void I2C4_NoAck(void);
uint8_t I2C4_GetAck(void);

void    I2C4_WriteByte(uint8_t Data);
uint8_t I2C4_ReadByte(uint8_t ack);

int HDC1080_I2C4_WriteByte(uint8_t Reg_Addr, uint8_t Data);
int HDC1080_I2C4_WriteBuffer(uint8_t Reg_Addr, uint8_t *pBuffer, uint8_t NumByteToWrite);

int HDC1080_I2C4_ReadByte(uint8_t Reg_Addr, uint8_t *Data);
int HDC1080_I2C4_ReadBuffer(uint8_t Reg_Addr, uint8_t *pBuffer, uint8_t NumByteToRead); 

void HDC1080_Start(void);
uint16_t HDC1080_Result(char ch);
void HDC1080_Caculate(uint16_t ut, uint16_t uh, float *rt, float *rh);

#endif

驱动代码 HDC1080.c

下面介绍驱动 HDC1080 芯片的核心通信代码和逻辑,首先我们看一下 TI 公司给出的官方芯片手册中的通信过程:
在这里插入图片描述
对于第一步配置HDC1080的工作模式和第四步读取温湿度数据,这两步理解起来很容易。而最难以理解的是第二步和第三步,这两句话是什么意思?我们该怎么做通信?我本以为第二步和第三步是做两个独立的通信动作。但实际上,第二部和第三步合起来只是做了一个通信动作。我们来看如下通信流程图:
在这里插入图片描述
流程图中,“I2C写1次数据” 完成了芯片手册中提到的第一步“I2C读一次数据” 完成了芯片手册中提到的的二、三、四步。我们都知道 I2C 在读/写设备数据的过程中,需要进行主从模式的转换。也就是说,STM32 使用 I2C 读数据前,首先进行写地址操作,将自己设置为主设备,也即流程图中的Write 0x80 和 Write 0x00。完成后,再次进行写操作,也就是流程图中的Write 0x81,这里需注意0x80和0x81的含义。同时将自己的工作模式转为从设备,开始进入数据接收状态。这时候,读取主设备发送来的数据。

下面回顾一下 HDC1080 芯片手册中提到的通信过程中的2,3,4条:

  1. Trigger the measurements by executing a pointer write transaction with the address pointer set to 0x00.
  2. Wait for the measurements to complete, based on the conversion time.
  3. Read the output data。

我们发现2,3,4条通信过程,即和流程图中的“I2C读一次数据”的过程完全对应。其中第3条通信动作,Wait for the measurements to complete,是夹在“I2C读一次数据”过程之中的,也就是流程图中红色字体标注的 Wait 20ms。 搞清楚这一步,下面再向寄存器读取温湿度数据就没有问题了。

下面提供 HDC1080.c 的核心通信代码,其中最重要的代码是 HDC1080_I2C4_ReadBuffer 函数,请多注意。

/           HDC1080 Coding       //
void HDC1080_Start(void)
{
	/* uint8_t ManuID[2];
	HDC1080_I2C4_ReadBuffer(HDC1080_ManufactID,ManuID,2);//read 0x5449 is ok! */
	
	uint8_t buf[4];
	buf[0] = 0x10; //config temp and humi
	buf[1] = 0x00; //both 14 bit

    HDC1080_I2C4_WriteBuffer(HDC1080_Configuration,buf,2);
}

uint16_t HDC1080_Result(char ch)
{
	uint16_t temp,humi;
	uint8_t buf[4];
	
	HDC1080_I2C4_ReadBuffer(HDC1080_TempAddress,buf,4);

	temp = buf[0] << 8;
	temp |= buf[1];

	humi = buf[2] << 8;
	humi |= buf[3];

	if (ch == 'T') //ch字符用来进行温度和湿度的选择性输出
	{
		return temp;
	}
	else if (ch == 'H')
	{
		return humi;
	}
	else{
		return 0;
	}
}

void HDC1080_Caculate(uint16_t ut, uint16_t uh, float *rt, float *rh)
{
		//ut 和 uh 为从HDC1080中读取出的原始温湿度值,这里根据芯片手册中的公式进行转换。
        *rt = ut / pow(2.0, 16.0) * 165.0 - 40.0; //'C
        *rh = uh / pow(2.0, 16.0) * 100.0; //%RH                          
}

int HDC1080_I2C4_ReadBuffer(uint8_t Reg_Addr, uint8_t *pBuffer, uint8_t NumByteToRead){ 
	uint8_t i;
	uint8_t tag;//选择性回应Ack

	I2C4_Start();
	I2C4_WriteByte(HDC1080_Write_Address);
	if(!I2C4_GetAck())// 有slave ack的响应
	{
		I2C4_Stop();
		return DISABLE;
	}

	I2C4_WriteByte(Reg_Addr); 
	if(!I2C4_GetAck())
	{
		I2C4_Stop();
		return DISABLE;
	}

	delay_ms(20);//等待温湿度数据转换

	I2C4_Start();//更改通信模式,主机从发送变为接收
	I2C4_WriteByte(HDC1080_Read_Address);
	if(!I2C4_GetAck())// 有slave ack的响应
	{
		I2C4_Stop();
		return DISABLE;
	}

	for(i=0; i<NumByteToRead; i++)
	{
		tag = (i == NumByteToRead-1) ? 0 : 1;
		pBuffer[i] = I2C4_ReadByte(tag);
	}

	I2C4_Stop(); //在这个位置统一停止
	return 1;
}
  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值