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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

數字溫度表,帶原理圖

[復制鏈接]
跳轉到指定樓層
樓主
ID:126620 發表于 2016-6-14 09:35 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
#include<reg52.h>
#include <intrins.h>
#include<math.h>
#define uint unsigned int
#define uchar unsigned char
#define LCD P0

sbit redLED=P2^7;//位定義報警顯示燈
sbit xuanze=P3^3;//位定義選擇按鍵
sbit up=P3^4;//位定義極限加
sbit down=P3^5;//位定義極限減

int th=20,tl=5,thh=0,tll=0;//初始上限值和下限值
uchar i,num=0;//定義變量
/*******************************************************
            延時函數
*******************************************************/
void delay(uint z)
{
  uint x,y;
    for (x=z;x>0;x--)
     for(y=110;y>0;y--);

}

/*************************************************
             LCD部分
***************************************************/
sbit rs=P2^0;
sbit rw=P2^1;
sbit E=P2^2;
uchar tmp5[]="temp:";
uchar tmp6[]="^C";
uchar code tab1[]="TH:";
uchar code tab2[]="TL:";
write_com(uchar com)//LCD寫地址函數
{
  rs=0;
  rw=0;
  E=1;
  LCD=com;
  delay(5);
  E=0;
  return 0;  
}
write_data(uchar dat)//LCD寫數據函數
{
  rs=1;
  rw=0;
  E=1;
  LCD=dat;
  delay(5);  
  E=0;
  return 0;
}
init_lcd()//LCD初始化函數
{

  write_com(0x38);//16*2顯示,5*7點陣,8位數據
  write_com(0x0c);//設置為顯示開,關光標,不閃爍
  write_com(0x06);//寫操作后,AC自動加1
  write_com(0x01); //LCD清屏



   write_com(0x80+0x01);//LCD第一行第二個位置起顯示"TH:"
   for(i=0;i<3;i++)
   {  
    write_data(tab1);
        
   }

   write_com(0x80+9);//LCD第一行第10個位置起顯示"TL:"
   for(i=0;i<3;i++)
   {
    write_data(tab2);
   }

   write_com(0x80+0X40+0x00);//LCD第二行開始出顯示"Temp:"
   for(i=0;i<5;i++)
   {

     write_data(tmp5);
   }

write_com(0x80+0X40+10);//顯示溫度的單位
   for(i=0;i<2;i++)
   {

     write_data(tmp6);
   }

//以下是溫度的上限和下限初始化顯示部分
                 write_com(0x80+0x00+4);
           write_data('+');
                 write_data(th/10+0x30);
              write_data(th%10+0x30);
               write_com(0x80+0x00+12);
                 write_data('+');
                   write_data(tl/10+0x30);
                     write_data(tl%10+0x30);
                                         return 0;
}
/*********************************************************
               DS18B20部分
**********************************************************/
uchar timecount;//定義中斷次數
uchar test0,test1,test;//溫度值變量
uchar a1,a2,a3;//溫度整數部分的十位,個位和小數部分的十分位
uchar readdate[2];//定義數組,用來暫存讀取的溫度值
sbit DQ=P3^0;//DS18B20數據口
bit sflag;//定義溫度的正負標志位
void delay1(uint i)//短延時函數
{
while(i--);
}
void reset()//DS18B20的復位函數
{
uchar x=0;
DQ=1;//使總線為高電平
delay1(8);//延時
DQ=0;//使總線為低電平
delay1(80);//延時,大于480us
DQ=1;//使總線為高電平
delay1(14);//延時,等待DS18B20回應低電平
x=DQ;//將DS18B20的回應讀到變量x,用于判斷復位是否成功
delay1(20);//延時一段時間結束
}


void writecmd(uchar cmd)//DS18B20的寫字節函數
{
uchar i=0;//定義位循環變量
for(i=8;i>0;i--)//循環8次
{
  DQ=0;//總線拉低
  DQ=cmd&0x01;//將發送字節的最低位送到總線
  delay1(5);//延時(30us),等待DS18B20取走總線數據
  DQ=1;//總線拉高
  cmd>>=1;//將待發送的字節右移后,繼續發送
}
}

uchar readdat()//DS18B20的讀字節函數
{
uchar i=0;//定義位循環變量
uchar temp=0;//定義暫存變量
for(i=8;i>0;i--)//循環8次
{
   DQ=0;//總線為低電平
   temp>>=1;//暫存變量右移
   DQ=1;//總線拉高,執行如下的讀操作
   if(DQ)//如果DS18B20輸出高電平
   temp|=0x80;//將暫存變量的最高位置1
   delay1(4);//延時一段時間
}
return temp;//程序結束后,將暫存變量返回調用程序
}

/***************************************************
         按鍵設置上線溫度和下限溫度值函數

****************************************************/
void key()
{
if(xuanze==0)//如果選擇鍵按下
{delay(10);//延時消抖
if(xuanze==0)//如果按鍵還處于按下狀態
{   num++;//次數加1
  while(!xuanze);//等待按鍵抬起


        if(num==1)//如果按下選擇鍵的次數為1
         {
          TR0=0;//關閉中斷
          write_com(0x80+0x00+5);//光標移到第一行第七個位置
      write_com(0x0f);//設置為顯示開,開光標,閃爍
     }
    if(num==2)//如果按下選擇鍵的次數為2
         {
         write_com(0x80+0x00+13);//光標移到第一行第十五個位置
         }
    if(num==3)//如果按下選擇鍵的次數為3
        {
         num=0;//次數清零
         write_com(0x0c);//設置為顯示開,關光標,不閃爍
         TR0=1;//開中斷
        }
  }  
}
if(num!=0)//在選擇鍵按下時
{
  if(up==0)//如果極限加按鍵按下
{
  delay(10);//延時消抖
  if(up==0)//如果極限加按鍵仍處于按下狀態
  {
    while(!up);//等待按鍵抬起

   if(num==1)//如果選擇鍵按了一次
   {
      th++;//上線值加1
            if(th>=0)//如果上線值為正
                {thh=0;//計數清零
                 write_com(0x80+0x00+4);
                  write_data('+');//顯示正號
               write_com(0x80+0x00+5);
                    write_data(th/10+0x30);//顯示上限溫度值的十位
                 write_data(th%10+0x30);//顯示上限溫度值的個位
              }

                        if(th<0)
                         {
                           thh--;
                            write_com(0x80+0x00+4);
                                 write_data('-');//顯示正號
                              write_com(0x80+0x00+5);
                                   write_data(thh/10+0x30);//顯示上限溫度值的十位
                                write_data(thh%10+0x30);//顯示上限溫度值的個位
                                 }
     }

if(num==2)//如果選擇鍵按了兩次
  {
        tl++;//下限溫度值加1
        if(tl>=0)//如果下限溫度值為正
        {
      tll=0;//計數清零
           write_com(0x80+0x00+12); // 顯示正號
            write_data('+');//
             write_com(0x80+0x00+13);
              write_data(tl/10+0x30);//顯示下限溫度值的十位
               write_data(tl%10+0x30);//顯示下限溫度值的個位
            }
               
                if(tl<0)
                {
                   tll--;
                    write_com(0x80+0x00+12);
                         write_data('-');//顯示正號
                      write_com(0x80+0x00+13);
                           write_data(tll/10+0x30);//顯示上限溫度值的十位
                        write_data(tll%10+0x30);//顯示上限溫度值的個位
                   }
      }
   }
  }


if(down==0)//如果極限減按鍵按下
{
  delay(10);//延時消抖
  if(down==0)//如果按鍵仍處于按下狀態
{while(!down);//等待按鍵抬起
  if(num==1)//如果選擇鍵按了一次
  {
          th--;//上限溫度值減1
           if(th>=0)//如果上限溫度值為正
                {
                 write_com(0x80+0x00+4);  //顯示正號
                write_data('+');
                write_com(0x80+0x00+5);
                write_data(th/10+0x30);//顯示上限溫度值的十位
                write_data(th%10+0x30);//顯示上限溫度值的個位
                }
                if(th<0)//如果上限溫度值為負
                {thh++;//計數變量加1
                 write_com(0x80+0x00+4);  
                write_data('-');//顯示負號
               
                write_com(0x80+0x00+5);
                write_data(thh/10+0x30);//顯示上限溫度值的十位
                write_data(thh%10+0x30);//顯示上限溫度值的個位

         }

                }
        }
                        
        if(num==2)//如果選擇鍵按了兩次
        {
        tl--;//下限溫度值減1
             if(tl>=0)//如果下限溫度值為正
                {
                 write_com(0x80+0x00+12);  
                 write_data('+');//顯示正號

                 write_com(0x80+0x00+13);
             write_data(tl/10+0x30);//顯示下限溫度值的十位
         write_data(tl%10+0x30);//顯示下限溫度值的個位
                }
                if(tl<0)//如果下限溫度值為負
                {tll++;//計數變量加1
                 write_com(0x80+0x00+12);  
                write_data('-');//顯示負號
                write_com(0x80+0x00+13);   
                write_data(tll/10+0x30);//顯示下限溫度值的十位
                 write_data(tll%10+0x30);//顯示下限溫度值的個位
                }
     }

   }
}
}
/******************************************************
                報警函數
********************************************************/
sbit ddd=P1^0;
void baojing()
{
   if((sflag==0&(test>=th|test<=tl))|(sflag==1&-test<=tl))//如果測得的溫度值>=上限溫度值(TH)或<=下限溫度值(TL)
    {
     redLED=~redLED;//發光二極管閃爍
     delay(300);//延時
      }
else
{
  redLED=1;//否則發光二極管滅
}

}
/********************************************************
               主函數

********************************************************/
void main()
{
  init_lcd();//初始化LCD

  TMOD=0X01;//定時器0,方式1
  TH0=0X3C;//50ms溢出一次
  TL0=0XB0;
  TR0=1;//啟動定時器0
  ET0=1;//開定時器0
  EA=1;//開總中斷

  while(1)
   {
    key();//調用按鍵函數


    baojing();//調用報警函數

    }        
}

