溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

51單片機(jī)課程設(shè)計(jì):基于DS18B20的溫度報(bào)警器

發(fā)布時(shí)間:2020-07-04 09:14:55 來(lái)源:網(wǎng)絡(luò) 閱讀:3313 作者:世界都一樣 欄目:開(kāi)發(fā)技術(shù)

51單片機(jī)課程設(shè)計(jì):基于DS18B20的溫度報(bào)警器

    本程序用于讀取DS18B20溫度,同時(shí)具備報(bào)警功能,工程分為3個(gè)文件,main.c、temp.c、temp.h,經(jīng)本人修改部分代碼,適用于吉林農(nóng)業(yè)大學(xué)51開(kāi)發(fā)板,其他朋友亦可移植到其他型號(hào)開(kāi)發(fā)板。工程文件及對(duì)應(yīng)開(kāi)發(fā)板的電路圖在文章最下方。

    關(guān)于粘貼復(fù)制亂碼的問(wèn)題:如果程序復(fù)制到Keil編譯器上出現(xiàn)注釋亂碼,可以先建一個(gè).c文件,也就是說(shuō)不在keil里面編輯,然后用記事本打開(kāi).c文件,將源碼復(fù)制進(jìn)去,再在keil中添加文件即可,其他操作方法一樣。

1.main.c文件

