⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 程序.c

📁 基于AT89S52单片机密码锁的源程序
💻 C
字号:
#include<AT89X52.H>

#define uchar unsigned char

uchar digbit;                 // 字位
uchar wordbuf[6 ];            // 字型缓冲码
uchar t1count;                // 定时器T0由50ms累积到5 s所用的计数器

unsigned char second;          // 秒
unsigned char minute;            // 分
unsigned char hour;             //时
unsigned int tcnt;
uchar count;                  // 密码位记数
uchar pw[6];                  // 初始密码存储区
uchar pwbuf[6];               // 输入密码存储区
uchar   wrong;                //错误次数计数器
bit cancelflag;                 //  取消键标志位
bit enterflag;                  // 确认键标志位
bit zhflag;                     // 功能键转换标志位
bit pwflag;                    //  密码正确标志位
bit showflag;                 //  数码管显示标志位
sbit green=P2^2;                
sbit red=P2^1;
sbit spk=P2^0;
void   display();
bit   pwcmp ();
/* 键盘消抖延时函数  10mus   */
void  delay ()
 {
   uchar i,j ;
   for (i=200;i>0;i--)
              for (j=50;j>0;j--);
 }
  
/* 键盘扫描程序  */
  uchar keyscan (void)
   {
      uchar scancode,tmpcode;
       P0= 0xf0;                           // 发全0行扫描
      if ((P0&0xf0)!= 0xf0)                 // 若有键按下
       {	 
			
	        delay();                           //  消除抖动 10ms
     	if ((P0&0xf0)!= 0xf0)
	  	{    
	   		 scancode=0xfe;
   			 while ((scancode&0x10)!=0)        // 逐行扫描
    			{
     			 P0 = scancode;                 // 输出行扫码
     			 if ((P0&0xf0)!=0xf0)            // 本行有键按下
       				{
                     tmpcode=(P0&0xf0)|0x0f ;
					 while ((P0&0xf0)!=0xf0) ;
					 
                     return ((~scancode)+(~tmpcode));      // 按键行列码
                    }
                 else scancode=( scancode<<1)|0x01 ;   // 行扫码左移一位
                 }
         }
       }
      return  (0);
    }


void time1_int(void) interrupt 3 using 0
{     
   
	tcnt++;                    //定时器中断次数加1,250US
    if(tcnt==4000)
   {
  		tcnt=0;
    	second++;
    	if(second==60)           // 秒进位
    	{
			second=0;
        	minute++;
        	if(minute==60)          //分进位
        	{ 
        		minute=0;
            	hour++;
            	if(hour==24)         // 时进位
            	{
           		 	hour=0;
            	}
       		}
   		}

	}                             //if(tcnt==4000) END		
}
void time0_int(void)  interrupt 1  // 50ms
{
 
  TH0=(65536-50000)/256;
  TL0=(65536-50000)%256;
  if  (t1count<100)                 //  5秒
   {
   t1count ++;
   } 
  else
   { 
     TR0=0;                 //  关T0
     count=0;              //密码计数器清零
     t1count=0;            // 5秒计数器清零
	 red=1;
	 green=1;
	 cancelflag=0;
     showflag=1;        // 打开显示
     digbit=0xfe;         // 第一位字型码
	 /*  初始显示  */
      wordbuf[0]=0x0e;
      wordbuf[1]=0x0e;
      wordbuf[2]=0x0e;
      wordbuf[3]=0x0e;
      wordbuf[4]=0x0e;
      wordbuf[5]=0x0e;
    }
}

/* 共阳极数码管0~9,A~B字型代码  */
uchar  getcode (uchar i )
{
  uchar  p;
  switch  (i)
   {
    case  0:  p=0xc0;  break;  // 0 
    case  1:  p=0xf9;  break;    // 1
    case  2:  p=0xa4;  break;    // 2
    case  3:  p=0xb0;  break;    // 3
    case  4:  p=0x99;  break;    // 4
    case  5:  p=0x92;  break;    // 5
    case  6:  p=0x82;  break;    // 6
    case  7:  p=0xf8;  break;    // 7
    case  8:  p=0x80;  break;    // 8
	case  9:  p=0x90;  break;      //  9
	case  10:  p=0x88;  break;      //  10
	case  11:  p=0x83;  break;     // 11
	case  12:   p=0xc6;   break;  // 12
	case  13:   p=0xa1;   break;  // 13
	case  14:   p=0x86;   break;  // 14
	case  15:   p=0x8e;   break;  // 15
    default:            break;
   }
   return  (p) ;
}

/* 显示函数  */
void   display(void)
 {
  uchar  i;
  switch (digbit)
    {
     case  0xfe:    i=0;   break;           //第1位字型码
     case  0xfd:    i=1;   break;           //第2位字型码
     case  0xfb:    i=2;   break;           //第3位字型码
     case  0xf7:    i=3;   break;           //第4位字型码
     case  0xef:    i=4;   break;           //第5位字型码
     case  0xdf:    i=5;   break;           //第6位字型码
     default:          break;
     }    
  P1 = getcode(wordbuf[i]);       // 送字型码
  P3 = digbit  ;                 // 送字位码
  if (digbit>0xdf)              // 共六位
         digbit =(digbit<<1)|0x01;            // 左移一位
  else 
         digbit = 0xfe;
}

/* 密码比较函数 */
bit   pwcmp (void)
{
      bit  flag ;
      uchar  i;
      for (i=0;i<6;i++)
	      {
		      if (pw[i]==pwbuf[i])
			         flag=1;
			  else  
			      {
				    flag=0;
					i=6;
				   }
			}

     return (flag);            
   }

      
     /* 报警   */
void  sound (void)
{ 
  unsigned int i,j,k;
  unsigned int count1,sound1,tone;
  count1=60;
  sound1=40;
  tone=110;
  for (k=0;k<count1;k++)
  {
     P3=0xff;
   red = ~ red;
        for (i = 0; i<sound1;i++)
         {
         spk= ~ spk;
         for (j=0;j<tone;j++);
         }
   delay();
 }
}
void  sound1 (void)
{ 
  unsigned int i,k,j;
  unsigned int count1,sound1,tone;
  count1=30;
  sound1=20;
  tone=70;
  for (k=0;k<count1;k++)
       {
            P3=0xff;
	     green = ~ green;
       for (i = 0; i<sound1;i++)
         {
            spk= ~ spk;
		 for (j=0;j<tone;j++);
         }
     delay();
    }
}
void  sound2 (void)
{ 
  unsigned int i,j,k;
  unsigned int count1,sound1,tone;
  count1=40;
  sound1=30;
  tone=90;
  for (k=0;k<count1;k++)
      {
	      P3=0xff;
         red = ~ red;
        for (i = 0; i<sound1;i++)
                 for (j=0;j<tone;j++);

   delay();
   }
}

    
/*   主程序  */
void  main()
{
  uchar  j,key;
  P3 = 0xff;              // 关闭数码管显示
  TMOD=0x21;           //  工作方式
 
   TH0=(65536-50000)/256;            //  5毫秒
   TL0=(65536-50000)%256;
   TR0=0;
   ET0=1;

   TH1=0X06;               // 250us
   TL1=0X06;
   TR1=1;
   ET1=1; 
   
   EA=1;            //   开中断
  count=0;               //   初始没有密码输入,计数器为0
  enterflag=0;             //  没有确定键按下
  cancelflag=0;
  pwflag=0;               //   密码标志记为0
  green =1;
  spk=1;
  wrong=0;
  red =1;            //  红灯、绿灯不亮
  /*    设定初始密码   */
  pw[0]=1;
  pw[1]=2;
  pw[2]=3;
  pw[3]=4;
  pw[4]=5;
  pw[5]=6;
  /*    设定时间   */
  second=50;
  minute=58;
  hour=12;
  showflag =1 ;               // 打开数码管显示
/*   刚加电时显示 8888888  */
      	wordbuf[0]=0x0e;
        wordbuf[1]=0x0e;
   		wordbuf[2]=0x0e;
   		wordbuf[3]=0x0e;
   		wordbuf[4]=0x0e;
   		wordbuf[5]=0x0e;	 
	  digbit = 0xfe;              //   从第一位开始动态扫描
	  
  while (1)
      {
   	  display();
      key = keyscan();          //   调用键盘扫描函数
      switch (key)
             {
              
             case  0x11:            //   第1行第1列,数字0
                       TR0=0;
                       TR0=1;
			           if (zhflag==1)
						    {
						     second++;
                             if(second==60)     // 调秒
                  				{
                   				 second=0;
						     	}
							 }
					  else 
						 {
                          if  (count<6)
                             {
                             wordbuf[count]=0x0f ;        //  对应位显示 F
                         	 pwbuf[count] = 0;
                    		 count+=1;
                              }
						  }
                        break;
            case  0x21:                    //  第1行第2列,数字1
                        TR0=0;
                        TR0=1;
                        if (zhflag==1)
						    {
						    minute++;
                         	if(minute==60)     // 调分
                 				{
                   				 minute=0;
                 				}
						     }
						else 
						 {
                          if  (count<6)
                             {
                             wordbuf[count]=0x0f ;        //  对应位显示 F
                         	 pwbuf[count] = 1;
                    		 count+=1;
                              }
						  }
      					break;
			case  0x41:                       //  第1行第3列,数字2
                        TR0=0;
                          TR0=1;
     					if (zhflag==1)
						    {
						    hour++;
            				if(hour==24)     // 调时
              				 	{
                  				 hour=0;
               					}
						    }
						 else 
						 {
                          if  (count<6)
                             {
                             wordbuf[count]=0x0f ;        //  对应位显示 F
                         	 pwbuf[count] = 2;
                    		 count+=1;
                              }
						  }
    					 break;
      		case  0x81:                     //  第1行第4列,数字3
                      TR0=0;
                      TR0=1;
                       if  (count<6)
                             {
                             wordbuf[count]=0x0f ;        //  对应位显示 F
                         	 pwbuf[count] = 3;
                    		 count+=1;
                              }
						
     					break;
		   case  0x12:                      //  第2行第1列,数字4
                      TR0=0;
                      TR0=1;
   				      if  (count<6)
                             {
                             wordbuf[count]=0x0f ;        //  对应位显示 F
                         	 pwbuf[count] = 4;
                    		 count+=1;
                              }
						 
                        break;
           case  0x22:                //  第2行第2列,数字5
                       TR0=0;
                       TR0=1;
                       if  (count<6)
                             {
                             wordbuf[count]=0x0f ;        //  对应位显示 F
                         	 pwbuf[count] = 5;
                    		 count+=1;
                              }
						 
    				   break;
           case  0x42:                   //  第2行第3列,数字6
                          TR0=0;
                           TR0=1;
                          if  (count<6)
                             {
                             wordbuf[count]=0x0f ;        //  对应位显示 F
                         	 pwbuf[count] = 6;
                    		 count+=1;
                              }
						 
   					  break;
          case  0x82:                   //  第2行第4列,数字7
                     TR0=0;
              		TR0=1;
                      if  (count<6)
                             {
                             wordbuf[count]=0x0f ;        //  对应位显示 F
                         	 pwbuf[count] = 7;
                    		 count+=1;
                              }
						
     				 break;
		 case  0x14:                     //  第3行第1列,数字8
                     TR0=0;
                     TR0=1;
                      if  (count<6)
                             {
                             wordbuf[count]=0x0f ;        //  对应位显示 F
                         	 pwbuf[count] = 8;
                    		 count+=1;
                              }
						  
    				 break;
 		case  0x24:                    //  第3行第2列,数字9
                     TR0=0;
                     TR0=1;
        		     if  (count<6)
                             {
                             wordbuf[count]=0x0f ;        //  对应位显示 F
                         	 pwbuf[count] = 9;
                    		 count+=1;
                              }
						  
    				 break;
		case  0x44:
          				enterflag=1 ;                 //比较密码
          				if (count==6)
           					pwflag = pwcmp () ;
          				else 
             				pwflag = 0 ;						
     				break;
		case  0x84:
    				    count=0;
						cancelflag=1;
       					for (j=0;j<6;j++)          // 取消密码输入
				          {
           				    wordbuf[j]=8;
                            pwbuf[j]=0x0f;        // 显示888888
						  }
                         t1count=50;
						 TR0=1;                   //开T0
          			break;
        case  0x18:    
		            count=0;
                    zhflag=~zhflag;          // 功能转换
                    break;

      	 default:  break;
	   }	   	   

	 if (zhflag==1)                        //显示电子钟
	       {
			  wordbuf[0]=second%10;
        	  wordbuf[1]=second/10;
   			  wordbuf[2]=minute%10;
   			  wordbuf[3]=minute/10;
   			  wordbuf[4]=hour%10;
   			  wordbuf[5]=hour/10;
             }
	  else
	       {  
		     if ((count==0)&(cancelflag==0))
			          {
		                        t1count=150;
		                        TR0=1;           // 开T0
					 }
			}
    if (enterflag ==1)
       {
         enterflag = 0;
         count = 0;   
           t1count = 0;
          if (pwflag==1)              //密码正确
	         {
	          wrong=0;
               sound1();
				 TR0=1;   
             }
	      else
             {
			   wrong+=1;
			  if(wrong==3)        //错误三次
			      { 
				    sound();        //调用报警并锁定键盘
				    wrong=0;
					TR0=1;          //开T0
					}
			   else 
			      {
				    sound2();            //密码错误
				    TR0=1;
				   }
	          }
        }
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -