📄 sht11.c
字号:
#include "SysDef.h"
#include <math.h> //Keil library
#define noACK 0
#define ACK 1
//adr command r/w
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0
#define PinSDA BIT3
#define PinSCL BIT4
#define SHTXXDIR P5DIR
#define SHTXXOUT P5OUT
#define SHTXXIN P5IN
#define SHT_DATA_In() SHTXXDIR &=~ PinSDA
#define SHT_DATA_Out() SHTXXDIR |= PinSDA
#define SHT_SCK_In() SHTXXDIR &=~ PinSCL
#define SHT_SCK_Out() SHTXXDIR |= PinSCL
#define SHT_SCK_CLR() SHTXXOUT &=~ PinSCL
#define SHT_SCK_SET() SHTXXOUT |= PinSCL
#define SHT_DATA_CLR() SHTXXOUT &=~ PinSDA
#define SHT_DATA_SET() SHTXXOUT |= PinSDA
#define Read_SHT_DATA() SHTXXIN & PinSDA
#define _SHT_Shout_Time_ 1
#define TEMP 0x55
#define HUMI 0xAA
//extern fp32 Temp_Value,Humi_Value; //温湿度值,可与外围接口
typedef union
{
unsigned int i;
float f;
} value;
void Delay_us(uint value)
{
while(value--);
}
//-----------------------------------------------------------------------------------------
//温度,湿度测量部分
//-----------------------------------------------------------------------------------
uint8 s_write_byte(uint8 value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge
{
uint8 i,error=0,flag = 0;;
for (i=0x80;i>0;i/=2)
{ //shift bit for masking
if (i & value)
{ //masking value with i , write to SENSI-BUS
SHT_DATA_SET();
}
else
{
SHT_DATA_CLR();
}
SHT_SCK_SET(); //clk for SENSI-BUS
Delay_us(_SHT_Shout_Time_); //pulswith approx. 5 us
SHT_SCK_CLR();
Delay_us(_SHT_Shout_Time_);
}
SHT_DATA_SET(); //release SHT_DATA-line
Delay_us(_SHT_Shout_Time_);
SHT_SCK_SET(); //clk #9 for ack
Delay_us(_SHT_Shout_Time_);
SHT_DATA_In();
flag = SHTXXIN & PinSDA;
if(flag == PinSDA)
{
error = 1;
}
SHT_DATA_Out();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_CLR();
Delay_us(_SHT_Shout_Time_);
return error; //error=1 in case of no acknowledge
}
//----------------------------------------------------------------------------------
uint8 s_read_byte(uint8 ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
uint8 i,val=0;
SHT_DATA_SET(); //release SHT_DATA-line
SHT_DATA_In(); //SHT_DATA input
Delay_us(_SHT_Shout_Time_);
for (i=0x80;i>0;i/=2)
{ //shift bit for masking
SHT_SCK_SET(); //clk for SENSI-BUS
Delay_us(_SHT_Shout_Time_);
if (Read_SHT_DATA())
{
val=(val | i); //read bit
}
SHT_SCK_CLR();
Delay_us(_SHT_Shout_Time_);
}
//SHT_DATA=!ack; //in case of "ack==1" pull down SHT_DATA-Line
if(ack)
{
SHT_DATA_CLR();
}
else
{
SHT_DATA_SET();
}
SHT_DATA_Out();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_SET(); //clk #9 for ack
Delay_us(_SHT_Shout_Time_); //pulswith approx. 5 us
SHT_SCK_CLR();
Delay_us(_SHT_Shout_Time_);
SHT_DATA_SET(); //release SHT_DATA-line
return val;
}
//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start
// _____ ________
// SHT_DATA: |_______|
// ___ ___
// SHT_SCK : ___| |___| |______
{
SHTXXDIR |= PinSDA + PinSCL;
SHT_DATA_SET(); //Initial state
Delay_us(_SHT_Shout_Time_);
SHT_SCK_CLR();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_SET();
Delay_us(_SHT_Shout_Time_);
SHT_DATA_CLR();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_CLR();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_SET();
Delay_us(_SHT_Shout_Time_);
SHT_DATA_SET();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_CLR();
}
//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: SHT_DATA-line=1 and at least 9 SHT_SCK cycles followed by transstart
// _____________________________________________________ ________
// SHT_DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SHT_SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
{
uint8 i;
SHTXXDIR += PinSDA + PinSCL;
SHT_DATA_SET();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_CLR(); //Initial state
Delay_us(_SHT_Shout_Time_);
for(i=0;i<9;i++)
{ //9 SHT_SCK cycles
SHT_SCK_SET();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_CLR();
Delay_us(_SHT_Shout_Time_);
}
s_transstart(); //transmission start
}
//----------------------------------------------------------------------------------
uint8 s_softreset(void)
//----------------------------------------------------------------------------------
// resets the sensor by a softreset
{
uint8 error=0;
s_connectionreset(); //reset communication
error+=s_write_byte(RESET); //send RESET-command to sensor
return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
uint8 s_read_statusreg(uint8 *p_value, uint8 *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{
uint8 error=0;
s_transstart(); //transmission start
error=s_write_byte(STATUS_REG_R); //send command to sensor
*p_value=s_read_byte(ACK); //read status register (8-bit)
*p_checksum=s_read_byte(noACK); //read checksum (8-bit)
return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
uint8 s_write_statusreg(uint8 *p_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
uint8 error=0;
s_transstart(); //transmission start
error+=s_write_byte(STATUS_REG_W);//send command to sensor
error+=s_write_byte(*p_value); //send value of status register
return error; //error>=1 in case of no response form the sensor
}
//--------------------------------------------------------------------
float calc_dewpoint(float h,float t)
{
//--------------------------------------------------------------------
// calculates dew point
// input: humidity [%RH], temperature [癈]
// output: dew point [癈]
float logEx,dew_point;
logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2);
dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx);
return dew_point;
}
void SHT11Init()
{
unsigned error=0;
s_connectionreset();
error+=s_write_byte(STATUS_REG_W);
error+=s_write_byte(0x00);
if(error!=0)
{
s_connectionreset(); //in case of an error: connection reset
}
}
/*名称:读取湿度 */
/*输入:无 */
/*返回:湿度值,数据是int型,湿度是 */
/* 从传感器读回来的值,未做处理*/
unsigned char ErrNum;
int read_rh(void)
{
unsigned int ret_rh = 0x0000;
unsigned char temp0 = 0x00;
unsigned char temp1 = 0x00;
unsigned long i;
unsigned char flag;
s_transstart(); //transmission start
s_write_byte(MEASURE_HUMI);
SHT_DATA_In();
//等待转换结束
for(i=0;i<0xFFFFF0;i++)
{
flag = SHTXXIN & PinSDA;
if(flag != PinSDA)
{
i = 0xFFFFFF;
break;
}
}
flag = SHTXXIN & PinSDA;
if(flag == PinSDA)
{
ErrNum ++;
}
temp0 = s_read_byte(ACK); //read the first byte (MSB)
temp1 = s_read_byte(ACK); //read the second byte (LSB)
flag = s_read_byte(noACK);
ret_rh = (((unsigned int)(temp0 & 0x0F)) << 0x08) | ((unsigned int)temp1);
return ret_rh;
}
/*名称:读取温度 */
/*输入:无 */
/*返回:温度值,数据是int型,温度是 */
/* 从传感器读回来的值,未做处理 */
int read_t(void)
{
unsigned int ret_rh = 0x0000;
unsigned char temp0 = 0x00;
unsigned char temp1 = 0x00;
unsigned long i;
unsigned char flag;
s_transstart(); //transmission start
//error += s_write_byte(MEASURE_TEMP);
s_write_byte(MEASURE_TEMP);
SHT_DATA_In();
for(i=0;i<0xFFFFF0;i++)
{
flag = SHTXXIN & PinSDA;
if(flag != PinSDA)
{
i = 0xFFFFFF;
break;
}
}
flag = SHTXXIN & PinSDA;
if(flag == PinSDA)
{
ErrNum ++;
}
temp0 = s_read_byte(ACK); //read the first byte (MSB)
temp1 = s_read_byte(ACK); //read the second byte (LSB)
flag = s_read_byte(noACK);
ret_rh = (((unsigned int)(temp0 & 0x3F)) << 0x08) | ((unsigned int)temp1);
return ret_rh;
}
#define LBCS 5
float TemperArrary[LBCS],RHArrary[LBCS];
void AddArry()
{
//"向前推
for(uchar i=0;i<(LBCS-1);i++)
{
TemperArrary[i] = TemperArrary[i+1];
RHArrary[i] = RHArrary[i+1];
}
TemperArrary[LBCS-1] = envionment_variables.temperature;
RHArrary[LBCS-1] = envionment_variables.humidity;
uchar i;
float sum=0;
float max;
float min;
//"温度平均值
max = min = TemperArrary[0];
for(i=0;i<LBCS;i++)
{
if(max < TemperArrary[i])
{
max = TemperArrary[i];
}
else if(min > TemperArrary[i])
{
min = TemperArrary[i];
}
sum += TemperArrary[i];
}
sum -= max;
sum -= min;
sum /= LBCS-2;
//envionment_variables.temperature = sum;
envionment_variables.temperature = sum - envionment_variables.Zero_temperature;
//"湿度平均值
max = min = RHArrary[0];
for(i=0;i<LBCS;i++)
{
if(max < RHArrary[i])
{
max = RHArrary[i];
}
else if(min > RHArrary[i])
{
min = RHArrary[i];
}
sum += RHArrary[i];
}
sum -= max;
sum -= min;
sum /= LBCS-2;
//envionment_variables.humidity = sum;
envionment_variables.humidity = sum - envionment_variables.Zero_humidity; //湿度
}
unsigned int TempAD;
void MeasureSHT11Task()
{
unsigned int tem = 0x0000;
unsigned int rh = 0x0000;
float rh_linear = 0.0;
float rh_true = 0.0;
float tem_true = 0.0;
float dp = 0.0;
ErrNum = 0 ;
tem = read_t();
rh = read_rh();
if(ErrNum != 0) s_connectionreset();
else
{
TempAD = tem;
rh_linear = (0.0405 * (float)rh) + ((-2.8 * 0.000001) * rh * rh) - 4;
tem_true = (0.01 * (float)tem) - 39.64;
rh_true = ((float)tem_true - 25.0) * (0.01 + (0.00008 * (float)rh)) + rh_linear;
dp = calc_dewpoint(tem_true,rh_true);
envionment_variables.temperature = tem_true; //温度
envionment_variables.humidity = rh_true; //湿度
envionment_variables.dew_point = dp *100;
if((envionment_variables.Zero_temperature > -10.0) && (envionment_variables.Zero_temperature < 10.0))
{
envionment_variables.temperature = tem_true - envionment_variables.Zero_temperature; //温度
}
if((envionment_variables.Zero_humidity > -10.0) && (envionment_variables.Zero_humidity < 10.0))
{
envionment_variables.humidity = rh_true - envionment_variables.Zero_humidity; //温度
}
//envionment_variables.humidity = rh_true - envionment_variables.Zero_humidity; //湿度
//envionment_variables.dew_point = dp ;
//AddArry();
// SHT_DATA_In();
SHT_DATA_CLR();
}
}
//=============================================================================================
//=============================================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -