📄 shtxx_iic.c
字号:
//温湿度传感器SHTXX系列,I2C接口程序
//2007-06-06
//-----------------------函数声明,变量定义--------------------------------------------------------
#include <reg52.h>
#include <intrins.h>
sbit SDA=P1^6; // 将p1.6口模拟数据口
sbit SCL=P1^7; // 将p1.7口模拟时钟口
#define uchar unsigned char
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
#define BIT7 0X80
#define BIT6 0X40
#define BIT5 0X20
#define BIT4 0X10
#define BIT3 0X08
#define BIT2 0X04
#define BIT1 0X02
#define BIT0 0X01
//#define NUM 10 // 接收和发送缓存区的深度
//unsigned char idata sendbuf[NUM]; // 数据发送缓冲区
//unsigned char idata receivebuf[NUM]; // 数据接收缓冲区
//bit bdata SystemError; // 从机错误标志位
//--------------------------------------------------------------------------------------------------
// 函数名称: iic_start()
// 函数功能: 启动I2C总线子程序
//--------------------------------------------------------------------------------------------------
void iic_start(void)
{
//:当SCK 时钟高电平时DATA 翻转为低电平,紧接着SCK 变为低电平,随后是在SCK时钟高电平时DATA 翻转为高电平。
// EA=0;
SDA = 1;
SCL = 1;
SDA = 0;
SCL = 0;
SCL = 1;
SDA = 1;
SCL = 0;
_nop_();_nop_();
}
//--------------------------------------------------------------------------------------------------
// 函数名称: iic_reset()
// 函数功能: 停止I2C总线数据传送子程序
//--------------------------------------------------------------------------------------------------
/*void iic_reset(void)
{
SDA = 1; //当DATA 保持高电平时,触发SCK 时钟9 次或更多。
SCL = 1;SCL = 0;
SCL = 1;SCL = 0;
SCL = 1;SCL = 0;
SCL = 1;SCL = 0;
SCL = 1;SCL = 0;
SCL = 1;SCL = 0;
SCL = 1;SCL = 0;
SCL = 1;SCL = 0;
SCL = 1;SCL = 0;
SCL = 1;SCL = 0;
}*/
//--------------------------------------------------------------------------------------------------
// 函数名称: iic_stop()
// 函数功能: 停止I2C总线数据传送子程序
//--------------------------------------------------------------------------------------------------
/*void iic_stop(void)
{
SDA = 1; //通过保持确认位ack 高电平,来中止通讯。
SCL = 1;SCL = 0;
}*/
//--------------------------------------------------------------------------------------------------
// 函数名称: slave_ACK
// 函数功能: 从机发送应答位子程序
//--------------------------------------------------------------------------------------------------
void slave_ACK(void)
{
SDA = 0;
SCL = 1;SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: slave_NOACK
// 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束
//--------------------------------------------------------------------------------------------------
void slave_NOACK(void)
{
SDA = 1; //通过保持确认位ack 高电平,来中止通讯。
SCL = 1;SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: check_ACK
// 函数功能: 主机应答位检查子程序,迫使数据传输过程结束
//--------------------------------------------------------------------------------------------------
void check_ACK(void)
{
SDA = 1; // 将p1.0设置成输入,必须先向端口写1
SCL = 1;
F0 = 0;
if(SDA == 1) // 若SDA=1表明非应答,置位非应答标志F0
F0 = 1;
SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: IICSendByte
// 入口参数: ch
// 函数功能: 发送一个字节
//--------------------------------------------------------------------------------------------------
void IICSendByte(unsigned char ch)
{
unsigned char idata n=8; // 向SDA上发送一位数据字节,共八位
while(n--)
{
if((ch&0x80) == 0x80) // 若要发送的数据最高位为1则发送位1
{
SDA = 1; // 传送位1
SCL = 1;SCL = 0;
}
else
{
SDA = 0; // 否则传送位0
SCL = 1;SCL = 0;
}
ch = ch<<1; // 数据左移一位
}
}
//--------------------------------------------------------------------------------------------------
// 函数名称: IICreceiveByte
// 返回接收的数据
// 函数功能: 接收一字节子程序
//--------------------------------------------------------------------------------------------------
unsigned char IICreceiveByte(void)
{
unsigned char idata n=8; // 从SDA线上读取一上数据字节,共八位
unsigned char tdata;
while(n--)
{
SDA = 1;
SCL = 1;
tdata = tdata<<1; // 左移一位,或_crol_(temp,1)
if(SDA == 1)
tdata = tdata|0x01; // 若接收到的位为1,则数据的最后一位置1
else
tdata = tdata&0xfe; // 否则数据的最后一位置0
SCL=0;
}
return(tdata);
}
//--------------------------------------------------------------------------------------------------
// 函数名称: InitSHTXX
// 函数功能: 初始化SHTXX
//--------------------------------------------------------------------------------------------------
void InitSHTXX(void)
{
unsigned char initdat;
initdat=0x06;//写状态寄存器命令
iic_start();//启动I2C
IICSendByte(initdat);//发送命令
// slave_ACK();//给SHTXX应答位
check_ACK();
if(F0==0)
{// initdat=0x00;//14bit(温度)、12bit(湿度)
initdat=0x01;//12bit(温度)、8bit(湿度)
IICSendByte(initdat);//发送状态字
//slave_ACK();//给SHTXX应答位
check_ACK();
}
}
//--------------------------------------------------------------------------------------------------
// 函数名称: ReadStatus
// 返回接收的数据
// 函数功能: 读状态寄存器
//--------------------------------------------------------------------------------------------------
/*unsigned char ReadStatus(void)
{
unsigned char rdata;
rdata=0x07;//读状态寄存器命令
iic_start();//启动I2C
IICSendByte(rdata);//发送命令
slave_ACK();//给SHTXX应答位
rdata=IICreceiveByte();//接收状态字
slave_NOACK();//给SHTXX非应答位,结束读命令
return(rdata);
}*/
//--------------------------------------------------------------------------------------------------
// 函数名称: MeasureTem
// 函数功能: 测量温度,调用后应延迟
//--------------------------------------------------------------------------------------------------
void MeasureTem(void)
{
unsigned char initdat;
initdat=0x03;//测量温度命令
iic_start();//启动I2C
IICSendByte(initdat);//发送命令
check_ACK();
/* TH0=0X28;
TL0=0X00;//11.0592MHz 60mS
TR0=1;*/
}
//--------------------------------------------------------------------------------------------------
// 函数名称: MeasureHum
// 函数功能: 测量湿度,调用后应延迟
//--------------------------------------------------------------------------------------------------
void MeasureHum(void)
{
unsigned char initdat;
initdat=0x05;//测量湿度命令
iic_start();//启动I2C
IICSendByte(initdat);//发送命令
check_ACK();
/* TH0=0Xca;
TL0=0X00;//11.0592MHz 15mS
TR0=1;*/
}
//--------------------------------------------------------------------------------------------------
// 函数名称: SoftReset
// 函数功能: 软复位,复位接口、清空状态寄存器, ,即清空为默认值,调用后应延迟11mS
//--------------------------------------------------------------------------------------------------
/*void SoftReset(void)
{
unsigned char initdat;
initdat=0x1E;//软复位命令
iic_start();//启动I2C
IICSendByte(initdat);//发送命令
/* TH0=0Xca;
TL0=0X00;//11.0592MHz 15mS
TR0=1;*/
//}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
// 函数名称: ReadData
// 返回接收的数据
// 函数功能: 读测量数据
//--------------------------------------------------------------------------------------------------
int ReadData(void)
{
int rdata;//int *p;
unsigned char dd[2];
while(SDA==1);//等待转换结束
dd[0]=IICreceiveByte();//接收状态字
slave_ACK();//给SHTXX应答位
dd[1]=IICreceiveByte();//接收状态字
slave_NOACK();//给SHTXX非应答位,结束读命令
// p=dd;
// rdata=*p;
rdata=(dd[0]<<8)+dd[1];
// rdata=dd[0]*256+dd[1];
return(rdata);
}
//--------------------------------------------------------------------------------------------------
// 函数名称: CalculateTem
// 返回计算后的温度数据
// 函数功能: 计算温度值
//--------------------------------------------------------------------------------------------------
float CalculateTem(void)
{
float rdata;int rdat;
// uchar *p;
float temp;
rdat=ReadData();
/* p=&rdat;
*p=*p&0x0f;//12bit模式,清除高4位
//*p=*p&0x3f;//14bit模式,清除高2位
*/ rdat=rdat&0x0fff;
rdata=rdat;
temp=0.04*rdata-40;//12bit温度公式
//temp=0.01*rdata-40;//14bit温度公式
return(temp);
}
//--------------------------------------------------------------------------------------------------
// 函数名称: CalculateHum
// 返回计算后的湿度数据
// 函数功能: 计算湿度值
//--------------------------------------------------------------------------------------------------
float CalculateHum(void)
{
float rdata;int rdat;
// uchar *p;
float hump;
rdat=ReadData();
/* p=&rdat;
*p=*p&0x00;//8bit模式,清除高8位
//*p=*p&0x0f;//12bit模式,清除高4位
*/ rdat=rdat&0x0ff;
rdata=rdat;
hump=0.648*rdata-rdata*rdata*0.00072-4;//8bit湿度公式
//temp=0.0405*rdata-rdata*rdata*0.0000028-4;//12bit湿度公式
return hump;
}
//--------------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -