HTU21D


////////////////////////

#include"HardWare.h"
////////////////////////////////////////////////////////////////////////

#define HTU21ADDR 0x80 //芯片的地址
#define ACK 0
#define NACK 1


uchar CRC=0; //读温度传感器所用的一个校验
uchar Flag_BDXS=0; //=1 当前在
uchar Flag_Tempr_Start=0; //温度采集需要开始标志
uchar Flag_Tempr_StartOK=0; //温度采集已经开始标志
uchar Flag_Tempr_OK=0; //温度采集完成标志位 湿度同时也完成了
uchar Flag_TemprINT=0; //=1 温度初始化OK


/////////////////////////////////////////////////////////////////////////////
void TempWaitUs(uint a) //等待的微秒数 特指当前的主频 16777216
{
uchar i;
do
{
i=0;
i++;
i++;
i++;

i++;
i++;
i++;
i++;

i++;
i++;
i++;
}while(--a);
}

//I2C启动函数
void I2C_STARTpnn()
{
SENSORSDA_DIR&=~SENSORSDA; //SENSORSDA配置为输入,拉高总线
SENSORSCL_OUT|=SENSORSCL;
TempWaitUs(4); //延时3.3US

SENSORSDA_OUT&=~SENSORSDA; //SENSORSDA拉低
SENSORSDA_DIR|=SENSORSDA; //SENSORSDA配置为输出
TempWaitUs(7); //延时6.6US
SENSORSCL_OUT&=~SENSORSCL;
TempWaitUs(7); //延时6.6US
}

//I2C停止函数
void I2C2_Stoppnn() //应答
{
SENSORSDA_OUT&=~SENSORSDA; //SENSORSDA拉低
SENSORSDA_DIR|=SENSORSDA; //SENSORSDA配置为输出
SENSORSCL_OUT&=~SENSORSCL; //SENSORSCL=0
TempWaitUs(4); //延时3.3US
SENSORSCL_OUT|=SENSORSCL; //SENSORSCL=1
TempWaitUs(4); //延时3.3US
SENSORSDA_DIR&=~SENSORSDA; //SENSORSDA=1
TempWaitUs(4); //延时3.3US
}

//主发送从接收8位数据+检测ACK函数
uchar I2C_TXpnn(uchar I2C_TX_DATA) // 发送一个字节+检测 Ack
{
uchar i;
SENSORSCL_OUT&=~SENSORSCL; //SENSORSCL=0
for(i=0;i<8;i++)
{
if(I2C_TX_DATA&0x80){SENSORSDA_DIR&=~SENSORSDA;}
else
{
SENSORSDA_OUT&=~SENSORSDA;
SENSORSDA_DIR|=SENSORSDA;
}
TempWaitUs(4); //延时3.3US
SENSORSCL_OUT|=SENSORSCL; //SENSORSCL拉高
TempWaitUs(7); //延时6.6US
SENSORSCL_OUT &=~SENSORSCL; //SENSORSCL=0
TempWaitUs(4); //延时3.3US
I2C_TX_DATA<<=1; //向左移动一位
}
SENSORSDA_DIR&=~SENSORSDA; //SENSORSDA配置为输入,拉高总线
SENSORSCL_OUT |=SENSORSCL; //SENSORSCL=0
TempWaitUs(7); //延时6.6US
if(SENSORSDA_IN & SENSORSDA) //从设备无响应
{
SENSORSCL_OUT&=~SENSORSCL; //SENSORSCL拉低
TempWaitUs(17); //延时16.5US
return NACK;
}
else //从设备响应
{
SENSORSCL_OUT&=~SENSORSCL; //SENSORSCL拉低
TempWaitUs(17); //延时16.5US
return ACK;
}
}

//主接收从发送8位数据
uchar I2C_RXpnn(uchar AckValue)


{
uchar i;
uchar I2C_RX_DATA=0;
SENSORSCL_OUT&=~SENSORSCL; //SENSORSCL拉低
SENSORSDA_DIR&=~SENSORSDA; //SENSORSDA配置为接收状态
for(i=0;i<8;i++)
{
I2C_RX_DATA<<=1; //向左移动一位
SENSORSCL_OUT |= SENSORSCL; //SENSORSCL拉高
TempWaitUs(7); //延时6.6US
if(SENSORSDA_IN & SENSORSDA){I2C_RX_DATA|=0x01;}
else {I2C_RX_DATA&=0xfe;}
SENSORSCL_OUT&=~SENSORSCL;
TempWaitUs(4); //延时3.3US
}
//主机是否要求从机停止发送函数
if(AckValue)
{
SENSORSDA_DIR&=~SENSORSDA; //SENSORSDA_OUT=1; //如果为1,要求从机停止发送
}
else
{
SENSORSDA_OUT&=~SENSORSDA;
SENSORSDA_DIR|=SENSORSDA; //SENSORSDA配置为输入释放总线
}
TempWaitUs(4); //延时3.3US
SENSORSCL_OUT|=SENSORSCL; //SENSORSCL拉高
TempWaitUs(17); //延时16.5US
SENSORSCL_OUT&= ~SENSORSCL; //SENSORSCL拉高
SENSORSDA_DIR&=~SENSORSDA;
TempWaitUs(1); //延时0.3US
return I2C_RX_DATA;
}


uchar CRC_check(uchar crc_bytes,uchar *pbuf,uchar checksum) //判断校验和是否对 对返回1
{
uchar crc=0;
uchar i;
uchar byteCtr;
for(byteCtr=0; byteCtr{
crc^=*(pbuf+crc_bytes-1-byteCtr);
for(i=8;i>0;i--)
{
if(crc&0x80){crc=(crc<<1)^0x0131;}
else {crc=(crc<<1);}
}
}
if(crc==checksum){return(1);}
else {return(0);}
}

void Htu_Read(void) //读温湿度
{
uchar j,k;
uchar whatdo;
ulong wendu_check_shidu; //由于温度变化对湿度值引起的修正量
uchar CRC_temp; //CRC校验值
uchar HandT[2]; //用于存放16位数

int lstemp;
uchar HTU21_TEST; //温湿度响应次数

ulong temp; //16位值暂存器
ulong shidu=0;
ulong wendu=0;

for(k=0;k<2;k++)
{
if(k==0)whatdo=0xf3; //读回来的是温度
else whatdo=0xf5; //读回来的是湿度
I2C_STARTpnn();
if(I2C_TXpnn(HTU21ADDR&0xfe)==ACK) //写地址
{
if(I2C_TXpnn(whatdo)==ACK) //转化命令
{
I2C_STARTpnn();
HTU21_TEST=1;
while(I2C_TXpnn(HTU21ADDR|0x01)==NACK)//检测是否对读数响应
{
DelayMs(1); //延时50MS转化
I2C_STARTpnn();
HTU21_TEST++; //最多约20次有响应.
if(HTU21_TEST>=40) //return 0;//5次后自动退出,返回主函数
{
This.HumVal=333;
This.TempVal=333;
return;
}
}

HandT[1]=I2C_RXpnn(ACK); //读高八位
HandT[0]=I2C_RXpnn(ACK); //读低八位
CRC_temp=I2C_RXpnn(NACK); //CRC校验位
I2C2_Stoppnn();

if(CRC_che

ck(2,HandT,CRC_temp)){This.TempBadCount=0;}//校验和对 //CRC校验函数
else
{
This.HumVal=444;
This.TempVal=444;
if(This.TempBadCount<250)This.TempBadCount++;
return;
} //校验和错 结束

HandT[0]&=0xfc;
temp=((ulong)HandT[1])*((ulong)256)+(ulong)HandT[0]; //可能是温度或湿度
if(whatdo==0xf5) //这是湿度
{
temp = temp*(12500);
temp = temp/(65536);
temp = temp-(600);
if(2500>wendu)
{
wendu_check_shidu=12*wendu;
wendu_check_shidu=30000-wendu_check_shidu;
wendu_check_shidu=wendu_check_shidu/100;
shidu=temp-wendu_check_shidu;
}
else
{
wendu_check_shidu=12*wendu;
wendu_check_shidu=wendu_check_shidu-30000;
wendu_check_shidu=wendu_check_shidu/100;
shidu=temp+wendu_check_shidu;
}
shidu=shidu/10;
This.HumVal0=shidu;

//湿度偏移量修正
This.HumVal=This.HumVal0+This.HumCoe; //加偏移量
if (This.HumVal<0) This.HumVal=0;
else if(This.HumVal>999)This.HumVal=999;
}
//
else //这是温度
{
if(temp>17473)
{
j=0;
temp=17572*temp;
temp=temp/65536;
wendu=temp-4685;
}
else //负温度
{
j=1;
temp=17572*temp;
temp=temp/65536;
wendu=4685-temp;
}
wendu=wendu/10;
if(j){This.TempVal0=0-wendu;}
else {This.TempVal0= wendu;}
//温度偏移量修正
lstemp=This.TempVal0+This.TempCoe;
if (lstemp<-350){lstemp=-350;}
else if(lstemp>799) {lstemp=799;}

This.TempVal=lstemp;
}
}
}
else
{
This.HumVal=0;
This.TempVal=0;
return;
}
}
}

uchar Htu_Start(void) //启动采集转换
{
I2C_STARTpnn();
I2C_TXpnn(0X80);
I2C_TXpnn(0XFE);
I2C2_Stoppnn();
//DelayMs(20); //延时15MS
return(1);
}

void Htu_Init(void) //初始化
{
SENSORSCL_SEL&=~SENSORSCL;
SENSORSCL_DIR|=SENSORSCL;
SENSORSDA_SEL&=~SENSORSDA;
}

相关文档
最新文档