⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sht75.c

📁 单片机c语言程序设计100例--基于PIC+PROTEUS
💻 C
字号:
//-----------------------------------------------------------------
//  名称: SHT75传感器程序(参照SENSIRION公司提供的8051版代码改编)
//-----------------------------------------------------------------
#define _XTAL_FREQ 4000000UL
#define INT8U   unsigned char
#define INT16U  unsigned int
#include <pic.h>
#include <stdio.h>
#include <math.h>
//传感器引脚相关定义
#define SCL  RB0
#define SDA  RB1
#define SDA_IN()     TRISB1 = 1  //设SDA数据方向为输入
#define SDA_OUT()    TRISB1 = 0  //设SDA数据方向为输出
//SHT75传感器命令集         //地址 命令 读/写
#define MEASURE_TEMP 0x03   //000  0001  1
#define MEASURE_HUMI 0x05   //000  0010  1
#define STATUS_REG_W 0x06   //000  0011  0
#define STATUS_REG_R 0x07   //000  0011  1
#define RESET        0x1E   //000  1111  0
//是否应答
#define NACK  0
#define ACK   1
//温湿度信息显示缓冲
char HT_Display_Buffer[20];
//定义温度与湿度符号
enum {TEMP,HUMI};
extern void PutStr(char *s);
//-----------------------------------------------------------------
// 写一节到SHT75并检查应答
//-----------------------------------------------------------------
INT8U s_Write_Byte(INT8U dat)
{ 


}

//-----------------------------------------------------------------
// 从传感器读一字节,在ack=1时发送应答
//-----------------------------------------------------------------
INT8U s_Read_Byte(INT8U ack)
{ 


}

//-----------------------------------------------------------------
// 传输开始
//-----------------------------------------------------------------
void s_TransStart()
{  
    //以下语句序列模拟传输开始的操作时序
    SDA = 1;   
    SCL = 0; __delay_us(1); SCL = 1; __delay_us(1); SDA = 0; __delay_us(1);
    SCL = 0; __delay_us(3); SCL = 1; __delay_us(1); SDA = 1; __delay_us(1);
    SCL = 0;    
}

//-----------------------------------------------------------------
// 传感器连接复位
//-----------------------------------------------------------------
void s_ConnectionReset()
{  
    INT8U i; 
    SDA = 1; SCL = 0;                            //初始状态
    for(i = 0; i < 9; i++) {SCL = 1; SCL = 0;}   //模拟9个时钟周期
    s_TransStart();                              //传输开始
}

//-----------------------------------------------------------------
// 传感器软复位
//-----------------------------------------------------------------
INT8U s_SoftReset()
{ 
    INT8U error = 0;
    s_ConnectionReset();                  //连接通讯复位
    error += s_Write_Byte(RESET);         //向传感器发送复位命令
    return error;                         //传感器无响应时返回1
}

//-----------------------------------------------------------------
// 读状态寄存器
//-----------------------------------------------------------------
INT8U s_Read_StatusReg(INT8U *p_value, INT8U *p_checksum)
{ 
    INT8U error = 0;
    s_TransStart();                       //传输开始
    error = s_Write_Byte(STATUS_REG_R);   //向传感器发送命令STATUS_REG_R
    *p_value = s_Read_Byte(ACK);          //读状态寄存器(8位)
    *p_checksum = s_Read_Byte(NACK);      //读取校验和(8位)
    return error;                         //传感器无响应时返回1
}

//-----------------------------------------------------------------
// 写状态寄存器
//-----------------------------------------------------------------
INT8U s_Write_StatusReg(INT8U *p_value)
{ 
    INT8U error = 0;
    s_TransStart();                       //传输开始
    error += s_Write_Byte(STATUS_REG_W);  //向传感器发送命令STATUS_REG_W
    error += s_Write_Byte(*p_value);      //发送状态寄存器的值
    return error;                         //传感器无响应时返回1
}
     
