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

📄 linshi.c

📁 MSC51的密码锁程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <reg51.h>
#include <absacc.h>
#include <stdio.h>	
#include <math.h>
#include <INTRINS.h>

#define WriteDeviceAddress 0xa0    // 写密码锁的地址
#define ReadDviceAddress 0xa1      // 读密码锁的地址

bit enter;                         // 确认键(1为按下0为未按下)
bit alter;                         // 修改确认剑(1为按下0为未按下)
bit keyflag;                       // 密码正确与否(1为正确0为非正确)
bit light;                         // 7段是否亮(1为亮2为灭)
sbit open=P3^0;                    // 继电器开关低电平为开,高电平为关
sbit buzzer=P3^1;                  // 喇叭 
sbit SCL=P3^6;                     // 定义I2C SCK端口
sbit SDA=P3^7;                     // 定义I2C SDA端口
unsigned char digit;               // 7段码的显示位
unsigned char font[4];             // 7段码缓冲区(共4位)
unsigned char t1count;             // 定时器1由50ms累积到1s所用的计数器
unsigned char count;               // 密码位计数
unsigned char recount;             // 修改密码时新密码计数
unsigned char keyword[4];          // 密码存储数组
unsigned char setkey[4];           // 修改密码时密码的缓存数组
unsigned char keyinterim[4];       // 输入密码存储区


void Delay(unsigned int number);   // 定义延时函数
void Resetkey(void);               // 定义密码修改函数
unsigned char keyscan(void);       // 定义键盘扫描函数
void time0_int(void);              // 定义中断0
void time1_int(void);              // 定义中断1
unsigned char getfont(unsigned char i);      // 根据获取七段码
void display(void);                // 定义显示函数
bit keycmp(void);                  // 定义密码比较函数
void Resetkey(void);
                                           
void Start();                      // 下面都是I2C函数
void Stop();
void NoAck();
bit TestAck();
void Write_I2C(unsigned char address,unsigned char ch);
unsigned char Read8Bit(void);
unsigned char Read_I2C(unsigned char address);





/* 主程序 */
void main()
{ 
  int wait,wait1;                  // 定义等待时用的变量
  unsigned char j,key;             // 定义扫描后输入的键值
  unsigned char num=0;             // 定义密码输入次数                        
  P2 = 0xff;                       // 关闭数码管显示
	
  TMOD = 0x11;                     // T0,T1工作方式1
  TH0 = -2000/256;                 // 2ms 定时设置 
  TL0 = 2000%256;                                                           
  TH1 = -50000/256;                // 50ms 定时设置 
  TL1 = -50000%256;
  TR0 = 1;                         // 启动计数器0,关闭计数器1
  ET0 = 1;
  TR1 = 0;
  ET1 = 1;
  EA = 1;
  count = 0;                       // 初始没有输入密码,计数器设为0
  enter= 0;                        // 没有按下确认键
  keyflag = 0;                     // 密码标志先置为0
  open = 1;                        // 门关
  buzzer = 0;                      // 报警器关
  digit = 0x01;                    // 从第一位数码管开始动态扫描

  keyword[0] = 0;                  // 假设内定密码为0000
  keyword[1] = 0;
  keyword[2] = 0;
  keyword[3] = 0;

  for (j=0;j<4;j++)                // 刚加电时,显示---- 
     font[j] = 15;
  light= 1;                        // 打开数码管显示
  Write_I2C(0x00,keyword[0]);      // 写入ROM
  Write_I2C(0x01,keyword[1]);
  Write_I2C(0x02,keyword[2]);
  Write_I2C(0x03,keyword[3]);
  keyword[0]=Read_I2C(0x00);       // 从ROM中读数,并存储在密码数组中
  keyword[1]=Read_I2C(0x01);
  keyword[2]=Read_I2C(0x02);
  keyword[3]=Read_I2C(0x03);

  while(1)
    {
      key = keyscan();             // 调用键盘扫描函数
      switch(key) 
      {
        case 0x11:                 // 1行1列,数字7
          if (count<4)
            {
              font[count] = 7;                
              keyinterim[count] = 7;
              count++;
            }
          break;
        case 0x21:                 // 1行2列,数字8
          if (count<4)
            {
              font[count] = 8;                      
              keyinterim[count] = 8;
              count++;
            }
           break;			  
        case 0x41:                 // 1行3列,数字9
          if (count<4)
            {
              font[count] = 9;                     
              keyinterim[count] = 9;
              count++;
            }
          break;
        case 0x81:                 // 1行4列
          if (count<4)
           {
              font[count]=10;              
              keyinterim[count]=10;
              count++;
           }
          break;                     
        case 0x12:                 // 2行1列,数字4
          if (count<4)
            {
              font[count] = 4;                      
              keyinterim[count] = 4;
              count++;
            }
          break;
        case 0x22:                 // 2行2列,数字5
          if (count<4)
            {
              font[count] = 5;                      
              keyinterim[count] = 5; 
              count++;
            }
          break;
        case 0x42:                  // 2行3列,数字6
          if (count<4)
            {
              font[count] = 6;                      
              keyinterim[count] = 6;
              count++;
            }
          break;
        case 0x82:                   // 2行4列
          if (count<4)
            {
              font[count] =11;                     
              keyinterim[count] = 11;
              count++;
            }
          break;
        case 0x14:                   // 3行1列,数字1
          if (count<4)
            {
              font[count] = 1;                       
              keyinterim[count] = 1;
              count++;
            }
          break;
        case 0x24:                   // 3行2列,数字2
           if (count<4)
             {
               font[count] = 2;                      
               keyinterim[count] = 2;
               count++;
             }
          break;
        case 0x44:                   // 3行3列,数字3
          if (count<4) 				
             { 
               font[count]=3;
               keyinterim[count]=3;
               count++;
             }
          break;	
        case 0x84:                   //3行4列,开始修改密码
          Resetkey();
          break;							
        case 0x18:                   //4行1列,取消
          count = 0;
          for (j=0;j<4;j++)
            {
              font[j] = 15;          // 数码管显示----
              keyinterim[j] = 15;		       
            }
          break;
        case 0x28:                   // 4行2列,数字0
          if (count<4)
            {
              font[count]=0;
              keyinterim[count]=0;
              count++;
            }
          break;
        case 0x48:                   // 4行3列
          enter= 1;
          if (count==4)
             keyflag = keycmp();
           else						
             keyflag = 0;            // 否则直接pmflag赋0
          break;
        case 0x88:                   // 4行4列 显示-
          if (count<4)
            {
              font[count]=15;
              keyinterim[count]=15;
              count++;
            }
          break;                             
        default:break;
      }
      Delay(300);                     // 延时防止重复读取键盘
      
                                                                          
      if (enter==1)                   // 如果按下确认键                                              
         {     
          num=num+1;
          enter= 0;
          count = 0;
          for (j=0;j<4;j++)
          keyinterim[j] = 0x0f;
          light= 0;                   // 关闭数码管显示
          TR1 = 1;                    // 计数器1开始计数
          t1count = 0;                // 定时器1由50ms累积到1s所用的计数器

          if (keyflag==1)             // 如果密码正确
            { 
              open = 0;               // 门开
              num=0;                  // 密码确认次数清0
            }
           else
              { 
               buzzer= 1;             // 报警器响
               P0=0x7C;
               P2=0x01;
               if(num==3)             // 如果输入错误次数为3
                 { num=0;
                   P0=0x7C;
                   buzzer=1;          // 报警器响,并挂起3分钟
                   for (wait1=1;wait1<999;wait1++)
                       {for (wait=1;wait<9999;wait++);
                       }
				 }
                for (wait1=1;wait1<9;wait1++)
                 {for (wait=1;wait<9999;wait++);
                 }
			    buzzer=0;

             }  
         }
                                                          

     }   

                                                
} 








