找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3070|回复: 1
打印 上一主题 下一主题
收起左侧

基于51单片机的烟雾报警器

[复制链接]
跳转到指定楼层
楼主
ID:469980 发表于 2020-1-29 19:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本设计为烟雾报警器附带的有温度和日期的显示。需要的拿走。



#include<reg51.h>
#include<intrins.h>
#include"riqi.h"
#include"wendu.h"
#include"n5110.h"
#define uchar unsigned char
#define uint unsigned int
sbit K1=P3^4;
sbit K2=P3^5;
sbit K3=P3^3;
sbit K4=P3^6;
uchar count=0x00;
sbit cs=P1^0;
sbit sclk=P1^1;
sbit dat=P1^2;
sbit fe=P1^3;
sbit k5=P3^7;
sbit mada=P1^4;
uint mdat=0x00;
int tidai;
uchar SetState,SetPlace,m=1;
void Int0Configuration();
void LcdDisplay();
void display(uint temp);
uchar code riqishuzu[][16]={          //8*16                        日期数字
0x00,0xF8,0x04,0x02,0x02,0x04,0xF8,0x00,0x00,0x03,0x04,0x08,0x08,0x04,0x03,0x00,//0
0x00,0x04,0x04,0xFE,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x0F,0x08,0x08,0x00,0x00,//1
0x00,0x1C,0x02,0x02,0x82,0x62,0x1C,0x00,0x00,0x0C,0x0A,0x09,0x08,0x08,0x0C,0x00,//2
0x00,0x0C,0x02,0x22,0x22,0x52,0x8C,0x00,0x00,0x06,0x08,0x08,0x08,0x04,0x03,0x00,//3
0x00,0xC0,0x30,0x08,0x04,0xFE,0x00,0x00,0x00,0x01,0x01,0x09,0x09,0x0F,0x09,0x00,//4
0x00,0x7E,0x42,0x22,0x22,0x42,0x82,0x00,0x00,0x06,0x08,0x08,0x08,0x04,0x03,0x00,//5
0x00,0xF8,0x44,0x22,0x22,0x46,0x80,0x00,0x00,0x03,0x04,0x08,0x08,0x04,0x03,0x00,//6
0x00,0x0E,0x02,0xC2,0x32,0x0E,0x02,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,//7
0x00,0x1C,0xA2,0x42,0x42,0xA2,0x1C,0x00,0x00,0x07,0x08,0x08,0x08,0x08,0x07,0x00,//8
0x00,0x38,0x44,0x82,0x82,0x44,0xF8,0x00,0x00,0x00,0x0C,0x08,0x08,0x04,0x03,0x00,//9

};
unsigned char code font6_8[][6] =
{
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // sp           0
    { 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 },   // ,         1          
    { 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 },   // .         2      14
    { 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 },   // /        3                 15
    { 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E },   // 0        4                 16
    { 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 },   // 1        5           17
    { 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 },   // 2         6           18
    { 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 },   // 3        7                 19
    { 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 },   // 4        8                 20
    { 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 },   // 5        9                   21
    { 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 },   // 6        10                 22
    { 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 },   // 7        11                 23
    { 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 },   // 8         12                 24
    { 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E },   // 9        13                 25
    { 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 },   // :        14                 26
        { 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 },   // (         15          
    { 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 },   // )         16           
                                                                                                                                          
};

uchar code xingqishuzi[][12]={           //    供星期调用
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00,   //1
0x00,0x20,0x20,0x24,0x24,0x24,0x24,0x24,0x24,0x20,0x20,0x00,        //2
0x00,0x80,0x48,0x49,0x49,0x49,0x49,0x49,0x49,0x48,0x80,0x00,     //3
0x00,0xff,0xa1,0x91,0x8f,0x81,0x81,0x9f,0x91,0x91,0xff,0x00,         //4
0x00,0x80,0x81,0xc9,0xb9,0x8f,0x89,0x89,0xf9,0x81,0x80,0x00,        //5
0x00,0x44,0x24,0x14,0x04,0x05,0x04,0x14,0x24,0x44,0x00,0x00,    //6
0x00,0x00,0xff,0x89,0x89,0x89,0x89,0x89,0x89,0xff,0x00,0x00,        //7
       

};
void delay(uchar x)                                  
{
  uint i,j;
  for(j=x;j>0;j--)
  for(i=110;i>0;i--);
}