//-----------------------------------------------------------------
// 带校验码的温度与湿度测量
//-----------------------------------------------------------------
INT8U s_Measure(INT8U *p_value, INT8U *p_checksum, INT8U mode)
{ 
    INT8U i = 0, error = 0;
    s_TransStart();                       //传输开始
    switch(mode)                          //向传感器发送命令
    {  case TEMP : error += s_Write_Byte(MEASURE_TEMP); break;
       case HUMI : error += s_Write_Byte(MEASURE_HUMI); break;
       default   : break;    
    }
    SDA_IN(); 
    while (SDA && ++i < 40) __delay_ms(100);
    if(SDA) error+=1;                     //超时
    *(p_value)     = s_Read_Byte(ACK);    //读第一字节(MSB)
    *(p_value + 1) = s_Read_Byte(ACK);    //读第二字节(LSB)
    *p_checksum    = s_Read_Byte(NACK);   //读校验和
    return error;
}

//-----------------------------------------------------------------
// 计算温湿度
//-----------------------------------------------------------------
void Calc_STH75(float *p_humidity ,float *p_temperature)
{
    const float C1 = -4.0;              //12位,系数C1
    const float C2 = +0.0405;           //12位,系数C2
    const float C3 = -0.0000028;        //12位,系数C3
    const float T1 = +0.01;             //14位 @ 5V ,系数T1
    const float T2 = +0.00008;          //14位 @ 5V ,系数T2
    float rh = *p_humidity;             // rh:      湿度 12 Bit 
    float t  = *p_temperature;          // t:       温度 14 Bit
    float rh_lin;                       // rh_lin:  线性湿度
    float rh_true;                      // rh_true: 温度补偿湿度
    float t_C;                          // t_C   :  温度(℃)
    t_C = t * 0.01 - 40;                            //计算温度
    rh_lin = C3 * rh * rh + C2 * rh + C1;           //计算湿度
    rh_true=(t_C - 25) * (T1 + T2 * rh) + rh_lin;   //计算:温度补偿湿度
    if(rh_true > 100) rh_true = 100;      //将湿度数据限制在可能的范围之内
    if(rh_true < 0.1) rh_true = 0.1;      //即0.1% ~ 100%
    *p_temperature = t_C;                 //返回温度[℃]
    *p_humidity = rh_true;                //返回湿度[%RH]
}

//--------------------------------------------------------------------
// 根据输入的湿度与温度计算露点
//--------------------------------------------------------------------
float Calc_Dew_point(float h,float t)
{ 
    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;
}

//--------------------------------------------------------------------
// 延时函数(n x 100ms)
//--------------------------------------------------------------------
void delayX100ms(INT8U n)
{ 
    while (n--) __delay_ms(100);
}
    
//--------------------------------------------------------------------
// 传感器测试(读取湿度与温度数据并进行转换计算,送虚拟终端显示)
//--------------------------------------------------------------------
void Temp_and_Humi_Sensors_Test()
{ 
    INT8U a[2],b[2];                         //读传感器湿度与温度,各两字节
    float x,y,d;                             //计算转换后的湿度,温度,露点
    INT8U error,checksum;                    //错误及校验和
    s_ConnectionReset();                     //连接复位
    while(1)
    {   error = 0;
        error += s_Measure((INT8U*)a, &checksum, HUMI);  //测量湿度
        error += s_Measure((INT8U*)b, &checksum, TEMP);  //测量温度
        if(error !=0 ) s_ConnectionReset();              //出错时传感器连接复位
        else
        {  x = (float)(a[0] * 256.0 + a[1]);   //将两字节温度转换为float类型
           y = (float)(b[0] * 256.0 + b[1]);   //将两字节湿度转换为float类型
           Calc_STH75(&x,&y);                  //计算湿度与温度
           d = Calc_Dew_point(x,y);            //计算露点
           //生成指定格式的待输出字符串(GCC中sprintf不支持%f输出,因此需要转换)
           sprintf(HT_Display_Buffer,"HUMI:%5d.%1d%%  TEMP:%5d.%1d  DEW:%5d.%1d\r",
                   (int)x, (int)(fabs(x-(int)x)*10),
                   (int)y, (int)(fabs(y-(int)y)*10),
                   (int)d, (int)(fabs(d-(int)d)*10));
           PutStr(HT_Display_Buffer);        //向虚拟终端输出结果
        }
       //延时近0.8s,以免传感器过热
       delayX100ms(8); 
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -