久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3734|回復: 11
打印 上一主題 下一主題
收起左側

單片機讀DHT12只能讀出濕度,溫度和校驗值全是FF?

[復制鏈接]
跳轉到指定樓層
樓主
ID:5616 發表于 2019-3-13 20:45 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
各位高手,51單片機讀DHT12,I2C,只能讀出濕度值,溫度值和校驗值都是FF,換了一個傳感器還是這樣,已經一周了,折騰的夠嗆,請高手幫忙分析一下程序,多謝了!

#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int

sbit I2C_SCL = P1^6;                        //DHT12時鐘線
sbit I2C_SDA = P1^7;                //DHT12數據線
                                                                        
void delay_ms(uint tim);                                                                          //毫秒級延時函數聲明
void delay_n10us(uchar tim);                                                                 //10倍微秒級延時函數聲明

void I2C_delay(void);
void I2C_Start(void);
void I2C_Stop(void);
void I2C_Ack(void);
void I2C_NAck(void);
uchar I2C_Wait_Ack(void);
void I2C_WriteByte(uchar txd);
uchar I2C_ReadByte(uchar ack);

void Init_DHT12();                                                                //初始化
void Read_DHT12(uchar *sht);                                               //測量DHT12的溫度濕度值,指針
                                                        
void main()
{
        uchar read_dht[5];                                                        //存放從DHT12讀取的數據
        float temperature=0.0,humidity=0.0;                               //將溫濕度轉為小數(保留2位)
               
        Init_DHT12();
        delay_ms(2000);
        
        while(1)
        {
                Read_DHT12(read_dht);                                                    //從DHT12中讀數據
                temperature = 1.0 * read_dht[2] + 0.1 * read_dht[3];            
                humidity = 1.0 * read_dht[0] + 0.1 * read_dht[1];               
        }
}

//產生起始信號
void I2C_Start(void)
{
     I2C_SDA = 1;        //注意先拉高SDA,否則可能會誤認為是停止信號
    delay_n10us(1);
    I2C_SCL = 1;
    delay_n10us(5);
    I2C_SDA = 0;
    delay_n10us(5);
    I2C_SCL = 0;
    delay_n10us(1);
}
//產生停止信號
void I2C_Stop(void)
{
    I2C_SCL = 0;
    delay_n10us(1);
    I2C_SDA = 0;
    delay_n10us(5);
    I2C_SCL = 1;
    delay_n10us(5);
    I2C_SDA = 1;
    delay_n10us(1);
}
//主機產生應答信號
void I2C_Ack(void)
{
    I2C_SCL = 0;
    delay_n10us(1);
    I2C_SDA = 0;
    delay_n10us(5);
    I2C_SCL = 1;
    delay_n10us(5);
    I2C_SCL = 0;
    delay_n10us(1);
}
//主機產生不應答信號
void I2C_NAck(void)
{
    I2C_SCL = 0;
    delay_n10us(1);
    I2C_SDA = 1;
    delay_n10us(5);
    I2C_SCL = 1;
    delay_n10us(5);
    I2C_SCL = 0;
    delay_n10us(1);
}
//主機等待從機應答信號
//返回值為0,接收應答成功,返回值為1,接收應答失敗
uchar I2C_Wait_Ack(void)
{
    uchar tempTime = 0;
    I2C_SCL = 0;
    delay_n10us(1);
    I2C_SDA = 1;
    delay_n10us(5); //增加等待從動件發送應答信號的時間,怕有些器件反應慢
    I2C_SCL = 1;
    delay_n10us(5);
    while(I2C_SDA == 1)//等于1,則無應答
    {
        tempTime++;
        if( tempTime > 250 )//一直無應答
        {
            I2C_Stop();
            return 1;
        }
       delay_n10us(2);
    }
    I2C_SCL = 0;
    delay_n10us(5);
    return 0;
}
//發送一個字節
void I2C_WriteByte(uchar txd)
{
    uchar i = 0;
    I2C_SCL = 0;        //拉低SCL為發送數據準備        
    for(i = 0; i < 8; i++)
    {
        I2C_SCL = 0;
        I2C_SDA = (txd & 0x80) >> 7;
        txd = txd << 1;        //左移1位
        delay_n10us(5);
        I2C_SCL = 1;        //拉高SCL
        delay_n10us(5);
     }
    I2C_SCL = 0;
}
//讀取一個字節
uchar I2C_ReadByte(uchar ack)
{
    uchar i = 0;
    uchar rxd = 0;
    I2C_SCL = 0;        
    delay_n10us(1);
    I2C_SDA = 1;
    delay_n10us(5);        //等待從機準備信號
    for(i = 0; i < 8; i++)
    {
        I2C_SCL = 0;
        delay_n10us(10);        //等待從機準備信號
        I2C_SCL = 1;        //拉高SCL
        delay_n10us(10);
        rxd = rxd << 1;        //左移一位,最低位補0
        rxd = rxd | I2C_SDA;        //然后與SDA的狀態取或
    }
    I2C_SCL = 0;
    if(ack == 0)
        I2C_NAck();
    else
        I2C_Ack();
    return rxd;
}
void Init_DHT12()
{
    I2C_SDA = 1;        
    delay_n10us(1);
    I2C_SCL = 1;        
    delay_n10us(1);
}
//讀取DHT12的溫度濕度值
void Read_DHT12(uchar *dht)
{
    I2C_Start();
    I2C_WriteByte(0xB8);        //DHT12寫地址0xB8,讀地址為0xB9
    I2C_Wait_Ack();
    I2C_WriteByte(0x00);        //寫地址
    I2C_Wait_Ack();        //等待從機響應
    I2C_Start();
    I2C_WriteByte(0xB9);        //讀指令
    I2C_Wait_Ack();        //等待從機響應
    dht[0] = I2C_ReadByte(1);        //讀濕度整數位
    dht[1] = I2C_ReadByte(1);        //讀濕度小數位
    dht[2] = I2C_ReadByte(1);        //讀溫度整數位
    dht[3] = I2C_ReadByte(1);        //讀溫度小數位
    dht[4] = I2C_ReadByte(0);        //讀校驗位
    I2C_Stop();
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:5616 發表于 2019-3-13 20:48 | 只看該作者
顯示我是用MAX7219,那部分程序就不發了,否則太長了。濕度值顯示正常,手靠近也會變好,但就是溫度值的整數部分、小數部分和校驗值都是FF,不知道為何?參考惡劣官方的例程(stm32的),和他的程序幾乎一模一樣,結果仍然是這樣。我按照程序一個一個脈沖的分析了,也沒有發現時序不對,愁死了。請熟悉I2C的幫忙看一下,多謝了。
回復

使用道具 舉報

板凳
ID:234075 發表于 2019-3-14 01:08 | 只看該作者
沒用過這個器件,不過既然濕度能正常讀出來,IIC通信應該沒問題的。我看你是先讀濕度,然后讀取溫度,試試讀取數據時增加延時,部分器件數據轉換需要時間~
回復

使用道具 舉報

地板
ID:5616 發表于 2019-3-14 08:06 | 只看該作者
困擾多天,始終得不到解決,還望熟悉I2C的幫忙解決一下,謝謝!
回復

使用道具 舉報

5#
ID:5616 發表于 2019-3-14 20:03 | 只看該作者
感謝上面這位朋友,我也很奇怪,濕度能讀出,溫度讀不出,可能還是時序的問題,只有再試試了。
回復

使用道具 舉報

6#
ID:502218 發表于 2019-5-11 16:56 | 只看該作者
我也遇到這個問題,請問現在有解決方案了嗎
回復

使用道具 舉報

7#
ID:587604 發表于 2019-7-21 10:06 | 只看該作者
請問樓主大哥現在解決了嘛?
回復

使用道具 舉報

8#
ID:425246 發表于 2019-8-3 21:14 來自手機 | 只看該作者
你好,解決了嗎,我也遇到了這個問題
回復

使用道具 舉報

9#
ID:116893 發表于 2019-9-11 11:04 | 只看該作者
這幾天也在玩這傳感器,stm32例程轉到STC8上來,也是一直不行。后面加好幾十毫秒以上的延時可以正確通過校驗后獲取正常溫 濕 度......
回復

使用道具 舉報

10#
ID:116893 發表于 2019-9-11 11:12 | 只看該作者

如果用函數名字說明一下,就是這個樣子:
unsigned char Data;//定義一個緩沖寄存器。
   IIC_Start();//產生起始信號
   IIC_Send_Byte(0xB8);//寫入設備地址(寫)
   IIC_Wait_Ack();//等待設備的應答
   IIC_Send_Byte(0x00);//寫入要操作的單元地址。(0x00~0x04)
   IIC_Wait_Ack();//等待設備的應答。
   IIC_Stop();//產生停止符號。
   IIC_Start();//產生起始信號
   IIC_Send_Byte(0xB9);//寫入設備地址(讀)
   IIC_Wait_Ack();//等待設備的應答
   Data=IIC_Read_Byte();//讀入數據。
   IIC_Stop();//產生停止符號。
( delay(50);//我在每次結束后加了大概50毫秒延時,可以通過校驗,不通過校驗的概率也很大.......

以上的步驟重復5次,分別輸入0x00~0x04這5個地址,就能讀出5個字節,
分別是濕度整數位,濕度小數位,溫度整數位,溫度小數位,校驗和。

回復

使用道具 舉報

11#
ID:141497 發表于 2019-11-10 23:19 | 只看該作者
allen2016 發表于 2019-9-11 11:12
如果用函數名字說明一下,就是這個樣子:
unsigned char Data;//定義一個緩沖寄存器。
   IIC_Start(); ...

請教一下,最近也在完這個DHT12,用I2C協議,問題是開機時能夠讀取一次完整的數據,之后程序讀不出數據了,這個I2C用在24C02上正常。請問一下是什么原因造成的?如果方便請回復一下,謝謝!
回復

使用道具 舉報

12#
ID:71233 發表于 2022-1-2 14:22 | 只看該作者
我的程序從以前讀寫24C02中搬過來的,現在讀出來的都是0xFF,不知道是什么原因。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91www在线观看| 美国黄色一级片 | 在线观看 亚洲 | 国产在线精品一区二区三区 | 国产超碰人人爽人人做人人爱 | 久操福利 | 激情综合五月天 | heyzo在线| 狠狠躁天天躁夜夜躁婷婷老牛影视 | 一级做a爰片性色毛片视频停止 | 日韩在线国产 | 日韩一区二区三区四区五区 | 999精品在线 | 网站一区二区三区 | 欧美亚洲另类丝袜综合网动图 | 日日摸天天添天天添破 | 久久久久国产一区二区三区四区 | 国产精品九九视频 | 91视视频在线观看入口直接观看 | 日韩中文字幕一区二区 | 国产日韩一区二区三免费 | 久热伊人| 在线观看成人精品 | 国产黄色大片 | www午夜视频 | 国产福利在线播放 | 日韩在线一区二区三区 | 久久精品国产一区二区电影 | 日本一二三区在线观看 | 黄色片在线观看网址 | 亚洲成人av一区二区 | 精品久久一区二区三区 | 日本久久久久久 | 久久久久久高清 | 欧美日韩视频一区二区 | 国产色婷婷精品综合在线手机播放 | 久久精品99 | 久久久久午夜 | 精品国产免费一区二区三区五区 | 一级毛片色一级 | 黄篇网址|