si7051高精度温度传感器驱动程序

si7051高精度温度传感器驱动程序

本文的si7051高精度温度传感器驱动程序是基于nrf52832的蓝牙soc,读者可以根据自己的mcu类型进行移植

io驱动文件 i2c.h和i2c.c

i2c.h

#ifndef I2C_H__
#define I2C_H__

#include "nrf_delay.h"
#include "nrf_gpio.h"


#define IIC_OK  											0
#define IIC_ERR  											0
#define ACK		    										0
#define NACK													1		
#define WaitAckTime 									5000
//i2c端口定义
#define IIC_SDA_PIN		  							7
#define IIC_SCL_PIN		  							8
#define IIC_SDA_IN										{nrf_gpio_cfg_input(IIC_SDA_PIN,NRF_GPIO_PIN_NOPULL);}
#define IIC_SDA_R                     nrf_gpio_pin_read(IIC_SDA_PIN)
#define IIC_SDA_H											{nrf_gpio_cfg_output(IIC_SDA_PIN);nrf_gpio_pin_set(IIC_SDA_PIN);}
#define IIC_SDA_L											{nrf_gpio_cfg_output(IIC_SDA_PIN);nrf_gpio_pin_clear(IIC_SDA_PIN);}
#define IIC_SCL_H											{nrf_gpio_cfg_output(IIC_SCL_PIN);nrf_gpio_pin_set(IIC_SCL_PIN);}
#define IIC_SCL_L											{nrf_gpio_cfg_output(IIC_SCL_PIN);nrf_gpio_pin_clear(IIC_SCL_PIN);}
typedef struct
{
	unsigned short IIC_Speed;
} IIC_ControlDef;
extern IIC_ControlDef IIC_ControlStruct;
void IIC_SpeedCtl ( unsigned short Speed );
unsigned short IIC_Read_Speed ( void );
void IIC_Init ( void );
void IIC_Start ( void );
void IIC_Stop ( void );
void IIC_Ack ( void );
uint8_t IIC_WaitAck ( unsigned int TimeOut );
void IIC_NAck ( void );
uint8_t IIC_SendByte ( unsigned char Byte, uint8_t ack);
uint8_t I2C_RecvByte(void);
uint8_t IIC_RecvByte ( uint8_t Ack );
#endif

i2c.c

#include "stdint.h"
#include "i2c.h"
#include "nrf_gpio.h"

/* 变量定义 */
IIC_ControlDef IIC_ControlStruct;           //IIC控制结构体

/* IIC速度控制 */
void IIC_SpeedCtl ( unsigned short Speed )
{
	IIC_ControlStruct.IIC_Speed = Speed;
}

/* 读取IIC速度 */
unsigned short IIC_Read_Speed ( void )
{
	return IIC_ControlStruct.IIC_Speed;
}

/* IIC的IO初始化 */
void IIC_Init ( void )
{
	IIC_SpeedCtl ( 5 );
	IIC_SDA_H;											
	IIC_SCL_H;												
}

void IIC_Start ( void )
{
	IIC_SDA_H					
	IIC_SCL_H						
	nrf_delay_us ( IIC_Read_Speed() );		
	IIC_SDA_L					
	nrf_delay_us ( IIC_Read_Speed() );		
	IIC_SCL_L					
}

void IIC_Stop ( void )
{
	IIC_SDA_L					
	IIC_SCL_L					
	nrf_delay_us ( IIC_Read_Speed() );		
	IIC_SCL_H					
	nrf_delay_us ( IIC_Read_Speed() );
	IIC_SDA_H			
}

void IIC_Ack ( void )
{
	IIC_SCL_L				
	IIC_SDA_L					
	nrf_delay_us ( IIC_Read_Speed() );
	IIC_SCL_H					
	nrf_delay_us ( IIC_Read_Speed() );
	IIC_SCL_L					
	IIC_SDA_H
}

uint8_t IIC_WaitAck ( unsigned int TimeOut )
{
	IIC_SDA_H
	nrf_delay_us ( IIC_Read_Speed() );			
	IIC_SCL_H
	nrf_delay_us ( IIC_Read_Speed() );			
	IIC_SDA_IN
	while ( IIC_SDA_R )					
	{
		if ( !(--TimeOut) )
		{
			IIC_Stop();				
			return IIC_ERR;					
		}
		nrf_delay_us ( IIC_Read_Speed() );
	}
	IIC_SCL_L						

	return IIC_OK;						
}

void IIC_NAck ( void )
{
	IIC_SCL_L					
	IIC_SDA_H				
	nrf_delay_us ( IIC_Read_Speed() );
	IIC_SCL_H				
	nrf_delay_us ( IIC_Read_Speed() );
	IIC_SCL_L					
}

//IIC_SendByte
uint8_t IIC_SendByte ( unsigned char Byte, uint8_t ack)
{
	unsigned char count = 0;

	IIC_SCL_L;								
	for ( ; count < 8; count++ )				
	{
		if ( Byte & 0x80 )						
			IIC_SDA_H
		else
			IIC_SDA_L
		Byte <<= 1;								

		nrf_delay_us ( IIC_Read_Speed() );
		IIC_SCL_H
		nrf_delay_us ( IIC_Read_Speed() );
		IIC_SCL_L
	}
	if(!ack)
	{
		if ( IIC_WaitAck ( WaitAckTime ) )	
		{
			IIC_Stop();	                   
			return IIC_ERR;
		}	
	}
	return IIC_OK;
	
}


//I2C_RecvByte
uint8_t I2C_RecvByte(void)
{
	uint8_t i;
	uint8_t value = 0;

	IIC_SDA_IN
	
	for (i = 0; i < 8; i++)
	{
		value <<= 1;
		IIC_SCL_H
		nrf_delay_us ( IIC_Read_Speed() );
		
		if (IIC_SDA_R )
		{
			value++;
		}
		IIC_SCL_L
		nrf_delay_us ( IIC_Read_Speed() );
	}
	return value;
}

//IIC_RecvByte
uint8_t IIC_RecvByte ( uint8_t Ack )
{
	uint8_t count = 0, receive = 0;

	IIC_SDA_IN		
	
	for ( ; count < 8; count++ )		
	{
		IIC_SCL_L
		nrf_delay_us ( IIC_Read_Speed() );
		IIC_SCL_H
		receive <<= 1;					
		if ( IIC_SDA_R )				
			receive++;
		nrf_delay_us ( IIC_Read_Speed() );
	}
	if ( Ack )
		IIC_NAck();
	else
		IIC_Ack();
	return receive;
}

温度传感器驱动文件 si7051.h和si7051.c

si7051.h

#ifndef SI7051_H__
#define SI7051_H__

#include "i2c.h"

#define SENSOR_EN_PIN      10

//器件地址
#define SI7051_IIC_SLAVE_ADDR    				0x40
#define SI7051_IIC_READ_ADDR    				((SI7051_IIC_SLAVE_ADDR << 1) | 0x00)
#define SI7051_IIC_WRITE_ADDR  					((SI7051_IIC_SLAVE_ADDR << 1) | 0x01) 
#define TEMP_COV_TIME                   12    //等待温度测量时间12ms
#define TEMP_DATA_LEN										2     //温度数据长度2字节 整数部分和小数部分

#define SERIAL_NUMBER_SI7050						0x32		
#define SERIAL_NUMBER_SI7051						0x33					
#define SERIAL_NUMBER_SI7053						0x35						
#define SERIAL_NUMBER_SI7054						0x36						
#define SERIAL_NUMBER_SI7055						0x37


//命令符
#define SI7051_CMD_MES_TEM_HOLD  				0xE3		//温度测量,hold master mode
#define SI7051_CMD_MES_TEM_NO_HOLD  		0xF3		//温度测量,no hold master mode
#define SI7051_CMD_RESET  							0xFE		//复位
#define SI7051_CMD_W_USER_REG  					0xE6		//写用户寄存器
#define SI7051_CMD_R_USER_REG  					0xE7		//读用户寄存器
#define SI7051_CMD_R_ID_1  							0xFA0F	//读器件id第一个字节
#define SI7051_CMD_R_ID_2   						0xFCC9	//读器件id第二个字节
#define SI7051_CMD_R_FW_VER   					0x84B8	//读固件版本


#define USER_REG_RES0_MASK              1
#define USER_REG_RES1_MASK              (1<<7)
#define USER_REG_RES0_NO_MASK           (~1)
#define USER_REG_RES1_NO_MASK           (~(1<<7))

#define MEA_RESOLUTION_14BIT(x)      		(((x)&USER_REG_RES0_NO_MASK)&USER_REG_RES1_NO_MASK)     
#define MEA_RESOLUTION_13BIT(x)   			(((x)&USER_REG_RES0_NO_MASK)|USER_REG_RES1_MASK)
#define MEA_RESOLUTION_12BIT(x)   			(((x)|USER_REG_RES0_MASK)&USER_REG_RES1_NO_MASK)
#define MEA_RESOLUTION_11BIT(x)  			  (((x)|USER_REG_RES0_MASK)|USER_REG_RES1_MASK)

