51学习库(6)--DHT11温湿度传感器

学过51单片机的回过头来都会觉得51还是比较简单的,在此我将贴出在我的学习过程中,把对各种外设所进行的操作,封装成函数库的形式,以供新手学习。

注:使用的单片机是stc12c5a60s2,该系列单片机属于加强51,在运行速度上是普通51的8-12倍,有关时序的操作需要加以注意。
注2:使用示例:

void main()
{
    char i;
    char array[14] = "lalalal";
    lcd_init();
    delayms(1000);                  //等待DHT11稳定         
    while(1)
    {
        i = GetData();    //读数据
        if(i != 0)        //有错误
        {
            break;        //重新开始
        }

        i = Check();     //数据校验
        if(i != 0)       //有错误
        {
            break;   //重新开始
        }
        //此处应该得到准确数据;
        i = sprintf(array, "HR:%d.%d", (int)dat_r[0], (int)dat_r[1]);//湿度数值字符串放入array
        array[i] = '\0';
        lcd_pos(0, 0);    //第0行显示
        i = 0;
        while('\0' != array[i])
            lcd_wdat(array[i++]);

        i = sprintf(array, "TEMP:%d.%d", (int)dat_r[2], (int)dat_r[3]);
        array[i] = '\0';
        lcd_pos(1, 0);
        i = 0;
        while('\0' != array[i])
            lcd_wdat(array[i++]);

//        dat_r[0];             //湿度整数
//        dat_r[1];             //湿度小数(根据数据手册,DHT11小数部分一直是0没用)
//        dat_r[2];             //温度整数
//        dat_r[3];             //温度小数(根据数据手册,DHT11小数部分一直是0没用)
//        dat_r[4];                //校验值
        delayms(1000);             //经测试,两次连读要至少延时80ms        
    }
}//main

申明:本系列全部例程通过单片机开发板,实验亲测有效!

/* dht11 */
#define JUDGE        30      //用于判断通信的0和1,与单片机速度和晶振频率有关
sbit DATA = P1^0;                //定义数据引脚
uchar dat_r[5];                        //用于存放从DHT11读取到的数值
/*****************************************************************************
函数名:DHT11读数据函数
调  用:? = GetData();
参  数:无
返回值:失败->-1,-2,-3,-4;成功->0
结  果:读DHT11数据并保存到数组dat_r[]
备  注:
******************************************************************************/
char GetData (void)
{
    uchar i,j;                                //for循环变量
    uchar t;                                //超时判断
    uchar dat8=0;                        //一次读取的8位数据,需要读5次

    DATA = 0;                                //主机发起始信号
    delayms(20);                        //主机拉低总线至少18ms
    DATA = 1;                                //主机拉高总线20~40us
    delay10us(3);

    t = 80;                                        //设置超时等待时间
    while(DATA && t--);                //等待DHT11拉低总线
    if(t == 0)                                //超时
    {
        DATA = 1;
        return -1;                        //通信错误退出,返回错误信号:-1
    }
    //等80us响应信号
    t = 250;                                //设置超时等待时间
    while(!DATA && t--);        //等待DHT11拉高总线
    if(t == 0)                                //超时
    {
        DATA = 1;
        return -2;                        //通信错误退出,返回错误信号:-2
    }
    //等80us响应信号
    t = 250;                                //设置超时等待时间
    while(DATA && t--);                //等待DHT11拉低总线
    if(t == 0)                                //超时
    {
        DATA = 1;
        return -3;                     //通信错误退出,返回错误信号:-3
    }
    for(j=0; j<5; j++)                //5次读取
    {
        for(i=0; i<8; i++)                        //1次8个位
        {
            //等待50us开始时隙
            t = 150;                                //设置超时等待时间
            while(!DATA && t--);        //等待DHT11拉高总线
            if(t == 0)                                //超时
            {
                    DATA = 1;
                    return -4;                   //通信错误退出,返回错误信号:-4
            }
            t = 0;                                        //记录时间清零
            while(DATA && ++t);                //等待并记录高电平持续时间
            dat8 <<= 1;
            if(t > JUDGE)                        //高电平持续时间较长(70us)
                    dat8 += 1;                        //传输值为1
            //else dat8 += 0;
        }
        dat_r[j] = dat8;
    }

    delay10us(3);                //等待DHT11拉低50us
    delay10us(3);
    DATA = 1;                        //结束,拉高总线
    return 0;                        //返回成功信号
}

/******************************************************************************
函数名:数据校验函数
调  用:? = Check();
参  数:无
返回值:成功->0;失败->-1;
结  果:数据校验
备  注:数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。
******************************************************************************/
char Check (void)
{
    uchar i;                        //for循环变量
    uint chk=0;                        //校验和
    for(i=0; i<4; i++)
            chk += dat_r[i];                //累加
    if((uchar)chk != dat_r[4])        //比对
        return -1;                                //返回错误信号:-1
    else
        return 0;                                //返回正确信号:0
}

你可能感兴趣的