專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

基于51單片機(jī)的天氣溫度報(bào)警系統(tǒng)(溫度可顯示正負(fù))

作者:佚名   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2013年10月16日   【字體:


基于AT89C51的天氣溫度報(bào)警系統(tǒng),采用Protues仿真。

元件:

DS1302時(shí)鐘芯片

DS18B20溫度傳感器 

LM016L(1602)液晶 

AT89C51單片機(jī)

LED燈若干 

蜂鳴器一只 用于報(bào)警 本人不寫(xiě)這個(gè)報(bào)警程序了  其實(shí)挺簡(jiǎn)單的

我只貼出部分主要的代碼

完整源代碼請(qǐng)到:   http://blog.sina.com.cn/u/2311964960(內(nèi)附圖片)

或直接下載: LSD.c (7.4 KB, 下載次數(shù): 72)

/*初始化DS18B20*/

void Init_DS18B20()
{               //初始化DS18B20必須先給DS18B20一個(gè)復(fù)位脈沖,接收到復(fù)位脈沖后DS18B20會(huì)返回一個(gè)存在脈沖
DQ=1;        //DQ先置高電平
_nop_();       //延時(shí)
_nop_();
DQ=0;      //DQ置低電平(拉低總線),開(kāi)始初始化
delayus(60);    //DQ置低電平后必須延時(shí)至少480us,此處延時(shí)600us
DQ=1;      //然后DQ置高電平(釋放總線)
delayus(3);     //釋放總線后要求延時(shí)15-60us,此處延時(shí)30us
flag=DQ;     //讀取DQ并付值flag,如果flag為0,表示返回了一個(gè)存在脈沖,初始化完成。相反失敗
delayus(20);
}

/*讀取DS18B20中的scrathpad一個(gè)字節(jié)*/
uchar read_scratchpad()
{
uchar i=0;
for (i=8;i>0;i--)
{
  DQ=1;        //DQ位拉高
  _nop_();     //延時(shí)1us秒
  DQ = 0;                    // DQ置0拉低總線
  dat>>=1;       //左移一位
  delayus(1);     //延時(shí)1us-15us,此處延時(shí)10us
  DQ = 1;                     // DQ置1釋放總線
  delayus(1);     //延時(shí)10us
  if(DQ==1){dat|=0x80;}  //采樣
  else{dat|=0x00;}
  delayus(5);      //延時(shí)50us
}
return dat;
}

/*向DS18B20中寫(xiě)入一個(gè)字節(jié),寫(xiě)ROM指令用*/
void write_command(uchar com)
{
uchar i=0;
uchar num;
for (i=8; i>0; i--)
{
  DQ=1;    //先將DQ置1;
  _nop_();   //延時(shí)
  DQ = 0;    //DQ置0,拉低總線
  num = com&0x01;   //讀取指令最低位
  if(num==1)     //如果為1
  {
   delayus(1);  //要求先延時(shí)1-15us,此處延時(shí)10us
   DQ=1;    //然后釋放總線
   delayus(4);    //延時(shí)大概45us,此處延時(shí)40us
  }else     //如果為0
   {
    delayus(6);   //要求延時(shí)60-120us,此處延時(shí)60us
    DQ=1;    //然后DQ置1釋放總線
    delayus(1);   //延時(shí)10us
   }
  com>>=1;
}
delayus(1);
}

/*溫度轉(zhuǎn)換*/
void Temperature_conversion()
{
Init_DS18B20();  //初始化DS18B20
write_command(0xCC); // 讀取ROM中64-bit code
write_command(0x4E); // 寫(xiě)暫存器,向暫存器中的TH、TL和configuration Register中寫(xiě)數(shù)據(jù)
write_command(0x50);//  向TH Register位寫(xiě)入數(shù)據(jù)
write_command(0x00);//向TL Register位寫(xiě)入數(shù)據(jù)
write_command(0x7F);//向configuration Register寫(xiě)入數(shù)據(jù)
delay(10);
Init_DS18B20();
write_command(0xCC); // 跳過(guò)讀序號(hào)列號(hào)的操作
write_command(0x44); // 啟動(dòng)溫度轉(zhuǎn)換
delay(10);
Init_DS18B20();//
write_command(0xCC); //跳過(guò)讀序號(hào)列號(hào)的操作
write_command(0xBE); //讀取溫度寄存器等(共可讀9個(gè)寄存器) 前兩個(gè)就是溫度
}