void SI7051_power_enable(void);
void SI7051_power_disable(void);
void SI7051_Init ( void );
uint8_t SI7051_IIC_Operation ( uint16_t cmd, uint8_t *wBuf, uint8_t wNum, uint8_t *rBuf, uint8_t rNum);
void temp_to_degrees ( uint8_t *temp, uint16_t *degrees);
void temp_to_int_frac ( uint8_t *temp, uint8_t *int_frac);
void temp_to_CHAR ( uint8_t *temp, uint8_t *cDegree);

#endif

si7051.c

#include "si7051.h"
#include "stdint.h"
#include "stdio.h"

//SI7051_IIC_Operation
//cmd  : 命令字符,一个或2个bytes
//wBuf : 待写入的数据
//wNum : 待写入的字节数
//rBuf : 待读取的数据
//rNum : 待读取的字节数
uint8_t SI7051_IIC_Operation ( uint16_t cmd, uint8_t *wBuf, uint8_t wNum, uint8_t *rBuf, uint8_t rNum)
{
	switch(cmd)
	{
		/* 温度测量,hold master mode 数据长度 = 2 bytes */ 
		case SI7051_CMD_MES_TEM_HOLD: 			
			IIC_Start();		
			if ( IIC_SendByte ( SI7051_IIC_WRITE_ADDR, ACK) )		//发送设备地址(写)
				return IIC_ERR;
			if ( IIC_SendByte ( (uint8_t)cmd, ACK ) )						//发送命令
				return IIC_ERR;
			IIC_Start();		
			if ( IIC_SendByte ( SI7051_IIC_READ_ADDR, ACK ) )	  //发送设备地址(读)
				return IIC_ERR;
			nrf_delay_ms(TEMP_COV_TIME); 												//clock stretch during measurement  测量的时间  (TODO)
			while(rNum--)
			{
				if ( rNum == 0 )
					*rBuf = IIC_RecvByte ( NACK );	
				else
					*rBuf = IIC_RecvByte ( ACK );	
				rBuf++;
			}
			IIC_Stop();		
		break;
		
		/* 温度测量,no hold master mode 数据长度 = 2 bytes */
		case SI7051_CMD_MES_TEM_NO_HOLD: 		
			IIC_Start();		
			if ( IIC_SendByte ( SI7051_IIC_WRITE_ADDR, ACK) )		//发送设备地址(写)
				return IIC_ERR;
			if ( IIC_SendByte ( (uint8_t)cmd, ACK ) )						//发送命令
				return IIC_ERR;
			IIC_Start();		
			if ( IIC_SendByte ( SI7051_IIC_READ_ADDR, NACK ) )	//发送设备地址(读)
				return IIC_ERR;
			IIC_Start();		
			if ( IIC_SendByte ( SI7051_IIC_READ_ADDR, ACK ) )	  //发送设备地址(读)
				return IIC_ERR;
			while(rNum--)
			{
				if ( rNum == 0 )
					*rBuf = IIC_RecvByte ( NACK );	
				else
					*rBuf = IIC_RecvByte ( ACK );	
				rBuf++;
			}
			IIC_Stop();				
		break;
			
		/* 复位 */
		case SI7051_CMD_RESET: 							
			IIC_Start();
			if ( IIC_SendByte ( SI7051_IIC_WRITE_ADDR, ACK ) )	//发送设备地址(写)
				return IIC_ERR;
			if ( IIC_SendByte ( (uint8_t)cmd, ACK ) )						//发送命令
				return IIC_ERR;
			IIC_Stop();	
		break;
		
		/* 写用户寄存器 数据长度 = 1 bytes */
		case SI7051_CMD_W_USER_REG: 				
			IIC_Start();		
			if ( IIC_SendByte ( SI7051_IIC_WRITE_ADDR, ACK ) )	//发送设备地址(写)
				return IIC_ERR;
			if ( IIC_SendByte ( (uint8_t)cmd, ACK ) )						//发送命令
				return IIC_ERR;
			while ( wNum-- )							
			{
				if ( IIC_SendByte ( *wBuf, ACK ) )	
					return IIC_ERR;
				wBuf++;						
			}
			IIC_Stop();		
		break;
		
		/* 读用户寄存器 数据长度 = 1 bytes */
		case SI7051_CMD_R_USER_REG: 			
			IIC_Start();		
			if ( IIC_SendByte ( SI7051_IIC_WRITE_ADDR, ACK ) )	//发送设备地址(写)
				return IIC_ERR;
			if ( IIC_SendByte ( (uint8_t)cmd, ACK ) )						//发送命令
				return IIC_ERR;
			IIC_Start();		
			if ( IIC_SendByte ( SI7051_IIC_READ_ADDR, ACK ) )		//发送设备地址(读)
				return IIC_ERR;
			while(rNum--)
			{
				if ( rNum == 0 )
					*rBuf = IIC_RecvByte ( NACK );	
				else
					*rBuf = IIC_RecvByte ( ACK );	
				rBuf++;
			}
			IIC_Stop();			
		break;
		
		/* 读器件id第一个字节   数据长度 = 8 bytes */
		/* SNA_3 CRC SNA_2 CRC SNA_1 CRC SNA_0 CRC  = 8 bytes */
		case SI7051_CMD_R_ID_1: 						
			
		/* 读器件id第二个字节  数据长度 = 6 bytes */
		/* SNB_3 SNB_2 CRC SNB_1 SNB_0 CRC  = 6 bytes */
		case SI7051_CMD_R_ID_2: 						
			IIC_Start();		
			if ( IIC_SendByte ( SI7051_IIC_WRITE_ADDR, ACK ) )	//发送设备地址(写)
				return IIC_ERR;
			if ( IIC_SendByte ( (uint8_t)(cmd >> 8), ACK ) )		//发送命令高字节
				return IIC_ERR;
			if ( IIC_SendByte ( (uint8_t)cmd , ACK) )						//发送命令低字节
				return IIC_ERR;
			IIC_Start();		
			if ( IIC_SendByte ( SI7051_IIC_READ_ADDR, ACK ) )		//发送设备地址(读)
				return IIC_ERR;
			while(rNum--)
			{
				if ( rNum == 0 )
					*rBuf = IIC_RecvByte ( NACK );	
				else
					*rBuf = IIC_RecvByte ( ACK );	
				rBuf++;
			}
			IIC_Stop();			
		break;
			
		/* 读固件版本 数据长度 = 1 bytes*/
		case SI7051_CMD_R_FW_VER: 					
			IIC_Start();		
			if ( IIC_SendByte ( SI7051_IIC_WRITE_ADDR, ACK ) )	//发送设备地址(写)
				return IIC_ERR;
			if ( IIC_SendByte ( (uint8_t)(cmd >> 8), ACK ) )		//发送命令高字节
				return IIC_ERR;
			if ( IIC_SendByte ( (uint8_t)cmd, ACK ) )						//发送命令低字节
				return IIC_ERR;
			IIC_Start();		
			if ( IIC_SendByte ( SI7051_IIC_READ_ADDR, ACK ) )		//发送设备地址(读)
				return IIC_ERR;
			*rBuf = IIC_RecvByte ( NACK );	
			IIC_Stop();			
		break;
			
		default:
		break;
		
	}
	return IIC_OK;
}

