单片机
返回首页

SHT11数字温湿度传感器

2020-09-04 来源:51hei


单片机源程序如下:

#include   

#include   

#include 'LCD1602.h'

/********************************************************

宏定义

********************************************************/

#define uint unsigned int  

#define uchar unsigned char  

#define noACK 0

#define ACK   1

#define STATUS_REG_W 0x06

#define STATUS_REG_R 0x07

#define MEASURE_TEMP 0x03

#define MEASURE_HUMI 0x05

#define RESET        0x1e


enum { TEMP, HUMI };


typedef union               //定义共用同类型  

{

        unsigned int i;

        float f;

} value;



/********************************************************

位定义

********************************************************/

sbit SCK = P1 ^ 0;

sbit DATA = P1 ^ 1;


/********************************************************

变量定义

********************************************************/

uchar wendu[6];

uchar shidu[6];



/********************************************************

50us延时函数

********************************************************/

void delay_50us(uint t)

{

        uint j;

        for (; t>0; t--)

        for (j = 19; j>0; j--);

}



/*******************************************************

液晶显示函数

********************************************************/

void displaywendu(void)

{

        uchar i;

        write_com(0x80+0x40);

        write_data('T');

        write_data(':');

        for (i = 0; i<3; i++)

        {

                write_data(wendu[i]);

                delay_50us(1);

        }

        for (i = 0; i<1; i++)

        {

                write_data('.');

                delay_50us(1);

        }

        for (i = 4; i<5; i++)

        {

                write_data(wendu[i]);

                delay_50us(1);

        }

        write_data(0xDF);

        write_data('C');

}



/********************************************************

液晶显示函数

********************************************************/

void displayshidu(void)

{

        uchar i;

        write_com(0x80);

        write_data('H');

        write_data(':');

        for (i = 0; i<3; i++)

        {

                write_data(shidu[i]);

                delay_50us(1);

        }

        for (i = 0; i<1; i++)

        {

                write_data('.');

                delay_50us(1);

        }

        for (i = 4; i<5; i++)

        {

                write_data(shidu[i]);

                delay_50us(1);

        }

        write_data('%');

        write_data('R');

        write_data('H');

}


/********************************************************

SHT11写字节程序

********************************************************/

char s_write_byte(unsigned char value)

{

        unsigned char i, error = 0;

        for (i = 0x80; i>0; i >>= 1)             //高位为1,循环右移  

        {

                if (i&value) DATA = 1;          //和要发送的数相与,结果为发送的位  

                else DATA = 0;

                SCK = 1;

                _nop_(); _nop_(); _nop_();        //延时3us   

                SCK = 0;

        }

        DATA = 1;                           //释放数据线  

        SCK = 1;

        error = DATA;                       //检查应答信号,确认通讯正常  

        _nop_(); _nop_(); _nop_();

        SCK = 0;

        DATA = 1;

        return error;                     //error=1 通讯错误  

}


/********************************************************

SHT11读字节程序

********************************************************/

char s_read_byte(unsigned char ack)

{

        unsigned char i, val = 0;

        DATA = 1;                           //释放数据线  

        for (i = 0x80; i>0; i >>= 1)             //高位为1,循环右移  

        {

                SCK = 1;

                if (DATA) val = (val | i);             //读一位数据线的值   

                SCK = 0;

        }

        DATA = !ack;                        //如果是校验,读取完后结束通讯;  

        SCK = 1;

        _nop_(); _nop_(); _nop_();          //延时3us   

        SCK = 0;

        _nop_(); _nop_(); _nop_();

        DATA = 1;                           //释放数据线  

        return val;

}


/********************************************************

SHT11启动传输

********************************************************/

void s_transstart(void)

{

        DATA = 1; SCK = 0;                   //准备  

        _nop_();

        SCK = 1;

        _nop_();

        DATA = 0;

        _nop_();

        SCK = 0;

        _nop_(); _nop_(); _nop_();

        SCK = 1;

        _nop_();

        DATA = 1;

        _nop_();

        SCK = 0;

}



/********************************************************

SHT11连接复位

********************************************************/

void s_connectionreset(void)

{

        unsigned char i;

        DATA = 1; SCK = 0;                    //准备  

        for (i = 0; i<9; i++)                  //DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位  

        {

                SCK = 1;

                SCK = 0;

        }

        s_transstart();                   //启动传输  

}


/********************************************************

SHT11温湿度检测

********************************************************/

char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)

{

        unsigned error = 0;

        unsigned int i;


        s_transstart();                   //启动传输  

        switch (mode)                      //选择发送命令  

        {

        case TEMP: error += s_write_byte(MEASURE_TEMP); break;          //测量温度  

        case HUMI: error += s_write_byte(MEASURE_HUMI); break;          //测量湿度  

        default: break;

        }

        for (i = 0; i<65535; i++) if (DATA == 0) break;        //等待测量结束  

        if (DATA) error += 1;                              // 如果长时间数据线没有拉低,说明测量错误   

        *(p_value) = s_read_byte(ACK);           //读第一个字节,高字节 (MSB)  

        *(p_value + 1) = s_read_byte(ACK);          //读第二个字节,低字节 (LSB)  

        *p_checksum = s_read_byte(noACK);        //read CRC校验码  

        return error;                   // error=1 通讯错误  

}

/********************************************************

SHT11温湿度值标度变换及温度补偿

********************************************************/

void calc_sth10(float *p_humidity, float *p_temperature)

{

        const float C1 = -4.0;              // 12位湿度精度 修正公式  

        const float C2 = +0.0405;           // 12位湿度精度 修正公式  

        const float C3 = -0.0000028;        // 12位湿度精度 修正公式  

        const float T1 = +0.01;             // 14位温度精度 5V条件  修正公式  

        const float T2 = +0.00008;          // 14位温度精度 5V条件  修正公式  


        float rh = *p_humidity;             // rh:      12位 湿度   

        float t = *p_temperature;           // t:       14位 温度  

        float rh_lin;                     // rh_lin: 湿度 linear值  

        float rh_true;                    // rh_true: 湿度 ture值  

        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;       //湿度最小修正  


        *p_temperature = t_C;               //返回温度结果  

        *p_humidity = rh_true;              //返回湿度结果  

}

/********************************************************

主函数

********************************************************/

void main(void)

{

        unsigned int temp, humi;

        value humi_val, temp_val;        //定义两个共同体,一个用于湿度,一个用于温度  

        unsigned char error;            //用于检验是否出现错误  

        unsigned char checksum;         //CRC   

        LcdInitiate();

……………………


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 如何利用ESP8266制作一个简单的四轴飞行器

  • 非常简单的150W功放电路图

  • 一个简单的警笛电路图

  • 基于IC555的可变PWM振荡器电路

  • 一个简单的立体声平衡指示器电路

  • 电谐波图形均衡器示意图

    相关电子头条文章