久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1566|回復: 6
打印 上一主題 下一主題
收起左側

單片機溫度控制,想把溫度下限設置成負的,不知道怎么弄

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:985137 發(fā)表于 2022-3-12 10:29 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
#include <reg51.h>

#define uint unsigned int
#define uchar unsigned char

sbit DQ=P2^3;   //ds18b20與單片機連接口

sbit RS=P2^5;   //液晶控制線接口
sbit RW=P2^6;
sbit EN=P2^7;



uchar data disdata[5];
uint tvalue,CurrentT=0;   //溫度值
uchar tflag;              //溫度正負標志

               
#define LCD_BUS P0

sbit SetKey = P2^0; //設置按鍵
sbit UpKey  = P2^1; //加按鍵
sbit DnKey  = P2^2; //減按鍵
sbit BEEP   = P2^4; //蜂鳴器

sbit Heat  = P1^0;  //加熱繼電器控制
sbit Cool  = P1^1;  //降溫繼電器控制


unsigned char AlarmTempLow=0,AlarmTempTop=30,Set=0;






void delayms(uint ms)   //延時xx毫秒
{
        uchar i;
        while(ms--)
        {
                 for(i=0;i<120;i++);
        }
}



void command(uint com)         //LCD寫指令
{
   RS=0;                                //RS為0
   LCD_BUS=com;             //裝載指令
   delayms(5);                 //延時5ms
   EN=1;                                 //LCD使能
   delayms(5);                //延時5ms
   EN=0;                                //LCD不使能
}

void write_dat(uchar dat)          //LCD寫數(shù)據(jù)
{
   RS=1;                                        //RS為1
   LCD_BUS=dat;                     //裝載數(shù)據(jù)
   delayms(5);                         //延時5ms
   EN=1;                                         //LCD使能
   delayms(5);                         //延時5ms
   EN=0;                                         //LCD不使能
}

void writestring(uchar x,uchar y,uchar *s) //LCD 寫字符串
{     
        if (y == 0)  command(0x80 + x);     //表示第一行
        else         command(0xC0 + x);      //表示第二行

        while (*s)                         //判斷是否字符串的結尾
        {     
     write_dat( *s);    //顯示當前字符
                s ++;                             //字符串地址加1
        }
}

void writeChar(uchar x,uchar y,uchar s) //LCD 寫字符串
{     
        if (y == 0)  command(0x80 + x);     //表示第一行
        else         command(0xC0 + x);      //表示第二行

        {     
     write_dat( s);    //顯示當前字符
        }
}


void LCD_Initial()                //LCD初始化
{

   EN=0;                                  //LCD不使能
   RW=0;                                  //RW為0
   command(0x38);                //發(fā)送初始化指令
   command(0x0c);                //發(fā)送初始化指令
   command(0x06);          //發(fā)送初始化指令
   command(0x01);          //發(fā)送初始化指令
   command(0x80+0x02);        //發(fā)送LCD初始位置
}


/*************************DS1820程序****************************/
void delay_18B20(unsigned int i)//延時1微秒
{
   while(i--);
}

void ds1820rst(void)/*ds1820復位*/
{
        unsigned char x=0;
        DQ = 1;          //DQ復位
        delay_18B20(4); //延時
        DQ = 0;          //DQ拉低
        delay_18B20(100); //精確延時大于480us
        DQ = 1;          //拉高
        delay_18B20(40);
}

uchar ds1820rd(void)/*讀數(shù)據(jù)*/
{
        unsigned char i=0;
        unsigned char dat = 0;
        for (i=8;i>0;i--)
        {   
                DQ = 0; //給脈沖信號
                dat>>=1;
                DQ = 1; //給脈沖信號
                if(DQ)
                dat|=0x80;
                delay_18B20(10);
                DQ=1;
        }
   return(dat);
}

void ds1820wr(uchar wdata)/*寫數(shù)據(jù)*/
{
        unsigned char i=0;
   for (i=8; i>0; i--)    //寫一個字節(jié)數(shù)據(jù)到DS18B20
   {
                DQ = 0;
                DQ = wdata&0x01;  //寫一位數(shù)據(jù)
                delay_18B20(10);  //延時
                DQ = 1;           //拉高數(shù)據(jù)線
                wdata>>=1;        //準備下一位
   }
}