/*********************************說(shuō)明******************************************
本程序用于讀取溫度檢測(cè)模塊DS18B20數(shù)值,并顯示到數(shù)碼管上
本程序分為兩部分,一部分為主函數(shù)部分,文件名為main.c
另一部分為溫度讀取部分,文件名為temp.c
數(shù)碼管以及蜂鳴器連接方法參照以下定義,DS18B20連接見(jiàn)temp.h(引腳P3.7)
在程序剛開(kāi)始,會(huì)要求設(shè)置預(yù)警值,通過(guò)按鍵可以實(shí)現(xiàn)數(shù)值的加減,設(shè)置完成后按確認(rèn)鍵。
然后開(kāi)始監(jiān)測(cè)數(shù)值是否超過(guò)預(yù)警值,超過(guò)則報(bào)警。
                                          (本程序經(jīng)修改適用于吉農(nóng)51單片機(jī)開(kāi)發(fā)板)
                                        2016-12-29------------------------SWorld
*******************************************************************************/
#include<reg51.h>
#include"temp.h"
//--定義使用的IO--//
#define GPIO_DIG P0//位選以及段選數(shù)據(jù)輸出端口定義
#define GPIO_KEY P1  //按鍵引腳 p1.0:ADD數(shù)值增加 p1.1:SUB數(shù)值減少   p1.2:OK 確定
sbit DUC=P2^2;        //DUC段選信號(hào)
sbit WEC=P2^3;        //WEC位選信號(hào)
sbit BELL=P2^4;//  蜂鳴器連接  超出預(yù)警范圍蜂鳴器響
//sbit LIGHT=P1^4;//定義LED燈閃爍引腳
char HIGH=30,LOW=20;//定義預(yù)警范圍最大以及最低值  超出此數(shù)值將會(huì)報(bào)警
unsigned int ifset=0;//判斷是否設(shè)置好最高以及最低溫度
//--定義全局變量
unsigned char code DIG_CODE[19]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x38,0x76};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、L、H的顯示碼   L代表最低溫度  H代表最高溫度
unsigned char DisplayData[8];
//用來(lái)存放要顯示的8位數(shù)的值
//--聲明全局函數(shù)--//
void LcdDisplay(int temp);
void DigDisplay();
void Delay10ms(unsigned int c);
unsigned char Key_Scan();
/*******************************************************************************
* 函 數(shù) 名         : main
* 函數(shù)功能         : 主函數(shù)
* 輸    入         : 無(wú)
* 輸    出         : 無(wú)
*******************************************************************************/
void main()
{
    DUC=0;WEC=0;BELL=1;      //初始化
    while(1)
    {
        switch(ifset)
        {
            case 0://設(shè)置最高溫度
                DisplayData[7] = DIG_CODE[17];//顯示H
                if(HIGH>0)
                {DisplayData[5]=0x00;}
                else
                {DisplayData[5]=0x40;}
                switch(Key_Scan())//掃描鍵值
                {
                    case 1://數(shù)值增加
                        if(HIGH>LOW)
                        HIGH-=1;
                    break;
                    case 2://數(shù)值減少
                        HIGH+=1;
                    break;
                    case 4://確定
                        ifset=1;
                    break;
                }
                //顯示最大溫度
                DisplayData[4] = DIG_CODE[HIGH / 100];
                DisplayData[3] = DIG_CODE[HIGH % 100 / 10];
                DisplayData[2] = DIG_CODE[HIGH % 10];
            break;
            case 1://設(shè)置最低溫度
                DisplayData[7] = DIG_CODE[16];
                if(LOW>0)
                {DisplayData[5]=0x00;}
                else
                {DisplayData[5]=0x40;}
                switch(Key_Scan())
                {
                    case 1:
                        LOW-=1;
                    break;
                    case 2:
                        if(LOW<HIGH)
                            LOW+=1;
                    break;
                    case 4:
                        ifset=2;
                    break;
                }
                //顯示最低溫度
                DisplayData[4] = DIG_CODE[LOW / 100];
                DisplayData[3] = DIG_CODE[LOW % 100 / 10];
                DisplayData[2] = DIG_CODE[LOW % 10];
            break;
            case 2://設(shè)置完成 開(kāi)始監(jiān)控
                DisplayData[7]=0x00;
                LcdDisplay(Ds18b20ReadTemp());
            break;
        }
        if(ifset!=2)
        DigDisplay();
    }
}
/*******************************************************************************
* 函 數(shù) 名         : LcdDisplay()
* 函數(shù)功能   : LCD顯示讀取到的溫度
* 輸    入         : v
* 輸    出         : 無(wú)
*******************************************************************************/
void LcdDisplay(int temp)  //lcd顯示
{
    float tp;  
    if(temp< 0)//當(dāng)溫度值為負(fù)數(shù)
    {
        DisplayData[6] = 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
   {
        DisplayData[6] = 0x00;
        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)后面。
        if(temp*100<LOW||temp>HIGH*100)//以下是判斷是否超出預(yù)警范圍
        {
            BELL=0;
        }
        else
        {
            BELL=1;
        }
    }
    DisplayData[5] = DIG_CODE[temp / 10000];
    DisplayData[4] = DIG_CODE[temp % 10000 / 1000];
    DisplayData[3] = DIG_CODE[temp % 1000 / 100] | 0x80;
    DisplayData[2] = DIG_CODE[temp % 100 / 10];
    DisplayData[1] = DIG_CODE[temp % 10];
    DigDisplay();   //掃描顯示
}
/*******************************************************************************
* 函 數(shù) 名         : DigDisplay
* 函數(shù)功能   : 使用數(shù)碼管顯示
* 輸    入         : 無(wú)
* 輸    出         : 無(wú)
*******************************************************************************/
void DigDisplay()
{
    unsigned char i;
    unsigned int j;
    for(i=0;i<8;i++)
    {
        WEC=1;DUC=0;
        switch(i) //位選,選擇點(diǎn)亮的數(shù)碼管,
        {
            case(0):
                GPIO_DIG=0x7F; break;//顯示第0位
            case(1):
                GPIO_DIG=0xBF; break;//顯示第1位
            case(2):
                GPIO_DIG=0xDF; break;//顯示第2位
            case(3):
                GPIO_DIG=0xEF; break;//顯示第3位
            case(4):
                GPIO_DIG=0xF7; break;//顯示第4位
            case(5):
                GPIO_DIG=0xFB; break;//顯示第5位
            case(6):
                GPIO_DIG=0xFD; break;//顯示第6位
            case(7):
                GPIO_DIG=0xFE; break;//顯示第7位
        }
        WEC=0;DUC=1;
        GPIO_DIG=DisplayData[i];//發(fā)送段碼
        j=50; //掃描間隔時(shí)間設(shè)定
        while(j--);
            GPIO_DIG=0x00;//消隱
    }
}
/*******************************************************************************
* 函 數(shù) 名         : Key_Scan()
* 函數(shù)功能   : 掃描鍵盤(pán)
* 輸    入         : 無(wú)
* 輸    出         : 讀取到的鍵值
*******************************************************************************/
unsigned char Key_Scan()
{
    unsigned char keyValue = 0 , i; //保存鍵值
    //--檢測(cè)按鍵1--//
    if (GPIO_KEY != 0xFF)//檢測(cè)按鍵K1是否按下
    {
        Delay10ms(1);//消除抖動(dòng)
        if (GPIO_KEY != 0xFF)//再次檢測(cè)按鍵是否按下
        {
            keyValue = ~GPIO_KEY;
            i = 0;
            while ((i<50) && (GPIO_KEY != 0xFF)) //檢測(cè)按鍵是否松開(kāi)
            {
                Delay10ms(1);
                i++;
            }
        }
    }
    return keyValue;   //將讀取到鍵值的值返回
}
/*******************************************************************************
* 函 數(shù) 名         : Delay10ms
* 函數(shù)功能   : 延時(shí)函數(shù),延時(shí)10ms
* 輸    入         : 無(wú)
* 輸    出         : 無(wú)
*******************************************************************************/
void Delay10ms(unsigned int c)   //誤差 0us
{
    unsigned char a, b;
    //--c已經(jīng)在傳遞過(guò)來(lái)的時(shí)候已經(jīng)賦值了,所以在for語(yǔ)句第一句就不用賦值了--//
    for (;c>0;c--)
    {
        for (b=38;b>0;b--)
        {
            for (a=130;a>0;a--);
        }         
    }       
}


