<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        C51--DS18B20數字溫度計--C語言

        作者:huqin   來源:本站原創   點擊數:  更新時間:2014年04月13日   【字體:



         

        #include<reg52.h>

        #include<intrins.h>

        #define uint unsigned int
        #define uchar unsigned char

        sbit DQ=P2^6;

        sbit lcdrs=P1^0;
        sbit lcdrw=P1^1;
        sbit lcden=P1^2;

        void disp(uint a);
        void init(void);

        void delay(uint i);

        uchar ds18b20_init(void);

        void write_byte(uchar byte);

        uchar read_byte(void);

        uint read_ds18b20(void);

        void delay50us(void);

        void delayms(uint a);

        void lcd1602_wr_com(uchar com);

        void lcd1602_wr_data(uchar dat);

        void lcd_init(void);

        uchar code str[]="temperature"; 

        void main(void)
        {
            init();
            while(1)
            
                disp(read_ds18b20());
                delayms(50);
            }
        }

        void init(void)
        {
            uchar i;
            lcd_init();
            lcd1602_wr_com(0x80+0x02);    //顯示的地址
            for(i=0;i<11;i++)
            {
                lcd1602_wr_data(str[i]);
                delayms(2);
            }
        }

        void disp(uint a)
        {
            uchar bai,ge,shi,dp,symbol;
            uint b;
            b=a&0x8000;
            if(b==0x8000)    //負溫度
            {
                a&=0x7fff;          //將最高位置0
                symbol=0x2d;        //符號為“-”
            }
            else symbol=0x2b;       //符號為“+”
           
            bai=a/1000+0x30;
            shi=a00/100+0x30;
            ge=a0/10+0x30;
            dp=a+0x30;
            if(bai==0x30)
            {
                bai=0x20;     //如果百位為0,不顯示
                if(shi==0x30)shi=0x20;    //如果百位為零,十位也為0,不顯示
            }
            lcd1602_wr_com(0x80+0x43);
            lcd1602_wr_data(symbol);
            delayms(2);
            lcd1602_wr_data(bai);
            delayms(2);
            lcd1602_wr_data(shi);
            delayms(2);
            lcd1602_wr_data(ge);
            delayms(2);
            lcd1602_wr_data(0x2e);
            delayms(2);
            lcd1602_wr_data(dp);
            delayms(2);
            lcd1602_wr_data(0xdf);
            delayms(2);
            lcd1602_wr_data(0x43);
            delayms(2);
        }
         

        void delay(uint i)
        {
            while(i--);   
        }
        uchar ds18b20_init(void)
        {
            uchar n;
            DQ=1;         //初始化時序從高到低,因此先置高
            delay(4);     //延時等待穩定
            DQ=0;         //拉低
            delay(60);    //延時大約500us
            DQ=1;         //主機放開
            delay(6);     //延時15~60us
            n=DQ;         //讀信號線狀態,如為低,則說明線上有設備,否則說明沒有或壞了
            delay(6);
            return n;   
        }
        void write_byte(uchar byte)
        {
            uchar i;
            for(i=0;i<8;i++)
            {
                DQ=0;              //復位信號線
                DQ=byte&0x01;      //低位開始寫入,0繼續拉低信號線,1則被拉高
                delay(5);          //延時大約45us左右,等待設備采樣數據
                byte>>=1;          //右移一位
                DQ=1;
            }
            delay(4);   
        }
        uchar read_byte(void)
        {
            uchar i,temp;
            for(i=0;i<8;i++)
            {
                DQ=0;
                temp>>=1;           //右移一位
                DQ=1;               //主機釋放信號線
                _nop_();
                if(DQ)temp|=0x80;   //將讀出數據放在最高位,如果是0,信號線會設備繼續拉低,1則為高
                delay(4);           
            }
            return temp;            //返回讀出的一字節數據
        }
        uint read_ds18b20(void)
        {
            uchar numh,numl;
            uint value;
            if(ds18b20_init()==0)           //判斷設置是否正常,0為正常
            {
                write_byte(0xcc);   //跳過ROM序列號讀取
                write_byte(0x44);   //啟動溫度轉換
                if(ds18b20_init()==0)       //再次初始化
                {
                    write_byte(0xcc);//跳過ROM序列號讀取
                    write_byte(0xbe);//讀溫度寄存器
                    numl=read_byte();//讀低位數據
                    numh=read_byte();//讀高位數據
                    value=numh;
                    value=value<<8|numl;  //將數據組合成16位數據
                    if(value<0x0fff)      //正溫度
                    {
                        value=value*0.0625*10+0.5;    //最一位小數,并進行4舍5入
                    }
                    else                  //負溫度
                    {
                        value=~value+1;            //內存中數據是以補碼存放的,負數補碼為絕對值按位取反加1
                                                   //而補碼的補碼為原碼,這樣就可以求得負數的絕對值
                        value=value*0.0625*10+0.5; //最一位小數,并進行4舍5入,這是負數的絕對值
                        value=value|0x8000;        //將最高位置1,表示此溫度為負溫度                                                    
                    }
                 
            }
            return value;       
        }

        void delay50us(void)
        {
            uint j;
            j=4;
            while(j--);
        }
        void delayms(uint a)
        {
            uint i,j;
            for(i=a;i>0;i--)
                for(j=122;j>0;j--);
        }
        void lcd1602_wr_com(uchar com)
        {
            lcdrs=0;
            P0=com;
            delayms(2);
            lcden=1;
            delay50us();
            lcden=0;
        }
        void lcd1602_wr_data(uchar dat)
        {
            lcdrs=1;
            P0=dat;
            delayms(2);
            lcden=1;
            delay50us();
            lcden=0;   
        }
        void lcd_init(void)
        {
            lcden=0;
            lcdrw=0;
            lcd1602_wr_com(0x38);    //顯示模式設置
            lcd1602_wr_com(0x0c);    //開顯示,不顯示光標   
            lcd1602_wr_com(0x06);    //寫字符后地址指針加1,整屏顯示不移動
            lcd1602_wr_com(0x01);    //清屏
        }

         

        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