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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3845|回復(fù): 2
收起左側(cè)

基于51單片機(jī)的溫度控制系統(tǒng)

[復(fù)制鏈接]
ID:791004 發(fā)表于 2020-6-30 16:41 | 顯示全部樓層 |閱讀模式
本溫度控制系統(tǒng)共有四個模塊,分別是單片機(jī)控制系統(tǒng),矩陣鍵盤電路,溫度檢測電路,液晶顯示電路,其中以單片機(jī)控制系統(tǒng)為控制核心,首先由溫度檢測電路對環(huán)境進(jìn)行溫度采集,本系統(tǒng)中檢測電路中用的溫度傳感器是DS18B20,將所在環(huán)境溫度檢測出來,單片機(jī)讀取溫度數(shù)據(jù),接著進(jìn)行液晶顯示。矩陣鍵盤輸入設(shè)定的數(shù)據(jù),然后與實際溫度比較,決定加熱還是降溫,并在液晶顯示屏上顯示相應(yīng)的狀態(tài)。
仿真圖:
51hei.png
程序:#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define ActualTemp_worth 9
#define TempSet_worth 9
#define row_worth 16
void dentify_key(uchar key);
void get_temp(void);
uchar keyscan();
void solid_data(void);
uchar sk,temp2;//sk表示有鍵按下標(biāo)志,temp2用來臨時存儲掃描值
uchar code table[]="RealTemp:";
uchar code table1[]="TempRset:";
uchar code table2[]={0xdf,'C'};
uchar code table3[]="ADD";
uchar code table4[]="SUB";
uchar a,a_low,b,t,t1,temp1,key,c;//t表示溫度整數(shù)部分,t1表示溫度小數(shù)部分,temp1為中間變量(P3)
float t2,f_temp;
uint temp;
uchar sg=0,made_temp=0,made_temp1=0;
sbit lcden=P1^7;       //*******************LCD1602的使能端
sbit lcdrs=P1^6;       //*******************LCD1602的數(shù)據(jù)命令端
sbit DQ=P1^1;         //*******************DS18B20的DS端
sbit SIG=P1^5;         //******************按鍵輸入信號
sbit ADD=P1^2;
sbit SUB=P1^3;
sbit ex0_enter=P3^2;
uchar code tablenum[]={0xc0,0xf9,0xa4,0xb0,0x99,        //0~9
                       0x92,0x82,0xf8,0x80,0x90};

uchar code tablenum2[]={0x30,0x31,0x32,0x33,0x34,       //0~9的ASIIC值
                        0x35,0x36,0x37,0x38,0x39};

/*****************************************************************
                    LCD1602液晶顯示
*****************************************************************/
uchar num=0;
void delay(int z)//延遲函數(shù)delay
{
    uint x,y;
    for(x=z;x>0;x--)
        for(y=110;y>0;y--);
}
void delay1(uint i)//延遲函數(shù)delay1
{
    while(i>0) i--;
}
void write_com(uchar com)
{
    lcdrs=0;
    P0=com;
    delay(1);
    lcden=1;
    delay(1);
    lcden=0;
}
void write_data(uchar date)
{
    lcdrs=1;
    P0=date;
    delay(1);
    lcden=1;
    delay(1);
    lcden=0;
}
void init_lcd()//LCD1602初始化函數(shù)
{
    lcden=0;
    write_com(0x38);
    write_com(0x0c);
    write_com(0x06);
    write_com(0x01);
}
bit int_DS18B20(void)//DS18B20初始化函數(shù)
{
    unsigned char x=0;
    uint i;
    DQ=0;
    i=103;
    while(i>0)i--;
    DQ=1;
    i=4;
    while(i>0)i--;
    x=DQ;           //延時片刻后,若x=0,則初始化成功;若x=1,則初始化失敗
    delay(20);
    return x;
}
//*************DS18B20讀取一位數(shù)據(jù)函數(shù)
bit tempreadbit(void)
{
    uint i;
    bit dat;
    DQ=0;i++;
    DQ=1;i++;i++;
    dat=DQ;
    i=8;while(i>0)i--;
    return (dat);
}

//*************DS18B20讀取一個字節(jié)函數(shù)
uchar Read(void)//DS18B20讀取一個字節(jié)
{
unsigned char i=0;
unsigned char j=0;
unsigned char dat=0;
for(i=8;i>0;i--)
    {
        j=tempreadbit();
        dat=(j<<7)|(dat>>1);
   
    }   
        return(dat);
}
//*************DS18B20寫一個字節(jié)函數(shù)
Write(unsigned char dat)
{
    uint i;
    uchar j;
    bit testb;
    for(j=1;j<=8;j++)
    {
        testb=dat&0x01;
        dat=dat>>1;
        if(testb)
        {
            DQ=0;
            i++;i++;
            DQ=1;
            i=8;while(i>0)i--;
        }
        else
        {
            DQ=0;
            i=8;while(i>0)i--;
            DQ=1;
            i++;i++;
        }
    }
}
//****************啟動轉(zhuǎn)換函數(shù)
void int_(void)
{
while(int_DS18B20());//若為1,重新初始化
delay(1);
Write(0xcc);
Write(0x44);
}

//main()主函數(shù)
void main()
{
    init_lcd();//液晶初始化
    int_();   //啟動溫度轉(zhuǎn)換
    sk=0;
    c=0;
    EA=1;   //開總中斷
    EX0=1;  //打開外部中斷0中斷
    solid_data();//打印固定數(shù)據(jù)
    while(1)
    {
        int_();
        
        delay1(1700);//等待溫度傳感器轉(zhuǎn)換溫度
        
        get_temp();
        keyscan(); //此次掃描主要是用來檢測設(shè)置按鍵是否被按下

        if((sk!=0)&&(c==1))//表明所要設(shè)置的溫度已經(jīng)給定
        {
            if((t+1)>made_temp)
            {
                ADD=1;
                SUB=0;
                write_com(0x80+0x4c);
                for(num=0;num<3;num++)
                    write_data(table4[num]);
            }
            else
            {
                SUB=1;
                ADD=0;
                write_com(0x80+0x4c);
                for(num=0;num<3;num++)
                    write_data(table3[num]);            
            }   
        }
    }
}//main函數(shù)

//***********************溫度讀取函數(shù)
void get_temp(void)
{
    while(int_DS18B20());
   
    Write(0xcc);
    Write(0xBE);//讀取溫度寄存器指令
    a=Read();
    b=Read();
    temp=b;
    temp<<=8;
    temp=temp|a;
    f_temp=temp*0.0625;
    t=(uchar)(f_temp);
    t2=f_temp-t;
    t1=(uchar)(t2*10);
/*      if(b>127)
    {
        sg=1;
        temp=~temp;
        temp=temp+1;
        if(a==0x00)
            b=b+1;
        a_low=a&0x0f;
        t2=a_low*5/80;
        t1=(uchar)(t2*10);
        a=a>>4;
        b=b<<4;
        b=b&0x70;//把b中的最高位符號位置0
        t=b|a;
        t=t*5/80;
    }
    else
    {
        sg=0;
        a_low=a&0x0f;
        t2=a_low*5/80;
        t1=(uchar)(t2*10);
        a=a>>4;
        b=b<<4;
        b=b&0x70;
        t=b|a;
        t=t*5/80;
    }
*/  

//*************************輸入溫度小數(shù)部分
    write_com(0x80+0x0d);
    write_data(0x30+t1);
//*************************輸入溫度整數(shù)部分
    write_com(0x80+0x0a);
    write_data(0x30+t/10);
   
    write_com(0x80+0x0b);
    write_data(0x30+t%10);

//  int_();
}
//顯示數(shù)據(jù)函數(shù)
void dentify_key(uchar key)
{
        
        if(key>=0&&key<=9)
        {
            write_data(tablenum2[key]);
        }
}
//*************************顯示固定數(shù)據(jù)
void solid_data(void)
{
//*************************寫第一行顯示數(shù)據(jù)
    write_com(0x80);
    for(num=0;num<ActualTemp_worth;num++)
    {
        write_data(table[num]);
        delay(1);
    }

//*************************打印溫度小數(shù)點以及攝氏度" °"
    write_com(0x80+0x0c);
    write_data(0x2e);//打印小數(shù)點,'0x2e'為小數(shù)點的ASCII碼
    write_com(0x80+0x0e);
    for(num=0;num<2;num++)
    {
        write_data(table2[num]);
        delay(1);
    }

//*************************寫第二行顯示數(shù)據(jù)
    write_com(0x80+0x40);
    for(num=0;num<TempSet_worth;num++)
    {
        write_data(table1[num]);
        delay(1);
    }
}

