找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

自己搞的DS18B20顯示程序,可以用,但是在延時方面有點小BUG,望有緣人一起探討

[復制鏈接]
跳轉到指定樓層
樓主
ID:325916 發(fā)表于 2018-5-9 14:47 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
#include <reg51.h>
#include <intrins.h>    //需要調用_nop_();延時函數(shù)

#define uchar unsigned char
#define uint  unsigned int
#define High_Temp  35    //定義空調適宜最高溫度為35度
#define Low_Temp  15     //定義空調適宜最低溫度為15度

/**********************第一部分門廳人員感應****************************/
sbit SPK = P3^4;       //音頻輸出
sbit door_call = P1^5; //紅外感應按鈕
sbit LED = P3^3;       //LED黃燈輸出
uint T_count = 0;      //全局整形變量控制 叮咚 聲響時長。

/**********************第二部分對溫度的檢測與控制****************************/
sbit DQ = P3^0;        //18B20數(shù)據(jù)線引腳
sbit Speaker=P3^1;     //蜂鳴器的定義
sbit KongTiao=P3^2;    //電機的定義
sbit RTGY=P1^4;        //空調人體感應的定義


/**********************第三部分天燃氣檢測   ****************************/
sbit TRQ = P1^6; //天然氣感應按鈕
sbit up=P3^5;        //自動開窗
sbit down=P3^6;        //自動關窗

//初始化程序
void initA ()
{
TMOD=0x00;          //T1方式定時器
TH1=(8192-700)/32;  //700us定時/初值高8位放TH1
TL1=(8192-700)%32;   //初值低5位放TL1
IE=0x88;          //打開T1中斷
}
//T1中斷控制叮咚聲響程序
void Timer1() interrupt 3    //定時器中斷服務函數(shù)
{
SPK=~SPK;
T_count ++;
if(T_count < 400)                 //叮  時長為400*700us
        {
          TH1=(8192-700)/32;  //0.3ms實現(xiàn)  叮  的音
          TL1=(8192-700)%32;   
        }
else if(T_count < 900)                 //咚  時長為400*1000us
        {

          TH1=(8192-900)/32;  //1ms實現(xiàn)  咚  的音
          TL1=(8192-900)%32;   
        }
        else         
        {
         TR1=0;        //關閉本次呼叫呼叫
         T_count=0;    //時長計數(shù)清零
        }
}


/**********************第二部分溫度檢測部分****************************/
uchar bw,sw,gw;       //溫度的百 十  個位。

uchar code DSY_CODE[]=
        {0xc0,0xf9,0xa4,0xb0,0x99,0x92,
        0x82,0xf8,0x80,0x90,0xbf,0xff,0xC6};


void Delay_2US(uint us)   //微秒延時,延時2*50us
{
while(--us);
}   

void Delay_50Us(uint t)   //微秒延時,延時t*50us
{
uchar j;
while(t--)
for(j=19;j>0;j--);
}


//DS18B20復位函數(shù)
void reset()
{
uchar x=0;
DQ=1;          //復位DQ
Delay_2US(8);
DQ=0;          //將DQ拉低
Delay_2US(80);//精確延時 >480us <960us
DQ=1;          //將DQ拉高
Delay_2US(14);  //延時15~60us后,接收脈沖
x=DQ;     //DQ 若為0則初始化成功,否則失敗
Delay_2US(20);
}

//讀取一個字節(jié)的數(shù)據(jù)函數(shù)
uchar Ds18b20_Read(void)

{
uchar i=0;
uchar dat=0;
for(i=8;i>0;i--)
{
DQ=0;
dat>>=1;    //右移一位
DQ=1;
_nop_();
if(DQ)dat=dat|0x80;
Delay_2US(20);
}
return(dat);
}


//寫入一個字節(jié)的數(shù)據(jù)函數(shù)
void Ds18b20_Write(uchar dat)

{
uchar i=0;
for(i=8;i>0;i--)
{
DQ=0;
_nop_();
DQ=dat&0x01;
Delay_2US(20);
DQ=1;
dat>>=1;
}
}

//讀取實際溫度函數(shù)
uchar Ds18b20_Read_Temperature(void)
{
uchar temp1,temp;
int temp2;
reset();
Ds18b20_Write(0xCC);      //跳過ROM
Ds18b20_Write(0x44);      //啟動DS18B20進行溫度轉換
Delay_2US(200);
reset();

Ds18b20_Write(0xCC);      //跳過ROM
Ds18b20_Write(0xBE);      //讀DS18B20內部暫存器命令
Delay_2US(200);
temp1=Ds18b20_Read();     //讀出低字節(jié)
temp2=Ds18b20_Read();     //讀出高字節(jié)
temp=(temp1|(temp2<<8))>>4;
return temp;
}



/*****轉換成十進制溫度并顯示*********/
void Change_Display(uchar i)
{
        uchar temp=i;
        if((temp&0xc0)==0xc0)
        {
        temp=~temp+1;
        bw=10;
        sw=(temp/10==0)?11:temp/10;
        gw=temp%10;
        }
        else
        {
        bw=(temp/100==0)?11:1;
        if(bw!=1)
        sw=(temp/10==0)?11:temp/10;
        else sw=(temp-100)/10;
        gw=temp%10;
        }
        P1=~0x01;   P2=~DSY_CODE[bw]; Delay_2US(900);           //顯示十位
        P1=~0x02;   P2=~DSY_CODE[sw]; Delay_2US(900);           //顯示個位
        P1=~0x04;   P2=(~DSY_CODE[gw]+0x80); Delay_2US(900);    //顯示小數(shù)點后一位
        P1=~0x08;   P2=~DSY_CODE[12]; Delay_2US(900);           //顯示溫度C
       
}
/********************************第一部分控制*********************************/
//紅外感應控制程序
void  D_1bf()
{
        if(door_call==0) //按下按鍵啟動定時器
                {
                TR1=1;  //啟動計數(shù),T1中斷開始工作并發(fā)出叮咚聲       
                while(!door_call);//等鍵釋放
                LED=~LED;
                Delay_50Us(8000);
                LED=1;
                }
}

/********************************第三部分窗戶的開關控制*********************************/
//開窗
void pwm1()
{
uchar i;
for(i=0;i<10;i++)
{
down=0;//確保窗戶不閉合
up=1;
Delay_2US(10);
up=0;
Delay_2US(10);
}
up=0;
}

/****主函數(shù)**********/
void main()
{     
       
        uchar i;
        initA ();           //第一部分初始化         
        while(1)
        {
        i=Ds18b20_Read_Temperature();  //讀取溫度
        Change_Display(i);               //顯示溫度
       
        //對串口的初始化定義         
        KongTiao=1;
        RTGY=1;
        TRQ=1;
        LED=1;
        Speaker=1;

        //判斷是否有人進門
        if(!door_call)    D_1bf();            //第一部分判斷程序調用  
        //判斷天然氣是否泄漏
        if(!TRQ)
        {
        Speaker=0;    //蜂鳴器報警
        pwm1();
        }

       
        //判斷當前溫度是否超值,是否需要啟動空調
        if(RTGY==0 & i!=0)
        {
                if(i>High_Temp||i<Low_Temp)     //蜂鳴器報警判斷電路
                {
                Speaker=0;                      //蜂鳴器報警
                KongTiao=0;
                }
        }               
  }
}



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

使用道具 舉報

沙發(fā)
ID:325916 發(fā)表于 2018-5-9 14:50 | 只看該作者
我的QQ1348216252可以一起探討
回復

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復 返回頂部 返回列表