void lcdwritechar(uchar c)                     //显示英文字符
{
uchar line;
                              //数组的行号   c=34 ;   
for(line=0;line<7;line++)
{
lcdwritebyte(font6_8[c][line],1);
}
}
void xingqi(uchar x,uchar y,uchar e )
{
           uchar tqr;
     lcdsetxy(x,y);               
   for(tqr=0;tqr<12;tqr++)
   {
     lcdwritebyte(xingqishuzi[e][tqr],1);
         
   }

}
  void riqi()
{
           lcdsetxy(58,3);                             //温度的小数点
           lcdwritebyte(0x30,1);
        lcdsetxy(59,3);          
           lcdwritebyte(0x30,1);

        lcdsetxy(13,1);                 //:
    lcdwritechar(14);

        lcdsetxy(31,1);                        //:
    lcdwritechar(14);


        lcdsetxy(30,0);                        //     /
        lcdwritechar(3);
        lcdsetxy(52,0);                 //   /
        lcdwritechar(3);

          lcdsetxy(58,1);                         //(                61
        lcdwritechar(15);  
        lcdsetxy(76,1);                  //    )         79
        lcdwritechar(16);
}

void yingwenzifu(uchar x,uchar y,uchar h)                 //在x  y    处显示一个字符
{

           lcdsetxy(x,y);
    lcdwritechar(h);
}

void wendu_shuzi(uint x,uint y,int a)   //日期上显示占两行的数字
{
   uchar b,c;
   lcdsetxy(x,y);               
   for(b=0;b<8;b++)
   {
     lcdwritebyte(riqishuzu[a][b],1);
   }
   lcdsetxy( x,y+1);                 
   for(c=8;c<16;c++)
   {
            lcdwritebyte(riqishuzu[a][c],1);
   }
          
}
void  convdata(uchar i)//此时的i为ad转换后的值,在0-5v之间,
{
         uchar w=0;
  // i=i*100;    //把i精确到0.0;i在0-255之间,共5v,十个等级,每个等级0.5v,255/10=25.5取整25

     if(i>=0&&i<=3)                //        if(i>=0&&i<=3)
     {wendu_shuzi(60,4,0);                // 检测0-0.3v    5110显示0级
         fe=1;
         mada=1;
         }     

                          if(k5==0&&m==1)
                {               
                delay(10);
                if(k5==0&&m==1)
                {
                w=1;
                m=0;

                while(!k5);
        //        tqr=0;                  //定时器开始计时,当tmr=51   tmr=0;m=0;tqr=1        定时器不在计时
                }
                }
        if(k5==0&&m==0)
                {               
                delay(10);
                if(k5==0&&m==0)
                {
       

                w=0;

                m=1;
       
        //        tqr=0;                  //定时器开始计时,当tmr=51   tmr=0;m=0;tqr=1        定时器不在计时
                }
        while(!k5);
                }          
        if(i>3&&i<=225)
        {
          
         mada=0;

        if(mada==0&&m==1)
            fe=0;
    if(mada==0&&m==0&&w==1)
           {
                fe=1;

                  }       
       
                    
    if(i>3&&i<=25)                                 //         if(i>3&&i<=25)       
     {wendu_shuzi(60,4,1);}     //  0.3-0.5v     1级
    if(i>25&&i<=51)
       {wendu_shuzi(60,4,2);}    //   0.5-1v      2
    if(i>51&&i<=76)
       {wendu_shuzi(60,4,3);}     //  1-1.5v      3
    if(i>76&&i<=102)
        {wendu_shuzi(60,4,4);}     //  1.5-2v      4
     if(i>76&&i<=127)
        {wendu_shuzi(60,4,5);}     //  2-2.5v      5
      if(i>127&&i<=153)
        {wendu_shuzi(60,4,6);}     //  2.5-3v      6
     if(i>153&&i<=178)
       {wendu_shuzi(60,4,7);}     //  3-3.5v      7
     if(i>178&&i<=204)
       {wendu_shuzi(60,4,8);}     //  3.5-4v      8
     if(i>204&&i<=229)
       {wendu_shuzi(60,4,9);}     //  4-4.5v      9
     if(i>229&&i<=255)
       {
                wendu_shuzi(60,4,1);
                wendu_shuzi(69,4,0);;
                }     //  4.5-5v      10
                }

        }
