/************************Copyright (c)********************************
** PP-DIY
**------------------------File Info------------------------------------
** File name: si702x.c
** Created by: P.P
** Last modified Date: 2014-10-3
** Descriptions:
***************************************************************************/
#include "SI7021.h"
#include "stdio.h"
float Temp_buf;
float Humi_buf;
struct SI70XX_TYPE SI70XX;
//========================================
//FUNCTION:ROUTES TO PROVIDE A START SIGNAL
//========================================
void SI_IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(SI7021_RCC,ENABLE);
GPIO_InitStructure.GPIO_Pin=SI7021_PIN;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_Init(SI7021_GPIO, &GPIO_InitStructure);
SI7021_CLK_H;
SI7021_SDA_H;
SI7021_POWER_ON;
}
void SI_start(void)
{
SI7021_SDA_OUT;
SI7021_CLK_L;
SI7021_IIC_Delay();
SI7021_SDA_H;
SI7021_IIC_Delay();
SI7021_CLK_H;
SI7021_IIC_Delay();
SI7021_SDA_L;
SI7021_IIC_Delay();
SI7021_CLK_L;
SI7021_IIC_Delay();
return;
}
//=======================================
//FUNCTION:ROUTES TO PROVIDE A STOP SIGNAL
//========================================
void SI_stop(void)
{
SI7021_SDA_OUT;
SI7021_SDA_L;
SI7021_CLK_L;
SI7021_IIC_Delay();
SI7021_CLK_H;
SI7021_IIC_Delay();
SI7021_SDA_H;
SI7021_IIC_Delay();
SI7021_CLK_L;
SI7021_IIC_Delay();
SI7021_SDA_L;
return;
}
//-----------------------------------------------------------------------------
// check the acknowledge
//
// Inputs:
// wrdata: Byte to be written
//
// Pin drive status upon exit:
// SDIO = high (open-drain input)
// SCLK = high
//-----------------------------------------------------------------------------
uchar Slave_acknowledge(void)
{
//check the acknowledge
SI7021_SDA_IN;
SI7021_SDA_H;
SI7021_CLK_L;
SI7021_IIC_Delay();
SI7021_CLK_H;
SI7021_IIC_Delay();
//while (SI7021_Data);//长时间等待退出
for(uchar i=0;i<254;i++)//容错处理,防止死等
{
if(SI7021_Data)
{
SI7021_IIC_Delay();
}
else
{
break;//直接退出
}
if(i==200)
{
//超时出错
return(1);
}
}
SI7021_CLK_L;
SI7021_IIC_Delay();
return(0);
}
void Master_acknowledge(void)
{
SI7021_SDA_OUT;
SI7021_SDA_L;
SI7021_IIC_Delay();
SI7021_CLK_L;
SI7021_IIC_Delay();
SI7021_CLK_H;
SI7021_IIC_Delay();
SI7021_CLK_L;
SI7021_IIC_Delay();
return;
}
void No_ack(void)
{
SI7021_SDA_IN;
SI7021_IIC_Delay();
SI7021_CLK_L;
SI7021_IIC_Delay();
SI7021_CLK_H;
SI7021_IIC_Delay();
SI7021_CLK_L;
SI7021_IIC_Delay();
return;
}
/*********************************************************************
*函数名称: char SI_R_Byte(uchar ack)
*说 明:reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
*********************************************************************/
uchar SI_R_Byte(void)
{
uchar val=0;
SI7021_SDA_IN; //release DATA-line
SI7021_CLK_L;
for(uchar i=8;i>0;i--)
{
SI7021_CLK_L;
SI7021_IIC_Delay();
SI7021_CLK_H;
SI7021_IIC_Delay();
if(SI7021_Data)
{
val |= 0x01;
}
if(i!=1)
{
val<<=1;
}
}
SI7021_CLK_L;
return(val);
}
/*********************************************************************
*函数名称: uchar SI_W_Byte(uchar value)
*说 明:
*********************************************************************/
void SI_W_Byte(uchar value)
{
SI7021_SDA_OUT;
SI7021_CLK_L;
for(uchar i=0x80;i>0;i>>=1) //shift bit for masking
{
if (i & value)
{
SI7021_SDA_H; //masking value with i , write to SENSI-BUS
}
else
{
SI7021_SDA_L;
}
SI7021_IIC_Delay(); //observe setup time
SI7021_CLK_H; //clk for SENSI-BUS
SI7021_IIC_Delay(); //pulswith approx. 5 us
SI7021_CLK_L;
SI7021_IIC_Delay();
SI7021_SDA_L;
}
return; //error=1 in case of no acknowledge
}
/******************************************************************************
*函数名称:ucahr s_measure(uchar *p_value, uchar *p_checksum, uchar mode)
*说 明:makes a measurement (humidity/temperature) with checksum
*******************************************************************************/
uchar SI_Read_Register(uchar Reg_add)
{
uchar temp=0;
//====================================================//
SI_start();
SI_W_Byte(0x80);
Slave_acknowledge();
SI_W_Byte(Reg_add);
Slave_acknowledge();
SI_start();
SI_W_Byte(0x81);
Slave_acknowledge();
temp=SI_R_Byte();
Master_acknowledge();
SI_stop();
return(temp);
}
/******************************************************************************
*函数名称:ucahr s_measure(uchar *p_value, uchar *p_checksum, uchar mode)
*说 明:makes a measurement (humidity/temperature) with checksum
*******************************************************************************/
uchar SI_Write_Register(uchar Reg_add,uchar Code)
{
uchar temp=0;
//====================================================//
SI_start();
SI_W_Byte(0x80);
Slave_acknowledge();
SI_W_Byte(Reg_add);
Slave_acknowledge();
SI_W_Byte(Code);
Slave_acknowledge();
SI_stop();
return(temp);
}
/*****************************************************************************/
/* SI70XX_Read_UserRegister */
/*****************************************************************************/
uchar SI70XX_Read_UserRegister(void)
{
uchar Data;
SI_start();
SI_W_Byte(0x80);// si7013
Slave_acknowledge();
SI_W_Byte(CMD_READ_REGISTER_1);
Slave_acknowledge();
delay_ms(20);//>=20ms等待转换
SI_start();
SI_W_Byte(0x81);//地址读
Slave_acknowledge();
Data=SI_R_Byte();
No_ack();
SI_stop();
return(Data);
}
#ifndef I2C_SIM
unsigned char I2C_Err=0;
uint8_t I2C_ReadOneByte(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint8_t Reg_addr)
{
RCC_ClocksTypeDef rcc_clocks;
uint8_t readout;
u32 tmr;
u32 ulTimeOut_Time;
RCC_GetClocksFreq(&rcc_clocks);
ulTimeOut_Time = (rcc_clocks.SYSCLK_Frequency /10000);
tmr = ulTimeOut_Time;
while((--tmr)&&I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
if(tmr==0) I2C_Err = 1;
I2C_GenerateSTART(I2Cx, ENABLE);
//??I2C?START??,?????????????
tmr = ulTimeOut_Time;
while((--tmr)&&(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)));
if(tmr==0) I2C_Err = 1;
I2C_Send7bitAddress(I2Cx,I2C_Addr,I2C_Direction_Transmitter);
tmr = ulTimeOut_Time;
while((--tmr)&&(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)));
if(tmr==0) I2C_Err = 1;
I2C_SendData(I2Cx, Reg_addr);
tmr = ulTimeOut_Time;
while((--tmr)&&(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED)));
if(tmr==0) I2C_Err = 1;
I2C_GenerateSTART(I2Cx, ENABLE);
tmr = ulTimeOut_Time;
while((--tmr)&&(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MO