新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > DS18B20匹配ROM地址單總線多點測溫(STC89C52)

        DS18B20匹配ROM地址單總線多點測溫(STC89C52)

        作者: 時間:2016-11-26 來源:網(wǎng)絡 收藏
        DS18B20總線多點測溫,程序通過匹配64位ROM地址的方法,實現(xiàn)單總線兩點測溫并1602顯示。該程序要先知道DS18B20的64位ROM地址才可以,ROM地址的讀取方法可參考上一篇的介紹。

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

        程序代碼:

        #include

        #defineucharunsignedchar

        #defineuintunsignedint

        sbitlcdrw=P1^1;//LCD1602讀/寫選擇H/L

        sbitlcdrs=P1^0;//LCD1602數(shù)據(jù)/命令選擇H/L

        sbitlcden=P2^5;//LCD1602使能

        sbitds=P2^2;//溫度傳感器信號線

        ucharcodetable[]="";

        ucharcodetable1[]="LOADINGWENDU";

        //uchardatafCode[8];

        ucharcoderom1[]={0x28,0x3b,0x08,0x32,0x04,0x00,0x00,0xe4};//ds18b20ROM地址

        ucharcoderom2[]={0x28,0xf8,0x19,0x0d,0x03,0x00,0x00,0x3b};//ds18b20rom地址

        inttemp;//整型溫度數(shù)據(jù)

        floatf_temp;//浮點型溫度數(shù)據(jù)

        uchartflag;//溫度正負標志

        //*****************LCD1602*******************************

        voiddelay(uintz)//延時函數(shù)延時z毫秒

        {

        uintx,y;

        for(x=z;x>0;x--)

        for(y=110;y>0;y--);

        }

        voidwrite_com(ucharcom)//lcd1602寫指令

        {

        lcdrs=0;

        P0=com;

        delay(5);

        lcden=1;

        delay(5);

        lcden=0;

        }//lcd1602寫數(shù)據(jù)

        voidwrite_date(uchardate)

        {

        lcdrs=1;

        P0=date;

        delay(5);

        lcden=1;

        delay(5);

        lcden=0;

        }

        voidinit1602()//開機初始化LCD1602

        {

        uchari;

        lcdrw=0;

        lcden=0;

        write_com(0x38);

        write_com(0x0c);

        write_com(0x06);

        write_com(0x01);

        write_com(0x80);

        for(i=0;i<16;i++)

        {

        write_date(table1[i]);

        delay(5);

        }

        write_com(0x80+0x41);

        for(i=0;i<14;i++)

        {

        write_date(0x2d);

        delay(100);

        }

        write_com(0x80);

        for(i=0;i<16;i++)

        {

        write_date(table[i]);

        delay(5);

        }

        write_com(0x80+0x40);

        for(i=0;i<16;i++)

        {

        write_date(table[i]);

        delay(5);

        }

        }

        //*******************DS18B20****************************

        voiddsreset()//DS18B20復位,初始化函數(shù)

        {

        uinti;

        ds=0;

        i=103;

        while(i>0)

        i--;

        ds=1;

        i=4;

        while(i>0)

        i--;

        }

        bittempreadbit()//讀一位數(shù)據(jù)函數(shù)

        {

        uinti;

        bitdat;

        ds=0;

        i++;

        ds=1;

        i++;

        i++;

        dat=ds;

        i=8;

        while(i>0)

        i--;

        returndat;

        }

        uchartempread()//讀一字節(jié)數(shù)據(jù)函數(shù)

        {

        uchari,j,dat;

        dat=0;

        for(i=1;i<=8;i++)

        {

        j=tempreadbit();

        dat=(j<<7)|(dat>>1);

        }

        returndat;

        }

        voidtempwrite(uchardat)//向DS18B20寫一字節(jié)數(shù)據(jù)函數(shù)

        {

        uinti;

        ucharj;

        bittestb;

        for(j=1;j<=8;j++)

        {

        testb=dat&0x01;

        dat=dat>>1;

        if(testb)//寫1

        {

        ds=0;

        i++;i++;

        ds=1;

        i=8;

        while(i>0)

        i--;

        }

        else//寫0

        {

        ds=0;

        i=8;

        while(i>0)

        i--;

        ds=1;

        i++;i++;

        }

        }

        }

        voidmatchrom(uchara)//匹配ROM

        {

        charj;

        tempwrite(0x55);//發(fā)送匹配ROM命令

        if(a==1)

        {

        for(j=0;j<8;j++)

        tempwrite(rom1[j]);//發(fā)送18B20的序列號,先發(fā)送低字節(jié)

        }

        if(a==2)

        {

        for(j=0;j<8;j++)

        tempwrite(rom2[j]);//發(fā)送18B20的序列號,先發(fā)送低字節(jié)

        }

        }

        uinttempchange(ucharz)//DS18B20開始獲取溫度并轉(zhuǎn)換

        {

        uchara,b;

        dsreset();

        delay(1);

        //tempwrite(0xcc);//寫跳過讀ROM指令

        //tempwrite(0xcc);

        //dsreset();

        if(z==1)

        matchrom(1);//匹配rom1

        if(z==2)

        matchrom(2);//匹配rom2

        tempwrite(0x44);//寫溫度轉(zhuǎn)換指令

        delay(5);

        dsreset();

        delay(1);

        //tempwrite(0xcc);//寫“跳過讀ROM”指令

        //tempwrite(0xcc);

        //dsreset();

        if(z==1)

        matchrom(1);//匹配rom1

        if(z==2)

        matchrom(2);//匹配rom2

        tempwrite(0xbe);//寫“讀內(nèi)部RAM中9字節(jié)的溫度數(shù)據(jù)”指令

        a=tempread();//讀高8位

        b=tempread();//讀低8位

        temp=b;

        temp<<=8;

        temp=temp|a;//兩個字節(jié)合為一個字節(jié)

        if(temp<0x0fff)

        tflag=0;//正值標識符

        else

        {

        temp=~temp+1;

        tflag=1;//負值標識符

        }

        f_temp=temp*0.0625;//溫度在寄存器中為12位,分辨路為0.0625

        temp=f_temp*10+0.5;//乘以10表示小數(shù)點后面只取一位,加0.5是四舍五入

        f_temp=f_temp+0.05;

        returntemp;//temp是整型

        }

        voidwrite_wendu(ucharaddress,uchardate)//寫溫度1602顯示

        {

        write_com(address);

        write_date(date);

        }

        voidinit_1602wendu()

        {

        write_wendu(0x80,N);

        write_wendu(0x81,O);

        write_wendu(0x82,.);

        write_wendu(0x84,:);

        write_wendu(0x89,.);

        write_wendu(0x8b,0xdf);

        write_wendu(0x8c,C);

        write_wendu(0x80+0x40,N);

        write_wendu(0x81+0x40,O);

        write_wendu(0x82+0x40,.);

        write_wendu(0x84+0x40,:);

        write_wendu(0x89+0x40,.);

        write_wendu(0x8b+0x40,0xdf);

        write_wendu(0x8c+0x40,C);

        }

        voiddisplay_wendu(ucharz)//顯示函數(shù)

        {

        uintw1,w2,w3,w4,addr;

        w1=temp/1000;//百位

        w2=temp00/100;//十位

        w3=temp0/10;//個位

        w4=temp;//小數(shù)點位

        if(z==1)

        {

        addr=0;

        write_com(0x80+3);

        write_date(0x30+1);

        }

        if(z==2)

        {

        addr=0x40;

        write_com(0x80+0x40+3);

        write_date(0x30+2);

        }

        if(tflag==0)

        write_wendu(0x80+addr+5,0x20);//不顯示正號

        else

        write_wendu(0x80+addr+5,0x2d);//顯示負號

        if(w1==0)

        {

        write_wendu(0x80+addr+6,0x20);//百位為0,不顯示

        if((w1==0)&&(w2==0))

        write_wendu(0x80+addr+7,0x20);//百位,十位都為0,不顯示

        else

        write_wendu(0x80+addr+7,0x30+w2);

        write_wendu(0x80+addr+8,0x30+w3);

        write_wendu(0x80+addr+10,0x30+w4);

        }

        else

        {

        write_wendu(0x80+addr+6,0x30+w1);

        write_wendu(0x80+addr+7,0x30+w2);

        write_wendu(0x80+addr+8,0x30+w3);

        write_wendu(0x80+addr+10,0x30+w4);

        }

        }

        //************************************************

        voidmain()//主函數(shù)

        {

        init1602();//啟動屏幕初始化

        while(1)

        {

        init_1602wendu();//顯示溫度屏幕初始化

        tempchange(1);//獲取溫度并轉(zhuǎn)化

        display_wendu(1);//顯示溫度

        tempchange(2);

        display_wendu(2);

        }

        }



        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 沅江市| 岳普湖县| 电白县| 遵义县| 胶南市| 临漳县| 昌乐县| 呼图壁县| 肇东市| 延寿县| 永修县| 沐川县| 三穗县| 安乡县| 揭东县| 博爱县| 望城县| 商丘市| 门头沟区| 札达县| 汉川市| 隆化县| 大同县| 沐川县| 扎鲁特旗| 贵南县| 淮南市| 高台县| 金寨县| 大荔县| 彰武县| 梧州市| 淮安市| 安陆市| 渭南市| 文安县| 龙南县| 社旗县| 德州市| 陇南市| 汽车|