新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > CEPARK 51單片機DS18B20測試程序

        CEPARK 51單片機DS18B20測試程序

        作者: 時間:2016-11-25 來源:網絡 收藏
        /**********************************************************************
        *文件名稱:CEPARK 51 V2.0開發板
        *程序版本:V1.0
        *技術支持:http://bbs.cepark.com

        *CEPARK
        http://bbs.cepark.com/viewthread.php?tid=34&fromuid=6136

        *Cepark暑期51在線免費培訓用程序---活動報名地址:
        http://bbs.cepark.com/viewthread.php?tid=14228&fromuid=6136
        **********************************************************************/
        #include"STC89C51RC_RD_PLUS.H"

        #define uchar unsigned char
        #define uint unsignedint

        uchar code C51BOX2[3]_at_ 0x43;//仿真器用三字節空間

        uchar code DispTab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
        0x88,0x83,0xc6,0xa1,0x86,0x8e};//段碼0-9,a-f
        uchar DispBuf[4];

        uchar TempH,TempL;
        uint Temp;
        bit Presence;

        sfr LedPort=0x80;//P0口接段碼
        sbit Led0=P1^0;//LED控制腳
        sbit Led1=P1^1;
        sbit Led2=P1^2;
        sbit Led3=P1^3;
        sbit DataPort=P1^6;//18B20的數據口

        void uDelay(uchar DelayTime)//延時子程序,入口參數每加1約加2us
        {while(--DelayTime);

        }

        void Hex2Bcd()//HEX轉BCD程序
        {
        if(Presence==1)
        { //如果沒有檢測到存在則顯示“no”
        DispBuf[0]=0xab;
        DispBuf[1]=0xa3;
        DispBuf[2]=0xff;
        DispBuf[3]=0xff;
        }
        else
        { //分解后查表得到段碼放入顯示緩存
        Temp=TempH*256+TempL;//數據合并成一個雙字節數

        if((Temp>>12)==0xf)//右移12位判斷是否為負溫度
        {Temp=0x10000-Temp;//計算出負溫度值
        DispBuf[0]=0xbf;}//并將最左邊數碼管顯示“-”號
        elseDispBuf[0]=0xff;//否則不顯示

        TempH=Temp>>4;//將小數點4位值移出后,得到整數部分放在TempH中
        Temp=(Temp&0x0f)*625;//相與取出小數點四位,乘法得到小數點值
        DispBuf[3]=DispTab[Temp/1000];//小數點位只取最高一位,后三位不顯示

        DispBuf[2]=DispTab[TempH%10]&0x7f;//個位處理并點亮小數點
        TempH=TempH/10;//取出百位、十位

        if(!TempH)DispBuf[1]=0xff;//百位和十位均為0則十位不顯示。
        elseDispBuf[1]=DispTab[TempH%10];

        if(DispBuf[0]==0xff)//正溫度情況下
        {
        if(TempH/10)DispBuf[0]=DispTab[TempH/10];//百位有數值顯示
        elseDispBuf[0]=0xff;//為0不顯示
        }
        }
        }

        void Display(uchar j)//顯示子程序
        {
        for(;j>0;j--)
        {
        LedPort=DispBuf[0];
        Led0=0;
        uDelay(20);
        Led0=1;
        LedPort=DispBuf[1];
        Led1=0;
        uDelay(20);
        Led1=1;
        LedPort=DispBuf[2];
        Led2=0;
        uDelay(20);
        Led2=1;
        LedPort=DispBuf[3];
        Led3=0;
        uDelay(20);
        Led3=1;
        }
        }

        void Inti()
        {
        DataPort=0;//拉低
        uDelay(180);//延時后拉高
        DataPort=1;
        uDelay(24);//延時后讀狀態,如果存在,由18B20將端口拉低
        Presence=DataPort;//狀態存入,用于后面顯示判斷
        uDelay(230);//延時完成一周期時間
        }

        void WriteByte(uchar val)//字節寫入
        {
        uchar i;
        for(i=8;i>0;i--)
        {
        DataPort=0;
        uDelay(4);
        DataPort=val&0x01;
        uDelay(20);
        DataPort=1;
        val=val/2;
        }
        uDelay(50);
        }


        uchar ReadByte()//字節讀取
        {
        uchar i;
        uchar value=0;
        for(i=0;i<8;i++)//讀入8字節
        {
        DataPort=0;//拉低后再拉高,產生讀間隙
        DataPort=1;
        uDelay(4);//延時后讀入
        if(DataPort)value|=0x01<uDelay(20);//延時完成一周期時間
        }
        return(value);
        }

        void SetStep(uchar Dat)//入口參數,1F-0.5度步進,3F-0.25度,5F-0.125度,7F-0.0625度
        {
        Inti();
        WriteByte(0xcc);
        WriteByte(0x4e);
        WriteByte(0x15);//寫地址2—TH
        WriteByte(0x00);//寫地址3—TL
        WriteByte(Dat);//地址4,保留區,用于小數后分辨率,1F,3F,5F,7F取值,值越大分辨率越高
        Inti();
        WriteByte(0xcc);
        WriteByte(0xbe);
        ReadByte();
        Inti();
        WriteByte(0xcc);
        WriteByte(0x48);//拷貝指令,發出后等6ms等待18B20將數據寫入EEPROM,寫結束再復位。
        uDelay(100);
        Inti();
        DataPort=1;
        }

        void GetTemp()//溫度獲得子程序,返回值在TempH,TempL中
        {
        Inti();Display(8);//每執行一條指令補充顯示,消除閃動
        WriteByte(0xcc);Display(8);
        WriteByte(0x44);Display(8);
        Inti();Display(8);
        WriteByte(0xcc);Display(8);
        WriteByte(0xbe);Display(8);
        TempL=ReadByte();Display(8);
        TempH=ReadByte();Display(8);
        }

        void main(void)
        {
        uDelay(100);
        Presence=1;
        SetStep(0x7f);
        GetTemp();Display(100);//發送第一個取溫度指令后,要延時一段時間等待內部轉換。(解決開機顯示85度的問題。)
        while(1){GetTemp();Hex2Bcd();Display(50);}

        }


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 衡东县| 巴东县| 内黄县| 时尚| 称多县| 利津县| 维西| 桦甸市| 高邮市| 南昌市| 宜城市| 平武县| 巴塘县| 黄龙县| 新宾| 安新县| 乌兰浩特市| 清远市| 耒阳市| 颍上县| 珲春市| 古交市| 页游| 台东县| 临高县| 白城市| 隆子县| 肥东县| 沿河| 徐汇区| 易门县| 巴彦淖尔市| 青龙| 广平县| 理塘县| 浪卡子县| 高阳县| 长子县| 天津市| 集安市| 浑源县|