专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

可调上下限温度报警器

作者:jiuded54   来源:本站原创   点击数:  更新时间:2010年07月12日   【字体:

     此程序是在上一个程序进行修改而来,把年月日删除,替换为可调温度上下限。

     带有可调时间星期功能,按键发声功能,手动设定温度上下限功能,温度报警功能,适用于AT89S52芯片。芯片内存剩余3.8K。 

    可扩展功能:闹钟。


 

                                程序
#include"reg51.h"
#define uchar unsigned char 
#define uint unsigned int 


   sbit BEEP=P3^7;    //// 定义蜂鸣器口

   unsigned char L,H;     //// 定义高低温度变量


/////////////////////////////////////////////////////////////////////////////////////////////////

 /**********报警声音**************/

 void bi(uint t)
   {
    int c,n;
    for(c=0;c<t;c++)
    {
     for(n=0;n<50;n++);
     BEEP=~BEEP;      //按位取反BEEP
    }
 //return(t);
   }

 


///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////


/**********18b20温度程序**********/ 

   sbit DQ=P3^6;       //定义温度数据口
    int xs;      //定义小数 
   unsigned int temp,temp1,temp2;  //定义温度转换变量     


 //////////////////////////////////////////////////////////////////////////////////////////////

   /*********18B20延时程序************/

  void delay_18B20(unsigned int i)
     {
      while(i--);
     }

//////////////////////////////////////////////////////////////////////////////////////////////

/*********ds18b20初始化函数*********/

void Init_DS18B20(void)  
   {
      unsigned char x=0;
      DQ = 1;          //DQ复位 ds18b20通信端口 
      delay_18B20(8);  //稍做延时
      DQ = 0;          //单片机将DQ拉低 
      delay_18B20(80); //精确延时 大于 480us
      DQ = 1;          //拉高总线
      delay_18B20(4);
      x=DQ;            //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
      delay_18B20(20);
   }

///////////////////////////////////////////////////////////////////////////////////////////

/********ds18b20读一个字节**********/

unsigned char ReadOneChar(void)
   {
     unsigned char i=0,dat = 0;
     for (i=8;i>0;i--)
     {
       DQ = 0;    //高电平拉成低电平时读周期开始
       dat>>=1;
       DQ = 1;    //给脉冲信号
       if(DQ)
       dat|=0x80;  
       delay_18B20(4);
     }
     return(dat);
   }

//////////////////////////////////////////////////////////////////////////////////////////

/*************ds18b20写一个字节****************/

void WriteOneChar(unsigned char dat)
 {
   unsigned char i=0;
   for (i=8; i>0; i--)
   {
     DQ = 0;         //从高电平拉至低电平时,写周期的开始
     DQ = dat&0x01;  //数据的最低位先写入
     delay_18B20(5); //60us到120us延时
     DQ = 1;        
     dat>>=1;        //从最低位到最高位传入
   }
 }


////////////////////////////////////////////////////////////////////////////////////////////

/**************读取ds18b20当前温度************/

void ReadTemperature(void)
 {
    unsigned char a=0,b=0,t=0;

    Init_DS18B20 ( );
    WriteOneChar ( 0xCC );       // 跳过读序号列号的操作
    WriteOneChar ( 0x44 );       // 启动温度转换
    delay_18B20  ( 100  );       // this message is wery important
    Init_DS18B20 ( );
    WriteOneChar ( 0xCC );       //跳过读序号列号的操作
    WriteOneChar ( 0xBE );       //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
    delay_18B20  ( 100  );
    a=ReadOneChar( );            //读取温度值低位
    b=ReadOneChar( );            //读取温度值高位

    temp1 = b<<4;                //高8位中后三位数的值
    temp1+= ( a&0xf0 )>>4;       //低8位中的高4位值加上高8位中后三位数的值   temp1室温整数值
    temp2 = a&0x0f;              //小数的值
    temp  = ( ( b*256+a ) >>4 ); //当前采集温度值除16得 实际温度值    zhenshu    
    xs=temp2*0.0625*10;          //小数位,若为0.5则算为5来显示   xs小数    xiaoshu      
 }


/////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////

 


/*********************1602液晶程序********************/
 

/******定义液晶控制口*******/ 
 
    sbit lcdrs=P2^5;   //定义液晶三个控制口
    sbit lcdrw=P2^6;
    sbit lcden=P2^7;

    sbit K1=P3^0;     //定义三个开关
 sbit K2=P3^1;
 sbit K3=P3^2;
 /////////////////////////////////////////////////////////////////////////////////////////////////

/******定义变量*******/
  
uchar count,shi,fen,miao,xq,K1num;   //定义时间程序里所需要的变量


/////////////////////////////////////////////////////////////////////////////////////////////////

/******定义数组*******/

  uchar code table [ ]= "TH:38 TL:25 XQ:7";    //液晶界面显示的内容
  uchar code table1[ ]= "23:59:55    .  C";

//////////////////////////////////////////////////////////////////////////////////////////////////

/******延时程序*******/ 
 
  void delay(uint m)    //液晶延时程序
     {
        uint i,j;
      for(i=m;i>0;i--)
     for(j=110;j>0;j--);
     }
///////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////// 

/**********写指令*************/ 
  void write_com(uchar com)
      {
         lcdrs=0;
         lcdrw=0;
         lcden=0;
         P0=com;
         delay(5);
         lcden=1;
         delay(5);
         lcden=0;
      }

 /////////////////////////////////////////////////////////////////////////////////////

/************写数据*************/ 

  void write_data(uchar date)
      {
         lcdrs=1;
         lcdrw=0;
         lcden=0;
         P0=date;
         delay(5);
         lcden=1;
         delay(5);
         lcden=0;
      }


///////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

 /***************液晶显示程序***************/  
  
   /*********时分秒数的分离**********/ 
    
  void write_sfm(uchar add,uchar date)
      { 
        uchar shi,ge;     //分离数字,如35,分成3和5  
     shi=date/10;     
      ge=date%10;     
        write_com  ( 0x80+0x40+add );    
        write_data ( 0x30+shi      );       
     write_data ( 0x30+ge       );       
      }

 //////////////////////////////////////////////////////////////////

/**********星期***********/ 

   void write_xq(uchar add1,uchar date1)
       {
          uchar ge;      //星期只需要一个数字显示   
       ge=date1%10;    
          write_com  ( 0x80+add1 );    
        write_data ( 0x30+ge   );      
       }
  

  ////////////////////////////////////////////////////////////////
 
 /************高温低温数的分离************/

  void write_HL(uchar add2,uchar date2)
     {
         uchar shi,ge;   
      shi=date2/10;     
       ge=date2%10;      
         write_com(0x80+add2);     
      write_data(0x30+shi);  
      write_data(0x30+ge);   
     }
 
  /////////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////////
 
 /***************按键调时程序***************/ 
   
   void keycan()
    {
         /**********功能选择**********/ 
      if( K1==0    ) { K1num++; delay(2); if( K1==0 ) {  while(!K1);bi(300);

     if( K1num==1 ) { TR0=0; write_com ( 0x80+0x40+7 ); write_com(0x0f); }
   if( K1num==2 ) { write_com ( 0x80+0x40+4 ); }
   if( K1num==3 ) { write_com ( 0x80+0x40+1 ); }
   if( K1num==4 ) { write_com ( 0x80+15 );  }
   if( K1num==5 ) { write_com ( 0x80+10 );  }
   if( K1num==6 ) { write_com ( 0x80+4 );  }
   if( K1num==7 ) { K1num=0; write_com(0x0c); TR0=1; } 
       } 
      }

/////////////////////////////////////////////////////////////////////////////////////////////////

         /*********功能加*********/ 
     
       if( K1num!=0 ) {
         if( K2==0    ) { delay(2);
         if( K2==0    ) { while(!K2);bi(300);

      if( K1num==1 ) { miao++;   if( miao==60 )  miao=0;  write_sfm ( 6,miao);  write_com ( 0x80+0x40+7 ); }
         if( K1num==2 ) { fen++;    if(  fen==60 )   fen=0;  write_sfm ( 3,fen );  write_com ( 0x80+0x40+4 ); }
      if( K1num==3 ) { shi++;    if(  shi==24 )   shi=0;  write_sfm ( 0,shi );  write_com ( 0x80+0x40+1 ); }
      if( K1num==4 ) { xq++;     if(   xq==8  )    xq=1;  write_xq  (15,xq  );  write_com ( 0x80+15 ); }
   if( K1num==5 ) {  L++;     if(    L==100)     L=0;  write_HL( 9,L   );  write_com ( 0x80+10 ); }
   if( K1num==6 ) {  H++;     if(    H==100)     H=0;  write_HL( 3,H   );  write_com ( 0x80+4  ); }
    }
      }
     } 
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
         /**********功能减************/ 
      if(K1num!=0)  {
      if(K3==0   )  { delay(2);
      if(K3==0   )  { while(!K3); bi(300);

      if( K1num==1 ) { miao--;   if( miao==-1 )  miao=59;  write_sfm ( 6, miao);  write_com ( 0x80+0x40+7 ); }
         if( K1num==2 ) {  fen--;   if(  fen==-1 )  fen =59;  write_sfm ( 3, fen );  write_com ( 0x80+0x40+4 ); }
      if( K1num==3 ) {  shi--;   if(  shi==-1 )  shi =23;  write_sfm ( 0, shi );  write_com ( 0x80+0x40+1 ); }
         if( K1num==4 ) {   xq--;   if(   xq==0  )  xq  = 7;  write_xq  (15, xq  );  write_com ( 0x80+15 ); }
   if( K1num==5 ) {    L--;   if(    L==-1  )    L=99;  write_HL  ( 9,L    );  write_com ( 0x80+10 ); }
   if( K1num==6 ) {    H--;   if(    H==-1  )    H=99;  write_HL  ( 3,H    );  write_com ( 0x80+4  ); }
    }
      }
     }
    }

////////////////////////////////////////////////////////////////////////////////////////////////////

/*************初始化**************/
 
  void init()
      {
        uchar num;  //定义一个变量num,用于下面数组的初始化//  
        lcden=0;
        write_com ( 0x38 );
        write_com ( 0x0c );   //不显示光标  
        write_com ( 0x06 );   //光标向右边自动移位  
        write_com ( 0x01 );   //清屏  

        shi=23; fen=59; miao=55; 
         xq=7; H=38;L=25;

        write_com ( 0x80 );     
               for( num=0; num<16; num++ )
                  { write_data( table[num]  );  delay(10); }

        write_com ( 0x80+0x40 );       
               for( num=0; num<16; num++ )
                  { write_data( table1[num] );  delay(10); }


 ///////////////////////////////////////////////////////////////////////////////////////
/********定时器初始化*************/ 

          TMOD=0x01; //定义定时器0,工作方式1  
          TH0=(65536-50000)/256;   //高8位  
          TL0=(65536-50000)%256;   //低8位  
          EA=1;     //开全局中断  
          ET0=1;    
          TR0=1;    //打开定时器  
        }

 

///////////////////////////////////////////////////////////////////////////////////////////////////////

/***********定时器中断函数************/
 
  void timer0() interrupt 1
   {
     TH0=(65536-50000)/256;
     TL0=(65536-50000)%256;
     count++;
   if( count==20 ) { count=0;    miao++;
   if(  miao==60 ) {  miao=0;     fen++; }  
   if(   fen==60 ) {   fen=0;     shi++; }  
   if(   shi==24 ) {   shi=0; xq++;
   if(    xq==8  ) {    xq=1;    }       }      
  }
   }

 


///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

/*****************************************/


uchar code mytab[8]={0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00};
/*  设定显示位置           
/**************************************/
void lcd_pos(uchar pos)
{                          
  write_com(pos | 0x80) ;  //数据指针=80+地址变量
}

  /////////////////////////////////////////////////////////////////////////////
/*自定义字符写入CGRAM   
/*********************************/
void  writetab()  
{  
    unsigned char i ;
    write_com(0x40) ;            //写CGRAM
    for (i = 0 ; i< 8 ; i++)       
    write_data(mytab[ i ]) ;        
}

 

/////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

void wendu()  /////温度显示程序/////   
 {
     
        writetab(   ) ;          //自定义字符写入CGRAM
        delay   ( 5 ) ;
        lcd_pos   ( 0x4e ) ;      //显示圈圈
        write_data( 0x00 ) ;    //显示自定义字符 
        write_com ( 0x0c );
        ReadTemperature();    
         
        write_com  ( 0x80+0x40+10 ); 
        write_data ( 0x30+temp/10 );

        write_com  ( 0x80+0x40+11 );
        write_data ( 0x30+temp%10 );
  
        write_com  ( 0x80+0x40+13 );
        write_data ( 0x30+xs%10   );


         /////时间显示地址/////  
        write_sfm( 6,miao );
        write_sfm( 3,fen  );
     write_xq (15,xq   ); 
        write_sfm( 0,shi  );
  } 


//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////

   //////温度报警程序//////
  void baojing()
   {
  
     if(H==temp)
    {
      bi(500);
       }
      if(L==temp)
    {
      bi(500);
       }
   }


 //////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
 /***************主函数***************/ 
   void main()
     {
        init();
        while(1)  
        {
  keycan();
        wendu(); 
  baojing();
     }
    }


 
关闭窗口

相关文章