unsigned int Read_Temperature(void)/*讀取溫度值并轉(zhuǎn)換*/
{
        uchar a,b;
        ds1820rst();   
        ds1820wr(0xcc);//*跳過讀序列號*/
        ds1820wr(0x44);//*啟動溫度轉(zhuǎn)換*/
        ds1820rst();   
        ds1820wr(0xcc);//*跳過讀序列號*/
        ds1820wr(0xbe);//*讀取溫度*/
        a=ds1820rd();  //讀取低位數(shù)據(jù)
        b=ds1820rd();  //讀取高位數(shù)據(jù)
        tvalue=b;   
        tvalue<<=8;
        tvalue=tvalue|a;   //取得16位數(shù)據(jù)
   if(tvalue<0x0fff)   tflag=0; //判斷是否正溫度
   else   {tvalue=~tvalue+1;tflag=1;}    //負溫度,數(shù)據(jù)取反,溫度標志位為1
        tvalue=tvalue*(0.625);//溫度值擴大10倍,精確到1位小數(shù)
        CurrentT=tvalue;//保存當前溫度
        return(tvalue);//返回溫度值
}

void Display_Temperature()                //顯示溫度
{
        uchar flagdat;
   disdata[0]=tvalue/1000+0x30;//百位數(shù)
   disdata[1]=tvalue%1000/100+0x30;//十位數(shù)
   disdata[2]=tvalue%100/10+0x30;//個位數(shù)
   disdata[3]=tvalue%10+0x30;//小數(shù)位

   if(tflag==0)   flagdat=0x20;//正溫度不顯示符號
   else   flagdat=0x2d;//負溫度顯示負號:-
        if(tflag==1)
        {
                writeChar(10,0,flagdat);//顯示符號位
                writeChar(11,0,disdata[0]);//顯示百位
                writeChar(12,0,disdata[1]);//顯示十位
                writeChar(13,0,disdata[2]);//顯示個位
                writeChar(14,0,0X2E);//顯示小數(shù)點
                writeChar(15,0,disdata[3]);//顯示小數(shù)位
        }
        else
        {
                writeChar(10,0,disdata[0]);//顯示百位
                writeChar(11,0,disdata[1]);//顯示十位
                writeChar(12,0,disdata[2]);//顯示個位
                writeChar(13,0,0X2e);//顯示小數(shù)點
                writeChar(14,0,disdata[3]);//顯示小數(shù)位
                writeChar(15,0,' ');//顯示小數(shù)位
        }
}

void SetFun(void) //進入設置參數(shù)子函數(shù)
{
        unsigned char i1=0,i2=0,i3=0,i4=0,i5=0,i6=0;
        if(SetKey==0)  //設置按鍵
        {
                delayms(20);   //延時防抖
                if(SetKey==0)  //設置按鍵
                {
                        if(Set<2)        Set++;   //設置按鍵次數(shù)累計
                        else Set=0;
                }
                switch(Set) //根據(jù)設置按鍵次數(shù),指向?qū)O置位置
                {
                        case 0:  writestring(0,1," ");writestring(8,1," ");break;//清除設置符號
                        case 1:        writestring(0,1,">");writestring(8,1," ");break;//指向設置下限
                        case 2:        writestring(0,1," ");writestring(8,1,">");break;//指向設置上限
                }
                while(SetKey==0);//等待按鍵松開
        }
       
        if((UpKey==0)&&(Set!=0))//加按鍵按下
        {
                delayms(20);//延時防抖
                if(UpKey==0)//加按鍵按下
                {
                        switch(Set)//根據(jù)設置按鍵次數(shù),設置上下限
                        {
                                case 1:        if(AlarmTempLow<99) AlarmTempLow++;else AlarmTempLow=99; break;//設置下限
                                case 2:        if(AlarmTempTop<99) AlarmTempTop++;else AlarmTempTop=99; break;//設置上限
                        }
                        i1 = AlarmTempLow/100;             //獲得下限溫度值的百位
                   i2 = (AlarmTempLow%100)/10;         //獲得下限溫度值的十位
                        i3 = AlarmTempLow%10;                 //獲得下限溫度值的個位
                       
                        i4 = AlarmTempTop/100;              //獲得上限溫度值的百位
                   i5 = (AlarmTempTop%100)/10;         //獲得上限溫度值的十位
                        i6 = AlarmTempTop%10;                 //獲得上限溫度值的個位

                        writestring(5,1,"   ");       //清除之前的內(nèi)容
                        writestring(13,1,"     ");    //清除之前的內(nèi)容
                        if(i1!=0)        writeChar(5,1,i1+'0');                  //在第二行第5位 ,顯示下限溫度值的百位
                        if((i1==0)&&(i2!=0)) writeChar(5,1,i2+'0');         //在第二行第5位 ,顯示下限溫度值的十位
                        if(i1!=0) writeChar(6,1,i2+'0');                    //在第二行第6位 ,顯示下限溫度值的十位
                        if((i1==0)&&(i2==0))        writeChar(5,1,i3+'0');      //在第二行第5位 ,顯示下限溫度值的個位
                        else if((i1==0)&&(i2!=0))        writeChar(6,1,i3+'0');  //在第二行第6位 ,顯示下限溫度值的個位
                        if((i1!=0))         writeChar(7,1,i3+'0');                 //在第二行第7位 ,顯示下限溫度值的個位
                       
                        if(i4!=0)        writeChar(13,1,i4+'0');                 //在第二行第13位 ,顯示上限溫度值的百位
                        if((i4==0)&&(i5!=0)) writeChar(13,1,i5+'0');        //在第二行第13位 ,顯示上限溫度值的十位
                        if(i4!=0) writeChar(14,1,i5+'0');                   //在第二行第14位 ,顯示上限溫度值的十位
                        if((i4==0)&&(i5==0))        writeChar(13,1,i6+'0');     //在第二行第13位 ,顯示上限溫度值的個位
                        else if((i4==0)&&(i5!=0))        writeChar(14,1,i6+'0'); //在第二行第14位 ,顯示上限溫度值的個位
                        if((i4!=0)) writeChar(15,1,i6+'0');                 //在第二行第15位 ,顯示上限溫度值的個位
                        while(UpKey==0);       //等待按鍵松開
                }
        }
       
        if((DnKey==0)&&(Set!=0))//減按鍵
        {
                delayms(20);
                if(DnKey==0)//減按鍵
                {
                        switch(Set)//根據(jù)設置按鍵次數(shù),設置上下限
                        {
                                case 1:        if(AlarmTempLow>0) AlarmTempLow--;else AlarmTempLow=0; break;//設置下限
                                case 2:        if(AlarmTempTop>0) AlarmTempTop--;else AlarmTempTop=0; break;//設置上限
                        }
                        i1 = AlarmTempLow/100;          //獲得下限溫度值的百位
                   i2 = AlarmTempLow%100/10;         //獲得下限溫度值的十位
                        i3 = AlarmTempLow%10;                 //獲得下限溫度值的個位
                       
                        i4 = AlarmTempTop/100;          //獲得上限溫度值的百位
                   i5 = AlarmTempTop%100/10;         //獲得上限溫度值的十位
                        i6 = AlarmTempTop%10;                 //獲得上限溫度值的個位
                        writestring(5,1,"   ");    //清除之前的內(nèi)容
                        writestring(13,1,"     ");//清除之前的內(nèi)容
                        if(i1!=0)        writeChar(5,1,i1+'0');//在第二行第5位 ,顯示下限溫度值的百位
                        if((i1==0)&&(i2!=0)) writeChar(5,1,i2+'0');//在第二行第5位 ,顯示下限溫度值的十位
                        if(i1!=0) writeChar(6,1,i2+'0');//在第二行第6位 ,顯示下限溫度值的十位
                        if((i1==0)&&(i2==0))        writeChar(5,1,i3+'0');//在第二行第5位 ,顯示下限溫度值的個位
                        else if((i1==0)&&(i2!=0))        writeChar(6,1,i3+'0');//在第二行第6位 ,顯示下限溫度值的個位
                        if((i1!=0))         writeChar(7,1,i3+'0');//在第二行第7位 ,顯示下限溫度值的個位
                       
                        if(i4!=0)        writeChar(13,1,i4+'0');//在第二行第13位 ,顯示上限溫度值的百位
                        if((i4==0)&&(i5!=0)) writeChar(13,1,i5+'0');//在第二行第13位 ,顯示上限溫度值的十位
                        if(i4!=0) writeChar(14,1,i5+'0');//在第二行第14位 ,顯示上限溫度值的十位
                        if((i4==0)&&(i5==0))        writeChar(13,1,i6+'0');//在第二行第13位 ,顯示上限溫度值的個位
                        else if((i4==0)&&(i5!=0))        writeChar(14,1,i6+'0');//在第二行第14位 ,顯示上限溫度值的個位
                        if((i4!=0)) writeChar(15,1,i6+'0');//在第二行第15位 ,顯示上限溫度值的個位
                       
                        while(DnKey==0);
                }
        }
}