2.temp.c文件

/*-----------------------------------------------------------------------------*/
/*----------------------------DS18B20操作函數(shù)----------------------------------*/
/*-----------------------------------------------------------------------------*/
#include"temp.h"
/*******************************************************************************
* 函 數(shù) 名         : Delay1ms
* 函數(shù)功能   : 延時(shí)函數(shù)
* 輸    入         : 無(wú)
* 輸    出         : 無(wú)
*******************************************************************************/
void Delay1ms(uint y)
{
    uint x;
    for( ; y>0; y--)
    {
        for(x=110; x>0; x--);
    }
}
/*******************************************************************************
* 函 數(shù) 名         : Ds18b20Init
* 函數(shù)功能   : 初始化
* 輸    入         : 無(wú)
* 輸    出         : 初始化成功返回1,失敗返回0
*******************************************************************************/
uchar Ds18b20Init()
{
    uchar i;
    DSPORT = 0; //將總線拉低480us~960us
    i = 70;
    while(i--);//延時(shí)642us
        DSPORT = 1;//然后拉高總線,如果DS18B20做出反應(yīng)會(huì)將在15us~60us后總線拉低
    i = 0;
    while(DSPORT)//等待DS18B20拉低總線
    {
        Delay1ms(1);
        i++;
        if(i>5)//等待>5MS
        {
            return 0;//初始化失敗
        }
    }
    return 1;//初始化成功
}
/*******************************************************************************
* 函 數(shù) 名         : Ds18b20WriteByte
* 函數(shù)功能   : 向18B20寫(xiě)入一個(gè)字節(jié)
* 輸    入         : com
* 輸    出         : 無(wú)
*******************************************************************************/
void Ds18b20WriteByte(uchar dat)
{
    uint i, j;
    for(j=0; j<8; j++)
    {
        DSPORT = 0;       //每寫(xiě)入一位數(shù)據(jù)之前先把總線拉低1us
        i++;
        DSPORT = dat & 0x01;  //然后寫(xiě)入一個(gè)數(shù)據(jù),從最低位開(kāi)始
        i=6;
        while(i--); //延時(shí)68us,持續(xù)時(shí)間最少60us
            DSPORT = 1;//然后釋放總線,至少1us給總線恢復(fù)時(shí)間才能接著寫(xiě)入第二個(gè)數(shù)值
        dat >>= 1;
    }
}
/*******************************************************************************
* 函 數(shù) 名         : Ds18b20ReadByte
* 函數(shù)功能   : 讀取一個(gè)字節(jié)
* 輸    入         : com
* 輸    出         : 無(wú)
*******************************************************************************/
uchar Ds18b20ReadByte()
{
    uchar byte, bi;
    uint i, j;
    for(j=8; j>0; j--)
    {
        DSPORT = 0;//先將總線拉低1us
        i++;
        DSPORT = 1;//然后釋放總線
        i++;
        i++;//延時(shí)6us等待數(shù)據(jù)穩(wěn)定
        bi = DSPORT; //讀取數(shù)據(jù),從最低位開(kāi)始讀取
        /*將byte左移一位,然后與上右移7位后的bi,注意移動(dòng)之后移掉那位補(bǔ)0。*/
        byte = (byte >> 1) | (bi << 7);  
        i = 4;//讀取完之后等待48us再接著讀取下一個(gè)數(shù)
        while(i--);
    }
    return byte;
}
/*******************************************************************************
* 函 數(shù) 名         : Ds18b20ChangTemp
* 函數(shù)功能   : 讓18b20開(kāi)始轉(zhuǎn)換溫度
* 輸    入         : com
* 輸    出         : 無(wú)
*******************************************************************************/
void  Ds18b20ChangTemp()
{
    Ds18b20Init();
    Delay1ms(1);
    Ds18b20WriteByte(0xcc);//跳過(guò)ROM操作命令 
    Ds18b20WriteByte(0x44);    //溫度轉(zhuǎn)換命令
    //Delay1ms(100);//等待轉(zhuǎn)換成功,而如果你是一直刷著的話,就不用這個(gè)延時(shí)了
}
/*******************************************************************************
* 函 數(shù) 名         : Ds18b20ReadTempCom
* 函數(shù)功能   : 發(fā)送讀取溫度命令
* 輸    入         : com
* 輸    出         : 無(wú)
*******************************************************************************/
void  Ds18b20ReadTempCom()
{
    Ds18b20Init();
    Delay1ms(1);
    Ds18b20WriteByte(0xcc); //跳過(guò)ROM操作命令
    Ds18b20WriteByte(0xbe); //發(fā)送讀取溫度命令
}
/*******************************************************************************
* 函 數(shù) 名         : Ds18b20ReadTemp
* 函數(shù)功能   : 讀取溫度
* 輸    入         : com
* 輸    出         : 無(wú)
*******************************************************************************/
int Ds18b20ReadTemp()
{
    int temp = 0;
    uchar tmh, tml;
    Ds18b20ChangTemp(); //先寫(xiě)入轉(zhuǎn)換命令
    Ds18b20ReadTempCom();//然后等待轉(zhuǎn)換完后發(fā)送讀取溫度命令
    tml = Ds18b20ReadByte();//讀取溫度值共16位,先讀低字節(jié)
    tmh = Ds18b20ReadByte();//再讀高字節(jié)
    temp = tmh;
    temp <<= 8;
    temp |= tml;
    return temp;
}


3.temp.h文件

#ifndef __TEMP_H_
#define __TEMP_H_
#include<reg51.h>
//---重定義關(guān)鍵詞---//
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint 
#define uint unsigned int
#endif
//--定義使用的IO口--//
sbit DSPORT=P3^7;
//--聲明全局函數(shù)--//
void Delay1ms(uint );
uchar Ds18b20Init();
void Ds18b20WriteByte(uchar com);
uchar Ds18b20ReadByte();
void  Ds18b20ChangTemp();
void  Ds18b20ReadTempCom();
int Ds18b20ReadTemp();
#endif


附件:http://down.51cto.com/data/2368528
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI