新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 單片機(jī)中使用DS18B20溫度傳感器C語言程序(參考6)

        單片機(jī)中使用DS18B20溫度傳感器C語言程序(參考6)

        作者: 時(shí)間:2016-11-18 來源:網(wǎng)絡(luò) 收藏
        /******************************************/

        //
        // DS18B20溫度計(jì)C程序
        // 2007.06.08
        /******************************************/
        //使用AT89C2051單片機(jī),12MHZ晶振,用共陽LED數(shù)碼管
        //P1口輸出段碼,P3口掃描,P3.4接DS18B20

        本文引用地址:http://www.104case.com/article/201611/315672.htm

        #include "reg51.h"
        #include "intrins.h" //_nop_();延時(shí)函數(shù)用
        #define Disdata P0 //段碼輸出口
        #define discan P2 //掃描口
        #define uchar unsigned char
        #define uint unsigned int
        sbit DQ=P2^2; //溫度輸入口
        sbit DIN=P0^7; //LED小數(shù)點(diǎn)控制
        uint h;
        //
        //
        //**************溫度小數(shù)部分用查表法***********//
        uchar code ditab[16]=
        {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
        //
        uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
        //共陽LED段碼表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"
        uchar code scan_con[4]={0xfe,0xfd,0xfb,0xf7}; //列掃描控制字
        uchar data temp_data[2]={0x00,0x00}; //讀出溫度暫放
        uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //顯示單元數(shù)據(jù),共4個(gè)數(shù)據(jù)和一個(gè)運(yùn)算暫用

        //
        //
        //
        /*****************11us延時(shí)函數(shù)*************************/
        //
        void delay(uint t)
        {
        for (;t>0;t--);
        }
        //
        /****************顯示掃描函數(shù)***************************/
        scan()
        {
        char k;
        for(k=0;k<4;k++) //4位LED掃描控制
        {
        Disdata=dis_7[display[k]]; //數(shù)據(jù)顯示
        if (k==1){DIN=0;} //小數(shù)點(diǎn)顯示
        discan=scan_con[k]; //位選
        delay(90); //延時(shí)
        discan=0xff;
        }
        }
        //
        //
        /****************DS18B20復(fù)位函數(shù)************************/
        ow_reset(void)
        {
        char presence=1;
        while(presence)
        {
        while(presence)
        {
        DQ=1;_nop_();_nop_();//從高拉倒低
        DQ=0;
        delay(50); //550 us
        DQ=1;
        delay(6); //66 us
        presence=DQ; //presence=0 復(fù)位成功,繼續(xù)下一步
        }
        delay(45); //延時(shí)500 us
        presence=~DQ;
        }
        DQ=1; //拉高電平
        }
        //
        //
        /****************DS18B20寫命令函數(shù)************************/
        //向1-WIRE 總線上寫1個(gè)字節(jié)
        void write_byte(uchar val)
        {
        uchar i;
        for(i=8;i>0;i--)
        {
        DQ=1;_nop_();_nop_(); //從高拉倒低
        DQ=0;_nop_();_nop_();_nop_();_nop_(); //5 us
        DQ=val&0x01; //最低位移出
        delay(6); //66 us
        val=val/2; //右移1位
        }
        DQ=1;
        delay(1);
        }
        //
        /****************DS18B20讀1字節(jié)函數(shù)************************/
        //從總線上取1個(gè)字節(jié)
        uchar read_byte(void)
        {
        uchar i;
        uchar value=0;
        for(i=8;i>0;i--)
        {
        DQ=1;_nop_();_nop_();
        value>>=1;
        DQ=0;_nop_();_nop_();_nop_();_nop_(); //4 us
        DQ=1;_nop_();_nop_();_nop_();_nop_(); //4 us
        if(DQ)value|=0x80;
        delay(6); //66 us
        }
        DQ=1;
        return(value);
        }
        //
        /****************讀出溫度函數(shù)************************/
        //
        read_temp()
        {
        ow_reset(); //總線復(fù)位
        write_byte(0xcc); //發(fā)命令
        write_byte(0xbe); //發(fā)讀命令
        temp_data[0]=read_byte(); //溫度低8位
        temp_data[1]=read_byte(); //溫度高8位
        ow_reset();
        write_byte(0xcc); //Skip ROM
        write_byte(0x44); //發(fā)轉(zhuǎn)換命令
        }
        //
        /****************溫度數(shù)據(jù)處理函數(shù)************************/

        //二進(jìn)制高字節(jié)的低半字節(jié)和低字節(jié)的高半字節(jié)組成一字節(jié),這個(gè)
        //字節(jié)的二進(jìn)制轉(zhuǎn)換為十進(jìn)制后,就是溫度值的百、十、個(gè)位值,而剩
        //下的低字節(jié)的低半字節(jié)轉(zhuǎn)化成十進(jìn)制后,就是溫度值的小數(shù)部分

        /********************************************************/
        work_temp()
        {
        uchar n=0;
        if(temp_data[1]>127) //正、負(fù)數(shù)判斷
        {
        temp_data[1]=(256-temp_data[1]);temp_data[0]=(256-temp_data[0]);n=1; //負(fù)溫度求補(bǔ)碼
        }
        display[4]=temp_data[0]&0x0f; //取低字節(jié)的低4位--小數(shù)部分
        display[0]=ditab[display[4]]; //存放小數(shù)部分
        display[4]=((temp_data[0]&0xf0>>4)|((temp_data[1]&0x0f)<<4));//取整數(shù)部分
        display[3]=display[4]/100; //取百位數(shù)
        display[1]=display[4]%100; //
        display[2]=display[1]/10; //取十位數(shù)
        display[1]=display[1]%10; //取個(gè)位數(shù)
        /******************符號(hào)位顯示判斷**************************/
        if(!display[3])
        {
        display[3]=0x0a; //最高位為0時(shí)不顯示
        if(!display[2])
        {
        display[2]=0x0a; //次高位為0時(shí)不顯示
        }
        }
        if(n){display[3]=0x0b;} //負(fù)溫度時(shí)最高位顯示"-"
        }
        //
        //
        /****************主函數(shù)************************/
        main()
        {
        Disdata=0xff; //初始化端口
        discan=0xff;
        for(h=0;h<4;h++) //開機(jī)顯示"8888"
        {display[h]=8;}
        ow_reset(); //開機(jī)先轉(zhuǎn)換一次
        write_byte(0xcc); //Skip ROM
        write_byte(0x44); //發(fā)轉(zhuǎn)換命令

        for(h=0;h<500;h++) //開機(jī)顯示"8888"
        {scan();}
        while(1)
        {
        read_temp(); //讀出DS18B20溫度數(shù)據(jù)
        work_temp(); //處理溫度數(shù)據(jù)
        for(h=0;h<500;h++) //顯示溫度值2s
        {scan();}
        }
        }



        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 嵩明县| 右玉县| 扬中市| 哈巴河县| 水城县| 顺昌县| 克拉玛依市| 宁河县| 海南省| 大安市| 商河县| 仁寿县| 麻栗坡县| 涞源县| 灵丘县| 寿阳县| 天津市| 密山市| 饶河县| 商都县| 柯坪县| 邻水| 霞浦县| 班玛县| 招远市| 阳信县| 高阳县| 驻马店市| 汪清县| 阳朔县| 光泽县| 贵阳市| 乌拉特前旗| 乌恰县| 鹤岗市| 宿迁市| 东乡县| 泉州市| 宜城市| 枣阳市| 成武县|