/*向16602寫(xiě)入指令*/
void write_com_1602(uchar com)
{
lcdrs=0;
lcdrw=0;
P3=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/*從1602讀取數(shù)據(jù)*/
void write_data_1602(uchar date)
{
lcdrs=1;
lcdrw=0;
P3=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}

/*判斷溫度正負(fù)*/
void checkMSB(uchar ta)
{
if(ta==0x07)
{
  write_com_1602(0x80+0x48);
  write_data_1602(0x20);
  TN=MSB*16+LSB/16;
  TD=(LSB%16)*10/16;
  if(TN>=TH){P1=~P1;}     //如果溫度設(shè)置的超出上限,LED閃爍
  else{P1=0xFF;}
}else{
  write_com_1602(0x80+0x48);
  display_minus();
  LSB=~LSB+1;
  MSB=~MSB;
  TN=MSB*16+LSB/16;
  TD=(LSB%16)*10/16;
  P1=~P1;    //如果溫度超出設(shè)置的下限(小于0),LED閃爍
}
}

/*向DS1302寫(xiě)數(shù)據(jù),分別寫(xiě)入地址和指令*/
void write_com_1302(uchar add,com)
{
uchar i;
CE=1;
for(i=0;i<8;i++)
{
  SCLK=0;
  IO=add&0x01;
  add>>=1;
  SCLK=1;
}
for(i=0;i<8;i++)
{
  SCLK=0;
  IO=com&0x01;
  com>>=1;
  SCLK=1;
}
SCLK=0;
CE=0;
}
/*從DS1302中讀數(shù)據(jù),但須先寫(xiě)入地址*/
uchar read_data_1302(uchar add)
{
uchar Data,i;
CE=1;
for(i=0;i<8;i++)
{
  SCLK=0;
  IO=add&0x01;
  add>>=1;
  SCLK=1;
}
for(i=0;i<8;i++)

  SCLK=0;
  Data>>=1;
  if(IO==1)Data|=0x80;
  SCLK=1;
  _nop_();
}
SCLK=0;
CE=0;
return Data;
}
/*將從DS1302中讀到的數(shù)據(jù)換化為10進(jìn)制*/
uchar changenum(uchar num)
{
uchar TH,TL,new_num;                 
TH=num&0xF0;
TH>>=4;
TH*=10;
TL=num&0x0F;
new_num=TH+TL;
return new_num;
}
void main()
{
while(1)
{
  Temperature_conversion(); //溫度轉(zhuǎn)換
  LSB=read_scratchpad();  //讀取LSB位數(shù)據(jù)
  MSB=read_scratchpad();  //讀取MSB位數(shù)據(jù)
  TH=read_scratchpad();  //讀取TH Register數(shù)據(jù)
  TL=read_scratchpad();  //讀取TL Register數(shù)據(jù)
  CR=read_scratchpad();  //讀取Configuration Register數(shù)據(jù)
  TA=MSB|0x07;  //按位與,從MSB位判斷溫度正負(fù)
  checkMSB(TA);   //判斷溫度正負(fù)
  write_com_1602(0x80+0x49); 
  display_temp1(TN);
  display_dot();
  display_temp2(TD);
  display_cent();
  write_com_1602(0x80);
  YY=read_data_1302(0x8D);
  YY=changenum(YY);
  display_temp3(YY);
  display_minus();
  MM=read_data_1302(0x89);
  MM=changenum(MM);
  display_temp3(MM);
  display_minus(); 
  DD=read_data_1302(0x87);
  DD=changenum(DD);
  display_temp3(DD);
  write_data_1602(0x20);
  write_data_1602(0x20);
  write_data_1602(0x20);
  HH=read_data_1302(0x85);
  HH=changenum(HH);
  display_temp3(HH);
  display_minus();
  MIN=read_data_1302(0x83);
  MIN=changenum(MIN);
  display_temp3(MIN);
  WEEK=read_data_1302(0x8B)-1;
  write_com_1602(0x80+0x45);
  write_data_1602(digit[WEEK]);
  //SEC=read_data_1302(0x81);
  //SEC=changenum(SEC);
  //display_temp3(SEC);
  }
}

 

關(guān)閉窗口

相關(guān)文章