资讯详情

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

文章目录

  • si7051高精度温度传感器驱动程序
    • io驱动文件 i2c.h和i2c.c
    • 温度传感器驱动文件 si7051.h和si7051.c

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

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

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

#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

#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

#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

#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");
}

标签: 传感器类型snb

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台