//*************************矩陣鍵盤掃描函數(shù)
uchar keyscan()
{
//*************************矩陣鍵盤第一列掃描
    P2=0xfe;
    temp1=P2;
    temp1=temp1&0xf0;
    if(temp1!=0xf0)
    {
        delay(10);//延時消斗
        temp1=P2;
        temp1=temp1&0xf0;
        while(temp1!=0xf0)
        {
            sk=sk+1;//有按鍵按下標(biāo)志
            temp1=P2;
            switch(temp1)
            {
                case 0xee:key=0;break;
                case 0xde:key=4;break;
                case 0xbe:key=8;break;
            }
            while(temp1!=0xf0)
            {
                temp1=P2;
                temp1=temp1&0xf0;
            }      
        }
    }
//*************************矩陣鍵盤第二列掃描
    P2=0xfd;
    temp1=P2;
    temp1=temp1&0xf0;
    if(temp1!=0xf0)
    {
        delay(10);
        temp1=P2;
        temp1=temp1&0xf0;
        while(temp1!=0xf0)  
        {   
            sk=sk+1;//有按鍵按下標(biāo)志
            temp1=P2;
            switch(temp1)
            {
                case 0xed:key=1;break;
                case 0xdd:key=5;break;
                case 0xbd:key=9;break;
            }
            while(temp1!=0xf0)
            {
                temp1=P2;
                temp1=temp1&0xf0;
            }           
        }
    }
//*************************矩陣鍵盤第三列掃描
    P2=0xfb;
    temp1=P2;
    temp1=temp1&0xf0;
    if(temp1!=0xf0)
    {
        delay(10);
        temp1=P2;
        temp1=temp1&0xf0;
        while(temp1!=0xf0)  
        {
            temp1=P2;
            sk=sk+1;//有按鍵按下標(biāo)志
            switch(temp1)
            {
                case 0xeb:key=2;break;
                case 0xdb:key=6;break;
                case 0xbb:key=10;break;
            }
            while(temp1!=0xf0)
            {
                temp1=P2;
                temp1=temp1&0xf0;
            }           
        }
    }
//*************************矩陣鍵盤第四列掃描
    P2=0xf7;
    temp1=P2;
    temp1=temp1&0xf0;
    if(temp1!=0xf0)
    {
        delay(10);
        temp1=P2;
        temp1=temp1&0xf0;
        while(temp1!=0xf0)
        {
            temp1=P2;
            sk=sk+1;//有按鍵按下標(biāo)志
            switch(temp1)
            {
                case 0xe7:key=3;break;
                case 0xd7:key=7;break;
                case 0xb7:key=11;break;
            }
            while(temp1!=0xf0)
            {
                temp1=P2;
                temp1=temp1&0xf0;
            }
            
        }
    }
   
    return (key);   
}

