新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 基于89S51的實時數字溫度計(DS1302 18B20)

        基于89S51的實時數字溫度計(DS1302 18B20)

        作者: 時間:2016-11-30 來源:網絡 收藏

        uchar Read_DS1302(uchar reg)//從DS1302寄存器讀數據
        {
        uchar byte;
        C_RST;
        C_CLK;
        S_RST;
        DS1302_InputByte(reg);
        byte = DS1302_OutputByte();
        S_CLK;
        C_RST;
        return(byte);
        }

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


        void GetTime_DS1302(uchar *ucCurtime) //讀取DS1302當前時間
        {

        ucCurtime[0] = Read_DS1302(0x81);//格式為: 秒 分 時
        ucCurtime[1] = Read_DS1302(0x83);
        ucCurtime[2] = Read_DS1302(0x85);
        }

        void Set_Time(uchar *receive) //寫時間
        {
        Write_Enable; //控制命令,允許寫操作

        RW_DS1302(0x80,receive[0]);
        RW_DS1302(0x82,receive[1]);
        RW_DS1302(0x84,receive[2]);


        Write_Disable; // 控制命令,寫保護
        }

        /********************************************************
        * *
        * 數碼管顯示程序段 *
        * *
        ********************************************************/
        void deal(void)//送顯前的數據處理
        {uint timer2;
        uint lstemp;
        timer2++;

        if(STA)
        {GetTime_DS1302(collect_time);}
        if(flash)//用于閃動效果的控制的
        {
        display[0] = num[sg];
        display[1] = num[sd];
        display[2] = num[fg];
        display[3] = num[fd];
        display[4] = num[mg];
        display[5] = num[md];
        }
        else
        {switch(choose)
        {
        case 1:display[0]=0;break;
        case 2:display[1]=0;break;
        case 3:display[2]=0;break;
        case 4:display[3]=0;break;
        case 5:display[4]=0;break;
        case 6:display[5]=0;break;
        }
        }
        if(timer2==3000)//間斷性獲取溫度
        {
        timer2=0;
        if(STA)
        {TR0=0;
        Ds18b20_ReadEE();
        TR0=1;
        }
        }
        if(collect_temperature[1]>127)
        {
        collect_temperature[0]=255-collect_temperature[0];
        collect_temperature[1]=255-collect_temperature[1];
        }
        lstemp=((collect_temperature[0])>>4)|((collect_temperature[1])<<4);


        display[6] = num[(uchar)((lstemp)/10)];
        display[7] = num[(uchar)((lstemp)%10)];

        }

        /********************************************************
        * *
        * 按鍵控制程序段 *
        * *
        ********************************************************/

        void Scan(void)
        {

        if(SET==0&&keyboard==1) //檢測設置鍵有無按下,并進行相應操作
        {
        if(SET==0&&keyboard==1)
        { RdefineT1; //超時檢測初始化
        choose++;

        while(SET==0);
        if(choose==7)
        {TR0=0;
        Set_Time(collect_time);
        TR0=1;
        STA=1; //設置完畢,重新開始采集時間
        choose=0;
        }
        }
        }

        if(choose) //只有在時間調整時,加減按鍵才有作用
        {
        if(ADD==0&&keyboard==1) //檢測加調整鍵有無按下,并進行相應操作
        {
        if(ADD==0&&keyboard==1)
        { RdefineT1; //超時檢測初始化a=0
        TR0=0;
        switch(choose)
        {
        case 1 :if(sg==2)
        collect_time[2] = collect_time[2]&0x0f;
        else {collect_time[2]+=16;}
        break;
        case 2 :if((sg<2)&&(sd==9))
        collect_time[2] &= 0x30;
        if((sg>=2)&&(sd==3))
        collect_time[2] &= 0x30;
        else {collect_time[2]++;}
        break;
        case 3: if(fg==5)
        collect_time[1] &= 0x0f;
        else {collect_time[1]+=16;}
        break;
        case 4: if(fd==9)
        collect_time[1] &= 0xf0;
        else {collect_time[1]++;}
        break;
        case 5: if(mg==5)
        collect_time[0] &= 0x0f;
        else {collect_time[0]+=16;}
        break;
        case 6: if(md==9)
        collect_time[0] &= 0xf0;
        else {collect_time[0]++;}
        break;
        }
        TR0=1;
        while(ADD==0);
        }
        }

        if(DEC==0&&keyboard==1) //檢測減調整鍵有無按下,并進行相應操作
        {
        if(DEC==0&&keyboard==1)
        { RdefineT1; //超時檢測初始化

        TR0=0;
        switch(choose)
        {
        case 1 :if(sg==0)
        collect_time[2]=0x20;
        else collect_time[2]-=16;
        break;
        case 2 :if(sg<2&&sd==0)
        collect_time[2] |= 0x09;
        if(sg==2&&sd==0)
        collect_time[2] |= 0x03;
        else collect_time[2]-=1;
        break;
        case 3 :if(fg==0)
        collect_time[1] |= 0x50;
        else collect_time[1]-=16;
        break;
        case 4 :if(fd==0)
        collect_time[1] |= 0x09;
        else collect_time[1]-=1;
        break;
        case 5 :if(mg==0)
        collect_time[0] |= 0x50;
        else collect_time[0]-=16;
        break;
        case 6 :if(md==0)
        collect_time[0] |= 0x09;
        else collect_time[0]-=1;
        break;
        }
        TR0=1;
        while(DEC==0);
        }
        }
        }

        if(choose!=0){TR1=1;STA=0;} //在設置模式下停止采集時間
        else {TR1=0;STA=1;}
        }

        /********************************************************
        * *
        * AT89S51主程序段 *
        * *
        ********************************************************/
        void main(void)
        {
        Time01_Int();
        Dat_Int();

        EA = 1; //開中斷

        ow_reset(); // 開機先轉換一次
        write_byte(0xCC); // Skip ROM
        write_byte(0x44); // 發轉換命令
        delay(100);

        Set_Time(collect_time);
        delay(10);

        while(1)
        {
        Scan();
        deal();
        }//while循環的結束
        }//main函數的結束


        void Time0_seve() interrupt 1 //定時器0中斷服務程序
        {
        uint timer;
        uchar i,ktemp;
        if((P1&0x70)<0x70) //防抖控制用
        keyboard=1;
        else keyboard=0;

        timer++;
        if(timer==800)//控制數碼管的閃動效果
        {
        if(choose !=0)
        flash=~flash;
        else flash = 1;
        timer=0;
        }

        TR0=0;
        ktemp=P0;
        if(P0==0xfe)i=1;
        else if(P0==0xfd)i=2;
        else if(P0==0xfb)i=3;
        else if(P0==0xf7)i=4;
        else if(P0==0xef)i=5;
        else if(P0==0xdf)i=6;
        else if(P0==0xbf)i=7;
        else if(P0==0x7f)i=0;
        else i=1;

        ktemp=ktemp*2+1;
        if(ktemp==0xff)ktemp=0xfe;
        P0=ktemp;
        P2=display[i];
        TR0=1;
        }

        void Time1_seve() interrupt 3 //定時器1中斷服務程序
        {
        TR1=0;TH1=0;TL1=0;
        a++;
        if(a>4*ReDetectTime)
        {
        choose=0;
        a=0;
        Set_Time(collect_time);
        STA=1; //超過按鍵等待時間,自動寫入并開始采集時間
        }
        }


        上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 达州市| 濉溪县| 滨海县| 右玉县| 三都| 阳西县| 盱眙县| 元江| 永丰县| 南溪县| 沁水县| 德清县| 大渡口区| 仲巴县| 大埔区| 浙江省| 武汉市| 高州市| 从江县| 略阳县| 大姚县| 南郑县| 象州县| 孝感市| 峡江县| 平定县| 改则县| 莱阳市| 浪卡子县| 营山县| 宝应县| 益阳市| 明水县| 西充县| 西城区| 丹阳市| 高州市| 永兴县| 凯里市| 谢通门县| 卓尼县|