#include <STC90C5xAD.H>
#include <intrins.h> //Keil library (is used for _nop()_ operation)
#include <math.h> //Keil library
#include <stdio.h> //Keil library
sbit IIC_SCL =P1^0 ;
sbit IIC_SDA =P1^1;
typedef unsigned charuchar;
typedef unsigned intuint;
uint POLYNOMIAL = 0x131;
uchar SHT3X_Data_Buffer[6];
float Sht30_Humidity,Sht30_Temperature;
uint Read_temp,Read_hum;
/*
函数功能:IIC总线起始信号
*/
void UART_sendbyte(unsigned char byte);
union Flow_Totalizer //仪表返回4位uchar转成浮点数
{
float x;
char table[4];
}TH_temp;
void Delay100ms()//@11.0592MHz
{
unsigned char i, j;
i = 180;
j = 73;
do
{
while (--j);
} while (--i);
}
void IIC_Start(void)
{
//IIC_SDA_OUTMODE(); //初始化SDA为输出模式
IIC_SDA=1; //数据线拉高
IIC_SCL=1; //时钟线拉高
_nop_();
_nop_();
_nop_();
_nop_();
// DelayUs(4); //电平保持时间
IIC_SDA=0; //数据线拉低
_nop_();
_nop_();
_nop_();
_nop_();
//DelayUs(4); //电平保持时间
IIC_SCL=0; //时钟线拉低
}
/*
函数功能:IIC总线停止信号
*/
void IIC_Stop(void)
{
//IIC_SDA_OUTMODE(); //初始化SDA为输出模式
IIC_SDA=0; //数据线拉低
IIC_SCL=0; //时钟线拉低
_nop_();
_nop_();
_nop_();
_nop_();
//DelayUs(4); //电平保持时间
IIC_SCL=1; //时钟线拉高
_nop_();
_nop_();
_nop_();
_nop_();
//DelayUs(4); //电平保持时间
IIC_SDA=1; //数据线拉高
_nop_();
_nop_();
_nop_();
_nop_();
}
/*
函数功能:获取应答信号
返 回 值:1表示失败,0表示成功
*/
unsigned char IIC_GetACK(void)
{
unsigned char cnt=0;
//IIC_SDA_INPUTMODE();//初始化SDA为输入模式
IIC_SDA=1; //数据线上拉
_nop_();
_nop_();
//DelayUs(2); //电平保持时间
IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据
_nop_();
_nop_();
//DelayUs(2); //电平保持时间,等待从机发送数据
IIC_SCL=1; //时钟线拉高,告诉从机,主机现在开始读取数据
while(IIC_SDA) //等待从机应答信号
{
cnt++;
if(cnt>250)return 1;
}
IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据
return 0;
}
/*
函数功能:主机向从机发送应答信号
函数形参:0表示应答,1表示非应答
*/
void IIC_SendACK(unsigned char stat)
{
//IIC_SDA_OUTMODE(); //初始化SDA为输出模式
IIC_SCL=0; //时钟线拉低,告诉从机,主机需要发送数据
if(stat)IIC_SDA=1; //数据线拉高,发送非应答信号
else IIC_SDA=0; //数据线拉低,发送应答信号
_nop_();
_nop_();
//DelayUs(2); //电平保持时间,等待时钟线稳定
IIC_SCL=1; //时钟线拉高,告诉从机,主机数据发送完毕
_nop_();
_nop_();
//DelayUs(2); //电平保持时间,等待从机接收数据
IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据
IIC_SDA=1; //数据线上拉
}
/*
函数功能:IIC发送1个字节数据
函数形参:将要发送的数据
*/
void IIC_WriteOneByteData(uchar Indata)
{
unsigned char i;
//IIC_SDA_OUTMODE(); //初始化SDA为输出模式
IIC_SCL=0; //时钟线拉低,告诉从机,主机需要发送数据
for(i=0;i<8;i++)
{
if(Indata&0x80)IIC_SDA=1; //数据线拉高,发送1
else IIC_SDA=0; //数据线拉低,发送0
IIC_SCL=1; //时钟线拉高,告诉从机,主机数据发送完毕
_nop_();
_nop_();
//DelayUs(2); //电平保持时间,等待从机接收数据
IIC_SCL=0; //时钟线拉低,告诉从机,主机需要发送数据
_nop_();
_nop_();
//DelayUs(2); //电平保持时间,等待时钟线稳定
Indata<<=1; //先发高位
}
}
/*
函数功能:IIC接收1个字节数据
返 回 值:收到的数据
*/
uchar IIC_ReadOneByteData(void)
{
uchar i,outdata;
//IIC_SDA_INPUTMODE();//初始化SDA为输入模式
for(i=0;i<8;i++)
{
IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据
_nop_();
_nop_();
//DelayUs(2); //电平保持时间,等待从机发送数据
IIC_SCL=1; //时钟线拉高,告诉从机,主机现在正在读取数据
outdata<<=1;
if(IIC_SDA) outdata|=0x01;
//DelayUs(2); //电平保持时间,等待时钟线稳定
}
IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据 (必须拉低,否则将会识别为停止信号)
return outdata;
}
/***************************************************************
* 函数名称: SHT3x_CheckCrc
* 说 明: 检查数据正确性
* 参 数: data:读取到的数据
nbrOfBytes:需要校验的数量
checksum:读取到的校对比验值
* 返 回 值: 校验结果,0-成功1-失败
***************************************************************/
uchar SHT3x_CheckCrc(char crcdata[], char nbrOfBytes, char checksum)
{
char crc = 0xFF;
char Rbit = 0;
char byteCtr ;
//calculates 8-Bit checksum with given polynomial
for(byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)
{
crc ^= (crcdata[byteCtr]);
for ( Rbit = 8; Rbit > 0; --Rbit)
{
if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;
else crc = (crc << 1);
}
}
if(crc != checksum)
return 1;
else
return 0;
}
/***************************************************************
* 函数名称: SHT3x_CalcTemperatureC
* 说 明: 温度计算
* 参 数: u16sT:读取到的温度原始数据
* 返 回 值: 计算后的温度数据
***************************************************************/
float SHT3x_CalcTemperatureC(unsigned short u16sT)
{
float temperatureC = 0; // variable for result
u16sT &= ~0x0003; // clear bits [1..0] (status bits)
//-- calculate temperature [℃] --
temperatureC = (175 * (float)u16sT / 65535 - 45); //T = -45 + 175 * rawValue / (2^16-1)
return temperatureC;
}
/***************************************************************
* 函数名称: SHT3x_CalcRH
* 说 明: 湿度计算
* 参 数: u16sRH:读取到的湿度原始数据
* 返 回 值: 计算后的湿度数据
***************************************************************/
float SHT3x_CalcRH(unsigned short u16sRH)
{
float humidityRH = 0; // variable for result
u16sRH &= ~0x0003; // clear bits [1..0] (status bits)
//-- calculate relative humidity [%RH] --
humidityRH = (100 * (float)u16sRH / 65535); // RH = rawValue / (2^16-1) * 10
return humidityRH;
}
void Sht30_init()
{
IIC_Start(); //发送起始信号
IIC_WriteOneByteData(0x44<<1|0); //写设备地址
IIC_GetACK();//获取应答
IIC_WriteOneByteData(0x21); //写设备地址
IIC_GetACK();//获取应答
IIC_WriteOneByteData(0x30); //写设备地址
IIC_GetACK();//获取应答
IIC_Stop(); //停止信号
}
//读取温湿度数据
void SHT3x_ReadData(void)
{
uchar r_s=0;
unsigned short tmp = 0;
IIC_Start(); //发送起始信号
IIC_WriteOneByteData(0x44<<1|0); //写设备地址
r_s=IIC_GetACK();//获取应答
IIC_WriteOneByteData(0xE0); //写数据
r_s=IIC_GetACK();//获取应答
IIC_WriteOneByteData(0x00); //写数据
r_s=IIC_GetACK();//获取应答
//读取sht30传感器数据
IIC_Start(); //发送起始信号
IIC_WriteOneByteData(0x44<<1|1);
r_s=IIC_GetACK();//获取应答
SHT3X_Data_Buffer[0]= IIC_ReadOneByteData();
IIC_SendACK(0); //发送应答信号
SHT3X_Data_Buffer[1]= IIC_ReadOneByteData();
IIC_SendACK(0); //发送应答信号
SHT3X_Data_Buffer[2]= IIC_ReadOneByteData();
IIC_SendACK(0); //发送应答信号
SHT3X_Data_Buffer[3]= IIC_ReadOneByteData();
IIC_SendACK(0); //发送应答信号
SHT3X_Data_Buffer[4]= IIC_ReadOneByteData();
IIC_SendACK(0); //发送应答信号
SHT3X_Data_Buffer[5]= IIC_ReadOneByteData();
IIC_SendACK(1); //发送非应答信号
IIC_Stop(); //停止信号
Read_temp = (SHT3X_Data_Buffer[0] << 8) | SHT3X_Data_Buffer[1];
Sht30_Temperature = SHT3x_CalcTemperatureC( Read_temp );
Read_hum = (SHT3X_Data_Buffer[3] << 8) | SHT3X_Data_Buffer[4];
Sht30_Humidity = SHT3x_CalcRH( Read_hum );
}
void Uart_Init(void)//9600bps@11.0592MHz
{
PCON &= 0x7F;
SCON = 0x50;
TMOD &= 0x0F;
TMOD |= 0x20;
TL1 = 0xFD;
TH1 = 0xFD;
ET1 = 0;
TR1 = 1;
EA=1;
ES=0;
}
void UART_sendbyte(unsigned char byte)
{
SBUF=byte;
while(TI==0);
TI=0;
}
void UART_send(float byte)
{
unsigned char i;
char *p;
p=(char*)(&byte);
for(i=0;i<4;i++)
{
UART_sendbyte(*p);
p++;
}
}
void Send_String_Com1(unsigned char *s,unsigned int strlen)
{
unsigned int k= 0 ;
do
{
UART_sendbyte(*(s + k));
k++;
}while(k < (strlen));
}
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void main (void)
{
Sht30_init();
Uart_Init();//9600bps@11.0592MHz
while(1)
{
Delay(1000);
SHT3x_ReadData();//Sht30_Humidity,Sht30_Temperature;
UART_send(Sht30_Humidity) ;
UART_send(Sht30_Temperature) ;
}
}