unsigned char keyscan(void)
{
   unsigned char scancode,tmpcode;
   P1 = 0xf0;                         // 开始扫描
    if ((P1&0xf0)!=0xf0)              // 若有键按下
      {
        Delay(500);                   // 延时去抖动并防止重复写入
        if ((P1&0xf0)!=0xf0)
          {
            scancode = 0xfe;
            while((scancode&0x10)!=0) // 逐行扫描
             {
               P1 = scancode;         // 输出行扫描码
               if ((P1&0xf0)!=0xf0)   // 本行有键按下
                 {
                   tmpcode = (P1&0xf0)|0x0f;
                   return((~scancode)+(~tmpcode)); // 返回特征字节码,为1的位即对应于行和列 
                 }
               else scancode = (scancode<<1)|0x01; // 行扫描码左移一位
              }
          }
      }
   return(0);                          // 无键按下,返回值为0 	
}



void time0_int(void) interrupt 1 
{
        TH0 = -2000/256;               // 重置2ms定时 
        TL0 = -2000%256;

        if (light==1)                  // 如果显示器为开
            display();                 // 调用显示函数
}



void time1_int(void) interrupt 3
{
   unsigned char k;
   TH1 = -50000/256;                   // 重置50ms定时 
   TL1 = -50000%256;

   if (t1count<20)				
     {
       t1count++;
     }
   else
     {
       TR1 = 0;                         // 关闭计数器1
       t1count = 0;	
       open = 1;                        // 关门
       light= 1;                        // 打开数码管显示
       digit = 0x01;                    // 从数码管第1位开始动态显示
       for (k=0;k<4;k++)                // 显示----
       font[k] = 15;
      }
}



unsigned char getfont(unsigned char i)
{
  unsigned char word;
  switch (i)
   {
     case 0:  word=0x3f;break;           //0
     case 1:  word=0x06;break;           //1
     case 2:  word=0x5B;break;           //2
     case 3:  word=0x4F;break;           //3
     case 4:  word=0x66;break;           //4
     case 5:  word=0x6D;break;           //5
     case 6:  word=0x7D;break;           //6
     case 7:  word=0x07;break;           //7
     case 8:  word=0x7F;break;           //8
     case 9:  word=0x6f;break;           //9
     case 10: word=0x77;break;           //A
     case 11: word=0x7C;break;           //B
     case 12: word=0x39;break;           //C
     case 13: word=0x5E;break;           //D
     case 14: word=0x79;break;           //E
     case 15: word=0x40;break;           //-
     default:       break;
    }
   return(word);
}



void display(void)
{
  unsigned char i;
  switch (digit)
   {
     case 1:  i=0; break;
     case 2:  i=1; break;
     case 4:  i=2; break;
     case 8:  i=3; break;
     case 16: i=4; break;
     case 32: i=5; break;
     default: break;
   }

   P2 = 0xff;                              // 关闭显示           
   P0 = getfont(font[i]);                  // 送字型码
   P2 = ~(digit);                          // 送字位码	
   if (digit<0x08)                         // 共4位
     digit = digit*2;                      // 左移一位
   else
     digit = 0x01;
}



⌨️ 快捷键说明

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