void Alarm(void)//報警子函數(shù)
{
        if((CurrentT>=(AlarmTempTop*10))||(CurrentT<=(AlarmTempLow*10))||(tflag==1)) //超出設定范圍
                {
                        BEEP=0;//啟動報警
                }
                else //在設定范圍內(nèi)
                {
                        BEEP=1;//取消報警
                }
}


void main(void)
{
        unsigned char i=0;
        //P3=0xef;
        P2=0xef;P1=0xff;BEEP=1;//端口初始化,
        LCD_Initial();         //LCD 初始化
       
        Read_Temperature(); //讀取溫度值
        writestring(1,0,"DS18B20 Alarmer");          //顯示“DS18B20 Alarmer”
        delayms(1000);                //延時1S
        writestring(0,0,"Current T=      ");          //顯示“Current T= ”
        writestring(0,1," Low=0   Top=30 ");          //顯示“ Low=10  Top=40 ”
       
        //NG=0;
        while(1)
        {
                 Read_Temperature();        //        //讀取溫度值
                Display_Temperature();                //顯示溫度值
                SetFun();//參數(shù)設置,按鍵功能
                Alarm();//報警子函數(shù)
                if((CurrentT<(AlarmTempTop*10))&&(CurrentT>(AlarmTempLow*10)))//當前溫度在設置范圍內(nèi)
                {
                        Cool=1;Heat=1;//不加熱,不降溫
                }
                else if((CurrentT>=(AlarmTempTop*10)))//當前溫度高過設定值上限
                {
                        Cool=0;Heat=1;//不加熱,降溫
                }
                else if((CurrentT<=(AlarmTempLow*10))||(tflag==1))//當前溫度低于下限
                {
                        Cool=1;Heat=0;//加熱,不降溫
                }
        }       

}

批注 2022-03-12 102710.png (34.61 KB, 下載次數(shù): 35)

批注 2022-03-12 102710.png
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:466505 發(fā)表于 2022-3-12 10:37 | 只看該作者
用有符號數(shù)不行??
回復

使用道具 舉報

板凳
ID:551638 發(fā)表于 2022-3-12 13:01 | 只看該作者
判斷,然后手動加
回復

使用道具 舉報

地板
ID:985137 發(fā)表于 2022-3-12 14:42 | 只看該作者
hcfat51h 發(fā)表于 2022-3-12 10:37
用有符號數(shù)不行??

不懂?
回復

使用道具 舉報

5#
ID:161164 發(fā)表于 2022-3-12 15:10 | 只看該作者
顯示歸顯示,按鍵歸按鍵
改了一部份
余下的加熱保溫控制你再想一下



                       
       
                                                        
回復

使用道具 舉報

6#
ID:985137 發(fā)表于 2022-3-14 09:33 | 只看該作者
lkc8210 發(fā)表于 2022-3-12 15:10
顯示歸顯示,按鍵歸按鍵
改了一部份
余下的加熱保溫控制你再想一下

老哥,SPL_tflag怎么定義呀
回復

使用道具 舉報

7#
ID:161164 發(fā)表于 2022-3-14 10:52 | 只看該作者
2248373991 發(fā)表于 2022-3-14 09:33
老哥,SPL_tflag怎么定義呀

bit SPL_tflag = 0;
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: av中文字幕在线观看 | 美女视频一区二区三区 | 91精品久久久久久久久 | 免费成人av网站 | 日韩二区 | 在线日韩精品视频 | 毛片免费视频 | 91精品国产综合久久福利软件 | 草樱av| 99色综合 | 91在线导航 | 免费看色 | 午夜伦理影院 | 午夜影院黄 | 成人高清在线视频 | 9色网站 | 久久999| 狠狠色狠狠色综合系列 | 欧洲成人 | 久久久在线视频 | 国产一区视频在线 | 久久亚洲一区二区三区四区 | 精品一区二区三区在线观看国产 | 亚洲成人毛片 | 国产精品视频一区二区三区四蜜臂 | 国产成人精品一区二区三区四区 | 日韩三区在线观看 | 成av人电影在线 | 国产成人av一区二区三区 | 国产精品免费一区二区三区四区 | 黄色一级片aaa| 久久国产视频网站 | 一本色道久久综合亚洲精品高清 | 精品久久99| 天天躁日日躁aaaa视频 | 亚洲欧洲在线观看视频 | 草比av| 国产精品久久久久久久久久久久久 | 久久久久国产一区二区三区 | 夜夜艹| 国产99视频精品免视看9 |