/************************************************************
          中斷函數
**************************************************************/
void timer0()   interrupt 1//定時器0中斷,中斷標號為1
{  
uint result;//
TH0=0X3C;
TL0=0XB0;
timecount++;//每中斷一次,timecount加1

if(timecount==20)//中斷定時達到1S,50ms*20=1s
{timecount=0;//timecount清零
  reset();//復位DS18B20
  writecmd(0xcc);//向DS18B20發送跳過ROM搜索命令
  writecmd(0x44);//啟動一次溫度轉換
  reset();//復位DS18B20
  writecmd(0xcc);//向DS18B20發送跳過ROM搜索命令
  writecmd(0xbe);//發送讀溫度的命令?
  readdate[0]=readdat();//讀溫度的低8位
  readdate[1]=readdat();//讀溫度的高8位

  sflag=0;//置負號標志為0
  if(( readdate[1]&0xf8)!=0x00)//如果是負溫度值,執行如下取補碼語句
{ sflag=1;
   readdate[1]=~ readdate[1];//高位取反碼
   readdate[0]=~readdate[0];//低位取反碼
   result=readdate[0]+1;//反碼加1
   readdate[0]=result;//將取補的高溫度值,送回數組
   if(result>255)//如果低8位有進位,則高8位加1
  {readdate[1]++;//
  }
}
test0=readdate[0];//低8位值賦予test0
test1=readdate[1];//高8位值賦予test1
test=((readdate[1]*256)+readdate[0])/16;//取出整數部分溫度值
test0=(test0|0x0f)/16;//取出小數部分溫度值

reset();//復位DS18B20
writecmd(0xcc);//向DS18B20發送跳過ROM搜索命令
writecmd(0x44);//啟動下次溫度測量
//以下是溫度值處理部分
write_com(0x80+0X40+0x05);

   if(sflag==1)
       write_data('-');//如果測得的溫度為負值,顯示負號
   else
        write_data('+');//如果測得的溫度為正值,顯示正號

       a1=(test/10)|0x30;//溫度整數部分的十位
       a2=(test%10)|0x30;//溫度整數部分的個位

   write_com(0x80+0X40+0x06);
   write_data(a1);//顯示溫度整數部分的十位
   write_data(a2);//顯示溫度整數部分的個位
   write_data('.');//顯示小數點
   a3=(test0/10)|0x30;//溫度小數部分的十分位
   write_data(a3);  //  顯示溫度小數部分的十分位
}
ddd=sflag;
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久91精品国产一区二区三区 | 中文字幕国产视频 | 国产成人99久久亚洲综合精品 | 国产91综合 | 国产精品久久久久久久久久久久冷 | 久久aⅴ乱码一区二区三区 91综合网 | 日韩精品一区二区三区在线播放 | 日本黄色的视频 | 亚洲视频观看 | 黄视频网站在线 | 射久久| 久草在线免费资源 | 亚洲色欧美另类 | 国产一二三视频在线观看 | 久久99精品久久 | 野狼在线社区2017入口 | 亚洲一区在线日韩在线深爱 | 精品一区二区三区中文字幕 | 成人片免费看 | 日本一区二区视频 | 国产精品久久久久久久久免费樱桃 | 久久久久国产一区二区 | 亚洲二区在线 | 国产ts一区 | 国产激情一区二区三区 | 日韩a | 国产91综合一区在线观看 | 国产精品视频一二三区 | 91亚洲国产成人久久精品网站 | 在线视频一区二区 | 超碰电影 | 综合二区| 日韩中文字幕 | 免费视频二区 | 91看片| 成人二区| 一区二区三区国产 | 成人免费视频一区二区 | 午夜影院毛片 | 亚洲二区在线 | 国产精品一区在线观看 |