/* 温度传感器电源使能 */
void SI7051_power_enable(void)
{
	nrf_gpio_cfg_output(SENSOR_EN_PIN);
	nrf_gpio_pin_set(SENSOR_EN_PIN);	
}

/* 温度传感器电源失能 */
void SI7051_power_disable(void)
{
	nrf_gpio_cfg_output(SENSOR_EN_PIN);
	nrf_gpio_pin_clear(SENSOR_EN_PIN);
}

/* 温度传感器初始化 */
void SI7051_Init ( void )
{
	uint8_t wUserReg = 0;
	uint8_t rUserReg = 0;
	uint8_t rID[8]   = {0};
	
	IIC_Init();
	
	SI7051_power_enable();
	
	SI7051_IIC_Operation ( SI7051_CMD_R_ID_2,     &wUserReg, 0, rID, 8);  		//读ID
	
	if(rID[0] != SERIAL_NUMBER_SI7051)
	{
		printf("[E] Temp sensor chip not ok\r\n");
		return;
	}
	printf("[D] Temp sensor chip ok\r\n");
	//复位后的用户寄存器默认值为0b00111010  :14bit Vdd ok
	SI7051_IIC_Operation ( SI7051_CMD_RESET,      &wUserReg, 1, &rUserReg, 1);//复位
	
	SI7051_IIC_Operation ( SI7051_CMD_R_USER_REG, &wUserReg, 1, &rUserReg, 1);//读用户寄存器
	
	wUserReg = MEA_RESOLUTION_14BIT(rUserReg);																//分辨率设为14bit
	
	SI7051_IIC_Operation ( SI7051_CMD_W_USER_REG, &wUserReg, 1, &rUserReg, 1);//写用户寄存器
	
	printf("[D] Temp sensor init ok\r\n");
}
发布了2 篇原创文章 · 获赞 0 · 访问量 20

猜你喜欢

转载自blog.csdn.net/u011052048/article/details/105629326