单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:2740|回复:1

基于51单片机楼宇对讲系统程序

[复制链接]
ID:300743发表于 2020-3-26 10:19|显示全部楼层
原理图
电路图.jpg


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

#define DUAN P0
#define WEI P1
#define KEYMATRIX P3
sbit ON=P1^0;//开关标志灯
sbit sure=P0^7;       //通话键
sbit KA=P1^7;
sbit KB=P1^6;
sbit KC=P1^5;
sbit INH=P1^4;
sbit OpenD=P3^7;       //开锁键
sbit Beep=P3^0;           //呼叫响铃
uchar dispbuf[8],dispcount;
uchar Key,result,password;
uint sum=0,temp;
uint num;       //等待变量
uchar code dispbitcode[]=
{0xfd,0xfb,0xf7,}; //共阳位码表  
unsigned char code dispcode[]=
{
       0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff
}; //共阳段码表
//0,1,2,3,4,5,6,7,8,9,A,b,C,c,d,E,F,-;NULL
void delay(uint z)//延时1ms子函数
{
       uint x,y;
       for(x=z;x>0;x--)
           for(y=110;y>0;y--);
}
void ledinit()/***初始化子函数,定时器0刷新显示内容***/
{
       TMOD|=0x01;  //  定时器0方式1
       TH0=(65536-5000)/256;
       TL0=(65536-5000)%256;
       TR0=1;
       ET0=1;
       EA=1;      
}
/***显示子函数**/
void leddisp(uint x)
{
       dispbuf[0]=x%10;      
       dispbuf[1]=x/10%10;            
       dispbuf[2]=x/100;
}
unsigned char Keyscan(void) //按键扫描程序 P2.0--P2.3为行线 P2.4--P2.7为列线
{
       unsigned char rcode, ccode;
       KEYMATRIX = 0xF1;     // 发全0行扫描码,列线输入
       Beep=1;
       if((KEYMATRIX& 0xF1) != 0xF1) // 若有键按下
           {
           delay(5);// 延时去抖动
           Beep=1;
           if((KEYMATRIX& 0xF1) != 0xF1)
                 {
                 rcode = 0xFd;       // 逐行扫描初值
                 while((rcode& 0x10) != 0)
                       {
                       KEYMATRIX = rcode;       // 输出行扫描码
                       if((KEYMATRIX& 0xF1) != 0xF1) // 本行有键按下
                           {
                           ccode = (KEYMATRIX& 0xF0) | 0x0F;
                           while((KEYMATRIX& 0xF1) != 0xF1); //等待键释放
                           Beep=1;
                           return ((~rcode) + (~ccode)); // 返回键编码
                           }
                       else
                           rcode = (rcode<<1)|0x01; // 行扫描码左移一位
                       }
                 }
           }
       Beep=1;
       return 0; // 无键按下,返回值为0
}
Keyresult(unsigned char key)
{
   switch(key)
   {
/*   case 0x11: return(7); break;
   case 0x21: return(8); break;
   case 0x41: return(9); break;             */
//  case 0x81: return(?); break;
   case 0x12: return(4); break;
   case 0x22: return(5); break;
   case 0x42: return(6); break;
//   case 0x82: return(7); break;
   case 0x14: return(1); break;
   case 0x24: return(2); break;
   case 0x44: return(3); break;
//  case 0x84: return(11); break;
   case 0x18: return(12); break;//*
   case 0x28: return(0); break;
   case 0x48: return(14); break;//#
//  case 0x88: return(15); break;
   default: break;
   }
}
void alarm()
{
       for(temp=0;temp<5;temp++)
       {
           P2=0X00;
           delay(200);
           P2=0XFF;
           delay(200);
       }
}
void hujiao()       //呼叫声      
{
       uchar a;
       for(a=0;a<5;a++)
       {
           Beep=!Beep;
           delay(50);
       }
}
void open()
{
       P2=0xbf;
       delay(100);

       P2=0xef;
       delay(100);

       P2=0xfb;
       delay(100);

       P2=0xfe;
       delay(100);


       delay(100);
       P2=0x7f;
       delay(100);
       P2=0xdf;
       delay(100);
       P2=0xf7;
       delay(100);
       P2=0xfd;
       delay(100);
       P2=0XFf;
}
void main()
{
start:
       ledinit();
      
       while(1)
       {
//P1=0x40;

           Key = Keyscan();  
           if(Key)
           {
                 result = Keyresult(Key);
                 if(result==14)//#密码锁状态
                       {
                       dispbuf[0]=15;      
                       dispbuf[1]=15;            
                       dispbuf[2]=15;
                       password=sum=0;
                       do
                       {
                           Key = Keyscan(); //检测键盘
                           if(Key)//有按键按下
                           {
                                 result = Keyresult(Key);//读入按键值
                                 if(result>=0&&result<=9)//属于数字的输入
                                       sum=sum*10+result;//计算累计数
                                 if(result==12)//清零按键按下?
                                       sum=0;//结果清零
                                 leddisp(sum);//显示结果
                                 if(sum>100)//已经输入三位数了,但是密码错
                                 {
                                       delay(1000);//延时并且报警
                                       password=sum;//读入密码值
                                       sum=0;//结果清零
                                       if(password!=123)
                                           alarm();//密码错误,报警
                                 }
                                 leddisp(sum);//显示结果
                           }
                       }while(password!=123);//等待密码正确
                       ON=0;//开锁
                       for(temp=0;temp<3;temp++)      
                           open();
                       delay(2000);
                       ON=1;
                       sum=0;
                 }
                 else
                 {
                       if(result==12)//清零按键按下?
                           sum=0;//结果为零
                       if(result>=0&&result<=9)//属于数字输入?
                           sum=sum*10+result;//将结果计算出
                       }
           }//以上是矩阵键盘操作
           leddisp(sum);//显示结果
           if(sum>100)
                 switch(sum)//输入正确,点亮对应的住户指示灯
                 {           //否则报警,重新输入
                       case  101:P2=0xbf;KC=0;KB=0;KA=0;hujiao();break;//对应八种结果
                       case  102:P2=0x7f;KC=0;KB=0;KA=1;hujiao();break;
                       case  201:P2=0xef;KC=0;KB=1;KA=0;hujiao();break;
                       case  202:P2=0xdf;KC=0;KB=1;KA=1;hujiao();break;
                       case  301:P2=0xfb;KC=1;KB=0;KA=0;hujiao();break;
                       case  302:P2=0xf7;KC=1;KB=0;KA=1;hujiao();break;
                       case  401:P2=0xfe;KC=1;KB=1;KA=0;hujiao();break;
                       case  402:P2=0xfd;KC=1;KB=1;KA=1;hujiao();break;
                       default : P2=0XFf;alarm();sum=0;hujiao();break;
                 }
//           sure=1;
           if(sure==0)       //一旦按下通话键
           {
                 Beep=1;
                 num=0;
                 if(sum==0)
                       INH=1;//关闭4051
                 if(sum>100)           //接通对应的摄像头。
                 {
                       INH=~INH;//开启4051
                       if(!INH)
                       {
                           P2=0xff;//关闭报警灯
                           sum=0;//结果清零
                       }
                 }
//                 ON=~ON;
                 while(!sure);//松开键盘检测
           }
           else
           {
                 if(sum>100)
                 {
                       num++;
                       if(num>40)
                       {
                           num=0;
                           P2=0XFf;
                           sum=0;
                           Beep=1;
                           goto start;
                       }
                 }
           }

           if(OpenD==0)       //开锁键
           {
                 delay(10);
                 if(OpenD==0)
                 {
                       ON=0;
                      
                 }
                 while(!OpenD);
                 delay(2000);
                       ON=1;
           }
       }
}
/***定时器0刷新显示内容**/
void t0(void) interrupt 1 //using 0
{
       TH0=(65536-5000)/256;
       TL0=(65536-5000)%256;
       WEI|=0x0e;//关位选
       DUAN=dispcode[dispbuf[dispcount]]; //段选
       WEI&=dispbitcode[dispcount]; //开位选
       dispcount++;
       if(dispcount==3)
         dispcount=0;
}

1.C语言程序.zip

48.84 KB, 下载次数: 36, 下载积分: 黑币 -5

程序

3.Protel99se图.zip

114.82 KB, 下载次数: 36, 下载积分: 黑币 -5

原理图

ID:1112461发表于 2024-3-9 15:19|显示全部楼层
大佬这个有仿真吗?想学习

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

Powered by 单片机教程网