uchar adc0832(uchar CH)    //(ucahr CH)
{
uchar i,test,adval;
     adval=0x00;
     test=0x00;
     sclk=0;
       dat=1;     //why dat=1;  dat should=0;
      _nop_();
      cs=0;
      _nop_();
      sclk=1;
      _nop_();

   if ( CH == 0x00 )      //通道选择
   {
       sclk = 0;
       dat = 1;      //通道0的第一位
       _nop_();
       sclk = 1;
       _nop_();
       sclk = 0;
       dat = 0;      //通道0的第二位
       _nop_();
       sclk = 1;
       _nop_();
    }
    else
    {
       sclk = 0;
       dat = 1;      //通道1的第一位
       _nop_();
       sclk = 1;
       _nop_();
       sclk = 0;
       dat = 1;      //通道1的第二位
       _nop_();
       sclk = 1;
       _nop_();
    }
       sclk=0;
       dat=1;
for(i=0;i<8;i++)
{
      _nop_();
      adval<<=1;
      sclk=1;
      _nop_();
      sclk=0;
  if(dat)
{
      adval|=0x01;

}
  else
      adval|=0x00;

}
for(i=0;i<8;i++)
{
      test>>=1;
      if(dat)
   {test|=0x80;}
    else
    test|=0x00;
    _nop_();
    sclk=1;
    _nop_();
    sclk=0;
  }
if(adval=test)   //如果输出一直为0 就去掉
   mdat=test;
   _nop_();
   cs=1;
   dat=1;
   sclk=1;
   return adval;
}


void main()
{
  unsigned char i;
    //delay(1);
          
        lcdinit();
        wendu_shuzi(42,2,0);    //0           最初温度显示为00.00
        wendu_shuzi(50,2,0);   //0
    wendu_shuzi(61,2,0);   //0
        wendu_shuzi(69,2,0);   //0          
           Int0Configuration();
        hanz(0,2,0);                   //显示"温度等级 "
    hanz(0,4,1);
        riqi();                                                //显示基本格局
            while(1)
        {

                    
           mdat=adc0832(0) ;
             convdata(mdat);
           delay(1);
           display(Ds18b20ReadTemp());


            if(SetState==0)                                   //如果不按k1就继续读日期
                {
                        Ds1302ReadTime();
                       
                }
                else
                {
                        if(K1==0)                //检测按键K1是否按下
                        {
                                delay(10);        //消除抖动
                                if(K1==0)
                                {
                                        SetPlace++;
                                        if(SetPlace>=7)
                                                SetPlace=0;                                       
                                }

                                while((i<50)&&(K1==0))         //检测按键是否松开
                                {
                                delay(10);
                                        i++;
                                }
                                i=0;
                        }
                        if(K2==0)                //检测按键K2是否按下
                        {
                                delay(10);        //消除抖动
                                if(K2==0)
                                {
                                 
                                   Ds1302Write(0x81+SetPlace,TIME[SetPlace]++);         //写入时间,停止掉电运行,调完后读取,在开启掉电运行
                                                       
                                        if((TIME[SetPlace]&0x0f)>9)                                         //换成BCD码。
                                        {
                                                TIME[SetPlace]=TIME[SetPlace]+6;                //
                                        }
                                        if((TIME[SetPlace]>=0x60)&&(SetPlace<2))                //分秒只能到59
                                        {
                                                TIME[SetPlace]=0;
                                        }
                                        if((TIME[SetPlace]>=0x24)&&(SetPlace==2))                //小时只能到23
                                        {
                                                TIME[SetPlace]=0;
                                        }
                                        if((TIME[SetPlace]>=0x32)&&(SetPlace==3))                //日只能到31
                                        {
                                                TIME[SetPlace]=0;       
                                        }
                                        if((TIME[SetPlace]>=0x13)&&(SetPlace==4))                //月只能到12
                                        {
                                                TIME[SetPlace]=0;
                                        }       
                                        if((TIME[SetPlace]>=0x08)&&(SetPlace==5))                //周只能到7
                                        {
                                                TIME[SetPlace]=1;
                                        }               
//                                        if(SetPlace==5)                //月只能到12
//                                        {
//                                                TIME[SetPlace]=;
//                                        }       
                   Ds1302Write(0x8e,0x80);
                                }
                               
                                while((i<50)&&(K2==0))         //检测按键是否松开
                                {
                                        delay(10);
                                        i++;
                                }
                                i=0;
                               
                        }


                  if(K4==0)                //检测按键K4是否按下
                        {
                                delay(10);        //消除抖动
                                if(K4==0)
                                {
                                //        TIME[SetPlace]--;
                                Ds1302Write(0x81+SetPlace,TIME[SetPlace]--);
                                        if((TIME[SetPlace]&0x0f)==0)                                         //换成BCD码。
                                        {
                                                TIME[SetPlace]=9;//TIME[SetPlace]+6;
                                        }
                                        if((TIME[SetPlace]<=0)&&(SetPlace<2))                //分秒只能到59
                                        {
                                                TIME[SetPlace]=0;
                                        }
                                        if((TIME[SetPlace]<=0)&&(SetPlace==2))                //小时只能到23
                                        {
                                                TIME[SetPlace]=0;
                                        }
                                        if((TIME[SetPlace]<=0)&&(SetPlace==3))                //日只能到31
                                        {
                                                TIME[SetPlace]=0;       
                                        }
                                        if((TIME[SetPlace]<=0)&&(SetPlace==4))                //月只能到12
                                        {
                                                TIME[SetPlace]=0;
                                        }       
                                        if((TIME[SetPlace]<=0x01)&&(SetPlace==5))                //周只能到7
                                        {
                                                TIME[SetPlace]=1;
                                        }               
//                                        if(SetPlace==5)                //月只能到12
//                                        {
//                                                TIME[SetPlace]=;
//                                        }
                      Ds1302Write(0x8e,0x80);        
                                }
                               
                                while((i<50)&&(K4==0))         //检测按键是否松开
                                {
                                        delay(10);
                                        i++;
                                }
                                i=0;
                               
                        }                                               
                }
                 
                  LcdDisplay();
          
        }
}



void Int0Configuration()
{
        //设置INT0


         
        IT1=1;//跳变沿出发方式(下降沿)
        EX1=1;//打开INT0的中断允许。
        EA=1;//打开总中断       
}
void LcdDisplay()          //lcd显示
{

       
yingwenzifu(0,0,6);  //        年
yingwenzifu(7,0,4);
yingwenzifu(15,0,4+TIME[6]/16);                        //十六进制除以16相当于十进制除以十          /16  只取高中四位字节        高四位是保存十位,低四位是保存个位的
yingwenzifu(22,0,4+(TIME[6]&0x0f));

yingwenzifu(38,0,4+TIME[4]/16); //                月
yingwenzifu(44,0,4+(TIME[4]&0x0f));

yingwenzifu(59,0,4+TIME[3]/16);          //          日
yingwenzifu(65,0,4+(TIME[3]&0x0f));

yingwenzifu(0,1,4+TIME[2]/16);        //                时         高位
yingwenzifu(7,1,4+(TIME[2]&0x0f));                       

yingwenzifu(19,1,4+TIME[1]/16);           //         分
yingwenzifu(25,1,4+(TIME[1]&0x0f));

yingwenzifu(37,1,4+TIME[0]/16);          //   秒
yingwenzifu(43,1,4+(TIME[0]&0x0f));

xingqi(65,1,(TIME[5]&0x0f) );           //星期           07                68
}
void display(uint temp)          //lcd显示                  温度
{
  float tp;
  if(temp<0)
  {
           yingwenzifu(30, 2,13);
        yingwenzifu(34, 2,13);                        //加上一个负号           其实现在x=
        temp=temp-1;
        temp=~temp;
        temp=tp*100+0.5;                     //保留两位小数

  }
  else
  {
    yingwenzifu( 36, 2,0);
        yingwenzifu(40, 2,0);
        tp=temp;
        temp=tp*0.0625*100+0.5;
}
     tidai=temp;
        wendu_shuzi(42,2,tidai%10000/1000);   //十位                                 48
    wendu_shuzi(50,2,tidai%1000/100);     //个位                                 56
        wendu_shuzi(61,2,tidai%100/10);        //小数点后第一位                  67
        wendu_shuzi(69,2,tidai%10);            //小数点后第二位                  75

}

void Int1() interrupt 2                  //中
                 
{
        delay(10);
        if(K3==0)
        {
                SetState=~SetState;
                SetPlace=0;
                Ds1302Init();

        }
}


烟雾报警器.pdf

244.01 KB, 下载次数: 16, 下载积分: 黑币 -5

烟雾报警器.zip

76.38 KB, 下载次数: 19, 下载积分: 黑币 -5

LCD5110驱动程序、温度显示、烟雾模块、模数转换、DS1302

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:778687 发表于 2020-6-14 08:39 | 只看该作者
很不错,学习一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表