新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > DS18B20+LCD1602數字溫度傳感器

        DS18B20+LCD1602數字溫度傳感器

        作者: 時間:2016-11-10 來源:網絡 收藏
        /*STC89C52+LCD1602+DS18B20溫度顯示

        顯示4位小數
        僅支持正溫度
        DJNZ指令為兩周期指令*/

        RS BIT P2.4
        RW BIT P2.5
        E BIT P2.6

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

        DQ BIT P1.7

        COM DATA 30H
        DAT DATA 31H
        BAI DATA 32H
        SHI DATA 33H
        GEX DATA 34H
        TH DATA 35H
        TL DATA 36H
        XI DATA 37H

        ORG 0000H
        SJMP MAIN
        ORG 0030H
        MAIN:MOV SP,#40H
        LCALL INIT_LCD
        N1:LCALL TEMP_18B20//測溫
        LCALL LCD18B20//合并整數 ,拆分小數
        LCALL BCD//數據拆解,將16進制轉為BCD碼
        LCALL DISP_LCD//溫度顯示
        LJMP N1

        TEMP_18B20:LCALL INIT_18B20
        MOV COM,#0CCH
        LCALL WRITE_18B20
        MOV COM,#44H
        LCALL WRITE_18B20
        LCALL DELAY200MS
        LCALL INIT_18B20
        MOV COM,#0CCH
        LCALL WRITE_18B20
        MOV COM,#0BEH
        LCALL WRITE_18B20
        LCALL READ_18B20
        MOV TL,DAT
        LCALL READ_18B20
        MOV TH,DAT
        RET

        INIT_18B20:SETB DQ
        NOP
        CLR DQ
        LCALL DELAY600US//延時600US
        SETB DQ
        MOV R0,#20
        N2:NOP
        DJNZ R0,N2//延時60US
        JB DQ,$
        LCALL DELAY600US//等待18B20響應完畢
        SETB DQ
        RET

        WRITE_18B20:MOV A,COM
        MOV R2,#8
        WR1:SETB DQ
        NOP
        CLR DQ
        NOP
        RRC A
        MOV DQ,C
        MOV R3,#30
        DJNZ R3,$
        DJNZ R2,WR1
        SETB DQ//寫完一個數據必須將DQ拉到,因為
        RET //若最后一位C為低電平超過600US則DS18B20被復位

        READ_18B20:MOV R2,#8
        RE01:SETB DQ
        NOP
        CLR DQ
        NOP
        SETB DQ
        MOV R3,#5
        DJNZ R3,$
        MOV C,DQ
        MOV R3,#23
        DJNZ R3,$
        RRC A
        DJNZ R2,RE01
        MOV DAT,A
        RET

        LCD18B20:MOV R0,#04
        MOV A,TH
        N8:RL A
        DJNZ R0,N8
        MOV TH,A
        MOV A,TL
        SWAP A
        ANL A,#0FH
        ORL A,TH
        MOV TH,A//整數部分
        MOV A,#0FH
        ANL A,TL
        MOV TL,A//小婁部分
        RET

        BCD: MOV A,TH
        MOV B,#100
        DIV AB
        MOV BAI,A
        MOV A,B
        MOV B,#10
        DIV AB
        MOV SHI,A
        MOV GEX,B
        MOV A,TL
        MOV R0,#4
        MOV R1,#XI//四位小數由高到低分別在XI開始的單元中存儲
        M1:MOV B,#10
        MUL AB
        MOV B,#16
        DIV AB
        MOV @R1,A
        INC R1
        MOV A,B
        DJNZ R0,M1
        RET

        INIT_LCD:MOV COM,#00111000B
        LCALL WRITE_COM
        MOV COM,#00001110B
        LCALL WRITE_COM
        MOV COM,#00000110B
        LCALL WRITE_COM
        MOV COM,#00000001B
        LCALL WRITE_COM
        RET

        DISP_LCD:MOV COM,#80H
        LCALL WRITE_COM
        MOV DPTR,#TABLE1
        MOV R1,#16
        MOV R0,#00
        M2:MOV A,R0
        MOVC A,@A+DPTR
        MOV DAT,A
        LCALL WRITE_DAT
        INC R0
        LCALL DELAY1MS
        DJNZ R1,M2
        MOV COM,#0C0H
        LCALL WRITE_COM
        MOV DPTR,#TABLE3
        MOV R1,#05H
        MOV R0,#00H
        M3:MOV A,R0
        MOVC A,@A+DPTR
        MOV DAT,A
        LCALL WRITE_DAT
        INC R0
        LCALL DELAY1MS
        DJNZ R1,M3
        MOV DPTR,#TABLE2
        MOV A,BAI
        MOVC A,@A+DPTR
        MOV DAT,A
        LCALL WRITE_DAT
        MOV A,SHI
        MOVC A,@A+DPTR
        MOV DAT,A
        LCALL WRITE_DAT
        MOV A,GEX
        MOVC A,@A+DPTR
        MOV DAT,A
        LCALL WRITE_DAT
        MOV A,#10
        MOV DPTR,#TABLE2
        MOVC A,@A+DPTR
        MOV DAT,A
        LCALL WRITE_DAT
        MOV R1,#04
        MOV R0,#XI
        M4:MOV A,@R0
        MOVC A,@A+DPTR
        MOV DAT,A
        LCALL WRITE_DAT
        LCALL DELAY1MS
        INC R0
        DJNZ R1,M4
        MOV A,#11
        MOVC A,@A+DPTR
        MOV DAT,A
        LCALL WRITE_DAT
        LCALL DELAY1MS
        RET

        WRITE_COM:CLR RS
        CLR RW
        MOV P0,COM
        LCALL DELAY3MS
        CLR E
        SETB E
        CLR E
        RET

        WRITE_DAT:SETB RS
        CLR RW
        MOV P0,DAT
        LCALL DELAY3MS
        CLR E
        SETB E
        CLR E
        RET

        DELAY200MS: ;誤差 0us
        MOV R7,#04H
        DL6:
        MOV R6,#74H
        DL5:
        MOV R5,#0D6H
        DJNZ R5,$
        DJNZ R6,DL5
        DJNZ R7,DL6
        NOP
        RET

        DELAY3MS: ;誤差 0us
        MOV R6,#6FH
        DL0:
        MOV R5,#0CH
        DJNZ R5,$
        DJNZ R6,DL0
        RET

        DELAY1MS: ;誤差 0us
        MOV R7,#01H
        DL4:
        MOV R6,#8EH
        DL3:
        MOV R5,#02H
        DJNZ R5,$
        DJNZ R6,DL3
        DJNZ R7,DL4
        RET

        DELAY600US: ;誤差 0us
        MOV R6,#03H
        DL2:
        MOV R5,#62H
        DJNZ R5,$
        DJNZ R6,DL2
        RET

        TABLE1: DB "Digital thermomet"
        TABLE2: DB "0123456789.C"
        TABLE3: DB "temp:"

        END

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #include
        #include
        #define uint unsigned int
        #define uchar unsigned char
        sbit rs=P2^4;
        sbit rw=P2^5;
        sbit e=P2^6;
        sbit dq=P1^7;
        uchar bai,shi,ge,xi1,xi2,i;
        uint temp;
        uchar code table1[]={"0123456789.C"};
        uchar code table2[]="Digital thermomet";
        uchar code table3[]="temp:";

        void delay(uchar t) //誤差 0us 1mS延時
        {
        unsigned char a,b;
        for(t=1;t>0;t--)
        for(b=142;b>0;b--)
        for(a=2;a>0;a--);
        }

        /**************DS18B20操作******************/
        void init_ds18b20()
        {
        dq=1;
        _nop_();
        dq=0;
        for(i=0;i<200;i++);//延時min=480uS ,max=960uS;
        dq=1;
        for(i=0;i<20;i++);//延時min=15uS,max=60uS.DS18B20等待15~60uS;
        while(dq);//dq為1表明無DS18B20
        for(i=0;i<200;i++)//延時300us使DS18B20輸出應答完畢
        dq=1;
        }

        void WriteOneByte(uchar dat)
        {
        uchar j;
        for(j=8;j>0;j--)
        {
        dq=1;
        _nop_(); //至少1mS延時
        dq=0;
        _nop_();
        dq=(bit)(dat&0x01);
        for(i=0;i<20;i++);//寫周期最少為60uS,不能超過120uS
        dq=1;
        //for(i=0;i<1;i++); //可以沒有
        dat>>=1;
        }
        }

        uchar ReadOneByte()
        {
        uchar j,dat;
        for(j=0;j<8;j++)
        {
        dq=1;
        _nop_(); //至少1uS的恢復期
        dq=0;
        _nop_();
        dq=1;
        for(i=0;i<3;i++);//主機在15uS內讀取DQ
        dat>>=1;
        if(dq==1)
        dat|=0x80;
        else
        dat|=0x00;
        for(i=0;i<15;i++);//一個讀周期至少要60us
        }
        return(dat);
        }

        void temp_ds18b20()
        {
        uchar th,tl;
        uint x;
        float p;
        init_ds18b20();
        WriteOneByte(0xcc);
        WriteOneByte(0x44);
        delay(255);//等待轉換最大為750ms,典型值為200mS
        init_ds18b20();
        WriteOneByte(0xcc);
        WriteOneByte(0xbe);
        tl=ReadOneByte();
        th=ReadOneByte();
        x=th;
        x<<=8;
        x|=tl;//合并高低位
        p=x*0.0625;//實際轉換溫度值為p
        temp=p*100+0.5;//將小數轉換為整數并保留兩位小數,第三位小數四舍五入
        }
        /******************************************************/

        /***********************數據轉換***********************/
        void datchx()
        {
        uchar d,t;
        float g;
        g=temp/100.00;
        d=g;
        t=(g-d)*100;//整數與小數部分分離,t為小數,d為整數;
        bai=d/100;
        shi=(d%100)/10;
        ge=d%10;//整數分離
        xi1=t/10;
        xi2=t%10;
        }
        /****************************************************/
        /******************LCD1602操作***********************/
        void write_com(uchar dat)
        {
        rs=0;
        rw=0;
        P0=dat;
        delay(3);
        e=0;
        e=1;
        e=0;
        }

        void write_dat(uchar dat)
        {
        rs=1;
        rw=0;
        P0=dat;
        delay(3);
        e=0;
        e=1;
        e=0;
        }

        void init_lcd()
        {
        write_com(0x38);
        write_com(0x0D);
        write_com(0x06);
        write_com(0x01);
        }

        void disp_lcd()
        {
        write_com(0x80);
        for(i=0;i<16;i++)
        {
        write_dat(table2[i]);
        delay(5);
        }
        write_com(0xc0);
        for(i=0;i<5;i++)
        {
        write_dat(table3[i]);
        delay(5);
        }
        write_dat(table1[bai]);
        write_dat(table1[shi]);
        write_dat(table1[ge]);
        write_dat(table1[10]);
        write_dat(table1[xi1]);
        write_dat(table1[xi2]);
        write_dat(table1[11]);
        }
        /****************************************************/
        void main()
        {
        SP=0x30;
        init_lcd();
        while(1)
        {
        temp_ds18b20();
        datchx();
        disp_lcd();
        }
        }



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 达日县| 阳新县| 郑州市| 屏南县| 疏勒县| 密山市| 章丘市| 舞阳县| 古蔺县| 阳城县| 安泽县| 靖安县| 仙游县| 汉寿县| 枞阳县| 云霄县| 本溪市| 育儿| 乐都县| 江西省| 滦南县| 六盘水市| 丹棱县| 于都县| 镇原县| 南召县| 河北区| 辰溪县| 堆龙德庆县| 香河县| 当涂县| 札达县| 南涧| 双桥区| 太白县| 内丘县| 晋城| 建德市| 汝城县| 龙门县| 随州市|