//*************************中斷函數(shù)
void ex_enter() interrupt 0
{
    c=1;//表明已進(jìn)入中斷
    delay(100);
    write_com(0x80+0x4c);
    for(num=0;num<4;num++)//在按下設(shè)置后清屏設(shè)置部分的數(shù)據(jù)
    {
        write_data(0x20);
    }
    ADD=1;
    SUB=1;
    write_com(0x80+0x49);
    write_com(0x0f);//開光標(biāo)并閃爍
   
    sk=0;
    ex0_enter=1;//外部中斷0中斷復(fù)位
    SIG=0;
    write_com(0x80+0x49);
    delay(100);//******************可能是因為剛剛按設(shè)置鍵的時候,由于單片機(jī)速度過快,進(jìn)入中斷后還沒
               //******************釋放按鍵,導(dǎo)致進(jìn)入do...while語句,使得sk值迅速變?yōu)?;
               //******************因此在此加一延時,可以防止這種情況發(fā)生。                             
    do
    {
        sk=0;
        made_temp=temp2=keyscan();          //sk自加已在keyscan函數(shù)中實現(xiàn)
    }while((sk!=1)||(temp2==10||temp2==11));//檢測按鍵是否是設(shè)置鍵,如是設(shè)置鍵,繼續(xù)掃描
    if(sk!=0)//打印數(shù)據(jù)
    {
        for(num=0;num<sk;num++)
        dentify_key(temp2);
    }
    made_temp=made_temp*10;

    sk=0;
    delay(100);//******************作用于上面相同
    do
    {
        sk=0;
        made_temp1=temp2=keyscan();//sk自加已在keyscan函數(shù)中實現(xiàn)
    }while((sk!=1)||(temp2==10||temp2==11));

    if(sk!=0)
    {
        for(num=0;num<sk;num++)
        dentify_key(temp2);
    }
   
    made_temp=made_temp+made_temp1;
    write_com(0x0c);
    sk=0;
    delay(100);
    do                  //***************檢測確定按鍵
    {
        sk=0;
        temp2=keyscan();//sk自加已在keyscan函數(shù)中實現(xiàn)
    }while((sk!=1)||(temp2!=11));
    delay(50);
    SIG=1;
   
        if(sk!=0)
        {
            if((t+1)>made_temp)
            {
                ADD=1;
                SUB=0;
                write_com(0x80+0x4c);
                for(num=0;num<3;num++)
                    write_data(table4[num]);
            }
            else
            {   
                SUB=1;
                ADD=0;
                write_com(0x80+0x4c);
                for(num=0;num<3;num++)
                    write_data(table3[num]);            
            }
        }
   
}

溫度控制系統(tǒng) 包含 C語言程序 protues仿真圖.zip

208.33 KB, 下載次數(shù): 79, 下載積分: 黑幣 -5

回復(fù)

使用道具 舉報

ID:1018243 發(fā)表于 2022-4-13 23:55 來自手機(jī) | 顯示全部樓層
有沒有他的電路圖,或者程序的詳細(xì)解說
回復(fù)

使用道具 舉報

ID:1022036 發(fā)表于 2022-4-27 10:07 | 顯示全部樓層
可以來個上下限報警
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 久久久久国产一区二区三区 | 亚洲天堂日韩精品 | 久久av网 | 国产在线麻豆精品入口 | 国产ts人妖一区二区三区 | 夜夜摸天天操 | 澳门永久av免费网站 | 午夜极品| 亚洲国产精品99久久久久久久久 | 一级黄色片网址 | 精品国产亚洲一区二区三区大结局 | 精品国产欧美一区二区 | 久久精品一区二区 | 国产成人精品一区二区三 | 91精品国产91久久久久久 | 在线精品一区二区 | 亚洲精品久久久蜜桃网站 | 成人精品免费视频 | 日韩精品一区二区在线 | 国产精品久久久 | 国产精品一区二区av | 91在线精品一区二区 | 综合九九 | 4hu最新网址 | 激情欧美一区二区三区中文字幕 | 亚洲精品高清视频 | 中文字幕 亚洲一区 | 久久免费精品视频 | 亚洲成人自拍 | 久久99精品久久久久 | 久草色播 | 99久久婷婷国产综合精品 | 日本a级大片 | 国内精品视频在线观看 | 久久日韩精品一区二区三区 | 自拍中文字幕 | 成人深夜福利 | 亚洲 中文 欧美 | 高清欧美性猛交 | 久久高清精品 | 一区二区三区四区在线视频 |