找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索

DS18B20溫度傳感器不能讀溫度,讀出來恒定一個(gè)數(shù),應(yīng)該是延時(shí)的問題

查看數(shù): 6506 | 評(píng)論數(shù): 7 | 收藏 0
關(guān)燈 | 提示:支持鍵盤翻頁(yè)<-左 右->
    組圖打開中,請(qǐng)稍候......
發(fā)布時(shí)間: 2019-6-26 10:26

正文摘要:

#include<reg51.h> #include<intrins.h> #include <ctype.h>        #include <stdlib.h>        #define LCD_DATA P0 sbit LCD_RS = P2^0; sbi ...

回復(fù)

ID:401564 發(fā)表于 2019-6-28 17:03
仿真是以AT8051的12T指令運(yùn)行的
STC89C52是6T指令
所有用到延時(shí)的延時(shí)時(shí)間要*2,定時(shí)器可以不用改
ID:503048 發(fā)表于 2019-6-27 17:46
現(xiàn)在仿真可以了,但是同樣代碼在硬件上不行
ID:503048 發(fā)表于 2019-6-27 17:44
青青梓衿 發(fā)表于 2019-6-26 14:32
如果你用的是12M的晶振就把復(fù)位里的低電平延時(shí)30改成70以上

仿真可以讀出來溫度,但是一燒到單片機(jī)上就不行了,單片機(jī)是STC89C52
ID:207421 發(fā)表于 2019-6-27 13:48
DS18B20 讀時(shí)序要求特別高,用實(shí)際硬件來調(diào)調(diào)吧,否則都用定時(shí)器
ID:427818 發(fā)表于 2019-6-26 23:41
先占個(gè)位置學(xué)習(xí)
ID:564898 發(fā)表于 2019-6-26 14:32
如果你用的是12M的晶振就把復(fù)位里的低電平延時(shí)30改成70以上
ID:164602 發(fā)表于 2019-6-26 10:26
我這個(gè)例程是使用過的,沒有問題。
有程序main.c:
/*******************************************************************************
* 實(shí)驗(yàn)名                           :溫度顯示實(shí)驗(yàn)
* 使用的IO             :
* 實(shí)驗(yàn)效果       :1602顯示溫度
*        注意                                         :
*******************************************************************************/

#include<reg51.h>
#include"temp.h"

//數(shù)碼管IO
#define DIG        P0
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

unsigned char code DIG_CODE[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char Num=0;
unsigned int disp[8]={0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f};

void LcdDisplay(int);
void Timer0Configuration();

/*******************************************************************************
* 函數(shù)名         : main
* 函數(shù)功能                   : 主函數(shù)
* 輸入           : 無
* 輸出                  : 無
*******************************************************************************/

void main()
{
    Timer0Configuration();
        while(1)
        {
                LcdDisplay(Ds18b20ReadTemp());
        }
}

/*******************************************************************************
* 函數(shù)名         : LcdDisplay()
* 函數(shù)功能                   : LCD顯示讀取到的溫度
* 輸入           : v
* 輸出                  : 無
*******************************************************************************/

void LcdDisplay(int temp)          //lcd顯示
{

          unsigned char datas[] = {0, 0, 0, 0, 0}; //定義數(shù)組
        float tp;  
        if(temp< 0)                                //當(dāng)溫度值為負(fù)數(shù)
          {
        disp[2] = 0x40;
                //因?yàn)樽x取的溫度是實(shí)際溫度的補(bǔ)碼,所以減1,再取反求出原碼
                temp=temp-1;
                temp=~temp;
                tp=temp;
                temp=tp*0.0625*100+0.5;       
                //留兩個(gè)小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語(yǔ)言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
                //后面的數(shù)自動(dòng)去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
                //算加上.5,還是在小數(shù)點(diǎn)后面。

          }
        else
          {       
        disp[2] = 0;               
                tp=temp;//因?yàn)閿?shù)據(jù)處理有小數(shù)點(diǎn)所以將溫度賦給一個(gè)浮點(diǎn)型變量
                //如果溫度是正的那么,那么正數(shù)的原碼就是補(bǔ)碼它本身
                temp=tp*0.0625*100+0.5;       
                //留兩個(gè)小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語(yǔ)言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
                //后面的數(shù)自動(dòng)去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
                //算加上0.5,還是在小數(shù)點(diǎn)后面。
        }
//    disp[0] = 0;
//    disp[1] = 0;
//    disp[3] = DIG_CODE[temp / 10000];
        disp[4] = DIG_CODE[temp % 10000 / 1000];
        disp[5] = DIG_CODE[temp % 1000 / 100] | 0x80;
        disp[6] = DIG_CODE[temp % 100 / 10];
        disp[7] = DIG_CODE[temp % 10];

}

/*******************************************************************************
* 函數(shù)名         : Timer0Configuration()
* 函數(shù)功能                   : 設(shè)置計(jì)時(shí)器
* 輸入           : 無
* 輸出                  : 無
*******************************************************************************/

void Timer0Configuration()
{
        TMOD=0X02;//選擇為定時(shí)器模式,工作方式2,僅用TRX打開啟動(dòng)。

        TH0=0X9C;        //給定時(shí)器賦初值,定時(shí)100us
        TL0=0X9C;       
        ET0=1;//打開定時(shí)器0中斷允許
        EA=1;//打開總中斷
        TR0=1;//打開定時(shí)器               
}

/*******************************************************************************
* 函數(shù)名         : DigDisplay() interrupt 1
* 函數(shù)功能                   : 中斷數(shù)碼管顯示
* 輸入           : 無
* 輸出                  : 無
*******************************************************************************/

void DigDisplay() interrupt 1
{
//定時(shí)器在工作方式二會(huì)自動(dòng)重裝初,所以不用在賦值。
//        TH0=0X9c;//給定時(shí)器賦初值,定時(shí)1ms
//        TL0=0X00;               
        DIG=0; //消隱
        switch(Num)         //位選,選擇點(diǎn)亮的數(shù)碼管,
        {
                case(7):
                        LSA=0;LSB=0;LSC=0; break;
                case(6):
                        LSA=1;LSB=0;LSC=0; break;
                case(5):
                        LSA=0;LSB=1;LSC=0; break;
                case(4):
                        LSA=1;LSB=1;LSC=0; break;
//                case(3):
//                        LSA=0;LSB=0;LSC=1; break;
//                case(2):
//                        LSA=1;LSB=0;LSC=1; break;
//                case(1):
//                        LSA=0;LSB=1;LSC=1; break;
//                case(0):
//                        LSA=1;LSB=1;LSC=1; break;       
        }
        DIG=disp[Num]; //段選,選擇顯示的數(shù)字。
        Num++;
        if(Num>7)
                Num=4;
}



溫度讀取程序temp.c:
#include"temp.h"
/*******************************************************************************
* 函數(shù)名         : Delay1ms
* 函數(shù)功能                   : 延時(shí)函數(shù)
* 輸入           : 無
* 輸出                  : 無
*******************************************************************************/

void Delay1ms(unsigned int y)
{
        unsigned int x;
        for(y;y>0;y--)
                for(x=110;x>0;x--);
}
/*******************************************************************************
* 函數(shù)名         : Ds18b20Init
* 函數(shù)功能                   : 初始化
* 輸入           : 無
* 輸出                  : 初始化成功返回1,失敗返回0
*******************************************************************************/

unsigned char Ds18b20Init()
{
        unsigned int i;
    EA = 0;
        DSPORT=0;                         //將總線拉低480us~960us
        i=70;       
        while(i--);//延時(shí)642us
        DSPORT=1;                        //然后拉高總線,如果DS18B20做出反應(yīng)會(huì)將在15us~60us后總線拉低
        i=0;
    EA = 1;
        while(DSPORT)        //等待DS18B20拉低總線
        {
                i++;
                if(i>5000)//等待>5MS
                        return 0;//初始化失敗       
        }
        return 1;//初始化成功
}

/*******************************************************************************
* 函數(shù)名         : Ds18b20WriteByte
* 函數(shù)功能                   : 向18B20寫入一個(gè)字節(jié)
* 輸入           : com
* 輸出                  : 無
*******************************************************************************/

void Ds18b20WriteByte(unsigned char dat)
{
        unsigned int i,j;
    EA = 0;
        for(j=0;j<8;j++)
        {
                DSPORT=0;                        //每寫入一位數(shù)據(jù)之前先把總線拉低1us
                i++;
                DSPORT=dat&0x01; //然后寫入一個(gè)數(shù)據(jù),從最低位開始
                i=6;
                while(i--); //延時(shí)68us,持續(xù)時(shí)間最少60us
                DSPORT=1;        //然后釋放總線,至少1us給總線恢復(fù)時(shí)間才能接著寫入第二個(gè)數(shù)值
                dat>>=1;
        }
    EA = 1;
}
/*******************************************************************************
* 函數(shù)名         : Ds18b20ReadByte
* 函數(shù)功能                   : 讀取一個(gè)字節(jié)
* 輸入           : com
* 輸出                  : 無
*******************************************************************************/


unsigned char Ds18b20ReadByte()
{
        unsigned char byte,bi;
        unsigned int i,j;
    EA = 0;       
        for(j=8;j>0;j--)
        {
                DSPORT=0;//先將總線拉低1us
                i++;
                DSPORT=1;//然后釋放總線
                i++;
                i++;//延時(shí)6us等待數(shù)據(jù)穩(wěn)定
                bi=DSPORT;         //讀取數(shù)據(jù),從最低位開始讀取
                /*將byte左移一位,然后與上右移7位后的bi,注意移動(dòng)之后移掉那位補(bǔ)0。*/
                byte=(byte>>1)|(bi<<7);                                                  
//                i=4;                //讀取完之后等待48us再接著讀取下一個(gè)數(shù)
//                while(i--);
        }
    EA = 1;                               
        return byte;
}
/*******************************************************************************
* 函數(shù)名         : Ds18b20ChangTemp
* 函數(shù)功能                   : 讓18b20開始轉(zhuǎn)換溫度
* 輸入           : com
* 輸出                  : 無
*******************************************************************************/

void  Ds18b20ChangTemp()
{
        Ds18b20Init();
        Delay1ms(1);
        Ds18b20WriteByte(0xcc);                //跳過ROM操作命令                 
        Ds18b20WriteByte(0x44);            //溫度轉(zhuǎn)換命令
//        Delay1ms(100);        //等待轉(zhuǎn)換成功,而如果你是一直刷著的話,就不用這個(gè)延時(shí)了

}
/*******************************************************************************
* 函數(shù)名         : Ds18b20ReadTempCom
* 函數(shù)功能                   : 發(fā)送讀取溫度命令
* 輸入           : com
* 輸出                  : 無
*******************************************************************************/

void  Ds18b20ReadTempCom()
{       

        Ds18b20Init();
        Delay1ms(1);
        Ds18b20WriteByte(0xcc);         //跳過ROM操作命令
        Ds18b20WriteByte(0xbe);         //發(fā)送讀取溫度命令
}
/*******************************************************************************
* 函數(shù)名         : Ds18b20ReadTemp
* 函數(shù)功能                   : 讀取溫度
* 輸入           : com
* 輸出                  : 無
*******************************************************************************/

int Ds18b20ReadTemp()
{
        int temp=0;
        unsigned char tmh,tml;
        Ds18b20ChangTemp();                                 //先寫入轉(zhuǎn)換命令
        Ds18b20ReadTempCom();                        //然后等待轉(zhuǎn)換完后發(fā)送讀取溫度命令
        tml=Ds18b20ReadByte();                //讀取溫度值共16位,先讀低字節(jié)
        tmh=Ds18b20ReadByte();                //再讀高字節(jié)
        temp=tmh;
        temp<<=8;
        temp|=tml;
        return temp;
}



溫度讀取頭文件temo.h:
#ifndef __TEMP_H_
#define __TEMP_H_

#include<reg51.h>

sbit DSPORT=P3^7;

void Delay1ms(unsigned int );
unsigned char Ds18b20Init();
void Ds18b20WriteByte(unsigned char com);
unsigned char Ds18b20ReadByte();
void  Ds18b20ChangTemp();
void  Ds18b20ReadTempCom();
int Ds18b20ReadTemp();

#endif




適用電路:






小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表