找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机+PCF8574简易密码锁程序 带详细注释 1602显示

[复制链接]
跳转到指定楼层
楼主
本帖最后由 LUQIMAI 于 2020-6-10 12:52 编辑

*      名称:基于STC51的简易密码锁
*        硬件配置:IAP15W4K61S4+LCD1602+PCF8574+4*4矩阵键盘
*        功能说明:键盘表
*                                          [   0,1,2,3,
*                                             4,5,6,7,
*                                              8,9,a,b,
*                                              c,d,e,f
*                                         ]
*                                                按键说明:f:确认键;e:设置键;b:上锁键
*                                         初始密码:1234
*                                         开门流程:通电,输入初始密码,按f键,提示open,同时P2灯亮代表开门。
*                                         修改密码流程:通电后,按e键,首先输入旧的密码(第一次设置时,旧密码就是初始密码),按照LCD提示操作即可。
*                                                上锁流程:开门后,按下b键,上锁,P2灯灭
*                                                灯光说明:流水灯-在修改密码时,每一步成功都会有流水灯提示
*                                                                全亮灯-门开
*                                                                全灭灯-门关
*        不足之处:1.不知是单片机识别出现问题,还是键盘读入的问题。有时输入正确的密码,但提示错误,慢慢的按键输入,出错的几率会低些
*                                                2.需要一直通电,如果重新供电后,修改的密码会失效,所以离应用到实际生活还有距离
*                                                3.暂时这些,有问题望指
*        如果有不同想法的朋友,欢迎一起交流学习!!
硬件连接图如下:
硬件连接的详细接法程序中有,不清楚的也可以直接回帖问我
注意注意!!!!做了几处修改,下面是优化版
注意注意!!!!做了几处修改,下面是优化版
注意注意!!!!做了几处修改,下面是优化版
修改:        1.添加删除功能

        2.优化了几处错误,基本完成所有密码锁的功能
如有发现其他错误,望不惜赐教!!
此处是优化版的源码,请下载这个:
优化版.rar (83.14 KB, 下载次数: 41)



(有几处错误)单片机源程序如下:
  1. #include <stc15.h>
  2. #include "intrins.h"
  3. #define uchar unsigned char  
  4. #define uint unsigned int  
  5. #define KeyPort P0                                //外接键盘,低四位接行,高四位接列

  6. uchar  KEY_TABLE[16] =
  7. {
  8.     0xEE, 0xDE, 0xBE, 0x7E,
  9.     0xED, 0xDD, 0xBD, 0x7D,
  10.     0xEB, 0xDB, 0xBB, 0x7B,
  11.     0xE7, 0xD7, 0xB7, 0x77
  12. };
  13. int flag1=0;                                                                                                                                                                                                                                                                                        //修改密码标志位
  14. uchar num,i=0,j;            
  15. uchar passwordtemp[16],password[16]={'1','2','3','4'},newpassword[16];       //输入的密码,默认的密码
  16. uchar inputtimes;                                                                                                                                                                                                      //密码输入错误次数
  17. uint n,m;                                                                                                                                                                                                                                                                    //输入密码长度,实际密码长度
  18. bit Flag=0;\
  19. uchar light,light1=0,light2=0xf0;                                                                                                                                                        //设置成功,开锁,错误,
  20.    
  21. sbit SCL = P1^0;
  22. sbit SDA = P1^1;

  23. char ADDR = 0x4e;    // PCF8574  T  模块的地址码
  24. //char ADDR = 0x7e;    // PCF8574   AT  模块的地址码

  25. //***************************** 延时 y  ms ***********************************************
  26. void delay1(int y)   //
  27. {
  28.          ;
  29.         while(y--)
  30.         {
  31.         unsigned char a,b,c;
  32.         for(c=1;c>0;c--)
  33.         for(b=142;b>0;b--)
  34.         for(a=2;a>0;a--);
  35.         }
  36. }

  37. //******************************** IIC 串口开始 ********************************************

  38. void IIC_start(void)
  39. {
  40.         SDA=1;
  41.         _nop_();
  42.         SCL=1;
  43.         _nop_();
  44.         _nop_();
  45.         _nop_();
  46.         _nop_();
  47.         _nop_();
  48.         SDA=0;
  49.         _nop_();
  50.         _nop_();
  51.         _nop_();
  52.         _nop_();
  53.         _nop_();
  54.         SCL=0;
  55.                                 _nop_();
  56.                                 _nop_();
  57.         
  58. }


  59. //********************************** IIC 串口写1个字节 ******************************************


  60. void IIC_writeByte(char temp)
  61. {
  62.         char i;
  63.         for(i=0;i<8;i++)
  64.         {
  65.                 SDA=(bit)(temp & 0x80) ;   // 根据规定1602的数据最高位必须为  1  
  66.                 temp <<=1;
  67.                 _nop_();
  68.                 _nop_();
  69.                 SCL=1;
  70.                 _nop_();
  71.                 _nop_();
  72.                 _nop_();
  73.                 _nop_();
  74.                 _nop_();
  75.                 SCL=0;
  76.         }
  77.         _nop_();
  78.         _nop_();
  79.         _nop_();
  80.         _nop_();
  81.         SDA=1;
  82.         _nop_();
  83.         _nop_();
  84.         _nop_();
  85.         _nop_();
  86.         SCL=1;
  87.         _nop_();
  88.         _nop_();
  89.         _nop_();
  90.         while(SDA);
  91.         _nop_();
  92.         SCL=0;
  93. }

  94. //******************************** 1602写命令 ********************************************


  95. void LCD_write_command(char comm)
  96. {
  97.         char tmp;
  98.         IIC_start();          // 串口开始
  99.         IIC_writeByte(ADDR);  // 先选PCF 8574T 的地址  (应该是相当于选中的意思吧)
  100.         
  101.         tmp = comm & 0xF0;    // 与0xf0 应该是取第四位的意思吧
  102.         tmp |= 0x0C;         //保留高4位为指令的高四位,低四位为   RS = 0, RW = 0, EN = 1  
  103.         IIC_writeByte(tmp);  //从串口送出
  104.         delay1(20);
  105.         tmp &= 0xFB;        //Make EN = 0
  106.         IIC_writeByte(tmp);
  107.         
  108.         tmp = (comm & 0x0F) << 4 ;  //将指令的低四位 送到高位置保存
  109.         tmp |= 0x0C;        //RS = 0, RW = 0, EN = 1
  110.         IIC_writeByte(tmp);
  111.         delay1(20);
  112.         tmp &= 0xFB; // Make EN = 0
  113.         IIC_writeByte(tmp);
  114.         
  115. }
  116. //******************************** 1602写数据 ********************************************


  117. void LCD_write_data(char data1)
  118. {
  119.         char tmp;
  120.         IIC_start();
  121.         IIC_writeByte(ADDR);   // 先选PCF 8574T 的地址  (应该是相当于选中的意思吧)
  122.         
  123.         tmp = data1 & 0xF0;
  124.         tmp |= 0x0D; //RS = 1, RW = 0, EN = 1
  125.         IIC_writeByte(tmp);
  126.         delay1(20);
  127.         tmp &= 0xFB; //Make EN = 0
  128.         IIC_writeByte(tmp);
  129.         
  130.         tmp = (data1 & 0x0F) << 4 ;
  131.         tmp |= 0x0D; //RS = 0, RW = 0, EN = 1
  132.         IIC_writeByte(tmp);
  133.         delay1(20);
  134.         tmp &= 0xFB ; // Make EN = 0
  135.         IIC_writeByte(tmp);
  136. }


  137. //******************************** 1602初始化 ********************************************


  138. void Init_Lcd(void)
  139. {
  140.         LCD_write_command(0x33); //将8位总线转为4位总线
  141.         delay1(50) ;
  142.         LCD_write_command(0x32); //
  143.         delay1(50) ;
  144.         LCD_write_command(0x28); // 4位数据线,显示2行,5*7点阵字符  !如果是0x38  则为8位数据线,显示2行,5*7点阵字符
  145.         delay1(50) ;
  146.         LCD_write_command(0x0C); // 开显示,关闭光标,不闪烁
  147.         delay1(50) ;  
  148.         LCD_write_command(0x06); // 设定输入方式,增量不位移
  149.         delay1(50) ;
  150.         LCD_write_command(0x01); // 清屏
  151.         delay1(50) ;
  152. }


  153. //*************************************** 在指定位置显示字符串 *************************************


  154. void Write_LCD(int x, int y, char *str)
  155. {
  156.         char addr;
  157.         if( x < 0)
  158.         {
  159.                 x = 0;
  160.         }
  161.         if(x > 15)
  162.         {
  163.                 x = 15;
  164.         }
  165.         if(y<0)
  166.         {
  167.                 y = 0;
  168.         }
  169.         if(y > 1)
  170.         {
  171.                 y = 1;
  172.         }
  173.         
  174.         addr = 0x80 + 0x40 * y + x;   // Move cursor  移动光标
  175.         LCD_write_command(addr);
  176.         while (*str)
  177.         {
  178.                 LCD_write_data(*str++);
  179.         }
  180. }


  181. //-------------------------------------------- 显示字符串的函数 ----------------------------------------------------


  182. void LCD_write_word(unsigned char *s)                  //显示字符串的函数
  183. {
  184.         while(*s>0)
  185.         {
  186.                 LCD_write_data(*s);
  187.                 s++;
  188.                                                                
  189.         }
  190. }

  191. //********************************* 指定位置显示一个字符*******************************************


  192. /*
  193. void Print_Char (unsigned char line,unsigned char num,unsigned char date)
  194. {
  195.                 LCD_write_command(line+num);
  196.                 LCD_write_data(date);
  197. }


  198. */

  199. //按指定位置显示一个字符(针对1602液晶)-用在温度显示

  200. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
  201. {
  202. Y &= 0x1;
  203. X &= 0xF;                 //限制X不能大于15,Y不能大于1
  204. if (Y) X |= 0x40;        //当要显示第二行时地址码+0x40;
  205. X |= 0x80;               // 算出指令码
  206. LCD_write_command(X);    //这里不检测忙信号,发送地址码
  207. LCD_write_data(DData);
  208. }

  209. //--------------------------------------初始化----------------------------------------------------------------
  210. void initial()
  211. {
  212.         P1M0=0;
  213.         P1M1=0;
  214.         P2M0=0;
  215.         P2M1=0;
  216.         P0M0=0;
  217.         P0M1=0;
  218. }

  219. /*------------------------------------------------
  220. 按键扫描函数,返回扫描键值
  221. ------------------------------------------------*/

  222. unsigned char KeyScan(void)  //键盘扫描函数,使用行列反转扫描法
  223. {
  224.          uchar cord_h,cord_l;            //行列值中间变量
  225.         uchar tempt;
  226.         uint i;
  227.          KeyPort=0xf0;                                                    //列线输出全为0
  228.          cord_l=KeyPort&0xf0;     //读入行线值
  229.          if(cord_l!=0xf0)    //先检测有无按键按下
  230.          {
  231.                   delay1(10);        //去抖
  232.                   if(cord_l!=0xf0)
  233.                   {
  234.                             cord_l=KeyPort&0xf0;  //读入列线值
  235.                             KeyPort=0x0f;                                        //行线输出为0
  236.                             cord_h=KeyPort&0x0f;  //读入行线值
  237.                             while((KeyPort&0x0f)!=0x0f);//等待松开并输出
  238.                             tempt = cord_l+cord_h;
  239.                                         for(i=0;i<16;i++)
  240.                                    if(KEY_TABLE[i]==tempt)
  241.                                                  break;
  242.                                         return(KEY_TABLE[i]);
  243.                    }
  244.           }
  245.           return(0xff);     //返回该值
  246. }

  247. /*------------------------------------------------
  248. 按键值处理函数,返回扫键值
  249. ------------------------------------------------*/

  250. unsigned char KeyPro(void)
  251. {
  252. switch(KeyScan())
  253. {
  254.   case 0xee:return '0';break;//0 按下相应的键显示相对应的码值
  255.   case 0xde:return '1';break;//1
  256.   case 0xbe:return '2';break;//2
  257.   case 0x7e:return '3';break;//3
  258.   case 0xed:return '4';break;//4
  259.   case 0xdd:return '5';break;//5
  260.   case 0xbd:return '6';break;//6
  261.   case 0x7d:return '7';break;//7
  262.   case 0xeb:return '8';break;//8
  263.   case 0xdb:return '9';break;//9
  264.   case 0xbb:return 'a';break;//a
  265.   case 0x7b:return 'b';break;//b
  266.   case 0xe7:return 'c';break;//c
  267.   case 0xd7:return 'd';break;//d
  268.   case 0xb7:return 'e';break;//e
  269.   case 0x77:return 'f';break;//f
  270.   default:return 0xff;break;
  271. }
  272. }

  273. //--------------------------------------------------------流水灯--------------------------------------------------------

  274. void RuningLight()                                                                                                                                                                                                //流水灯
  275. {
  276.         light=0xfe;
  277.         P2=light;
  278.         for(j=0;j<8;j++)
  279.            { light<<=1 ;
  280.                          delay1(250);
  281.                          P2=light;
  282.                  }
  283.         P2=0xff;
  284.                         
  285.         
  286. }

  287. //--------------------------------------------------------密码验证--------------------------------------------------------

  288. void VriefytPassword()                                                                                                                                                                        //验证密码
  289. {        if(flag1)
  290.                                                 m=sizeof(newpassword);                                                                                                                        //记录新密码的长度
  291.                                  else
  292.                                           m=sizeof(password);                                                                                                                                        //记录旧密码的长度
  293.                                                 n=sizeof(passwordtemp);                                                                                                                        //记录输入密码的长度
  294.                                  if(m==n)                                                                                                        //长度判断
  295.                                                 {
  296.                                                          if(flag1)                                                                                                                                                                                        //修改密码后
  297.                                                                         for(j=0;j<sizeof(passwordtemp);j++)                                                                //是否一一对应
  298.                                                                                 { if(passwordtemp[j]==newpassword[j])
  299.                                                                                         Flag=0;
  300.                                                                                         else
  301.                                                                                         { Flag=1;
  302.                                                                                                 break;
  303.                                                                                         }
  304.                                                                                 }
  305.                                                                 else                                                                                                                                                                                                //修改密码前
  306.                                                                         for(j=0;j<sizeof(passwordtemp);j++)                                                                //是否一一对应
  307.                                                                                 { if(passwordtemp[j]==password[j])
  308.                                                                                         Flag=0;
  309.                                                                                         else
  310.                                                                                         { Flag=1;
  311.                                                                                                 break;
  312.                                                                                         }
  313.                                                                                 }
  314.                                                 }
  315.                                  else
  316.                                  {         Flag=1;
  317.                                                 Write_LCD(0,1,"                ");                //清除该行
  318.                                                 delay1(10);
  319.                                                 Write_LCD(0,1,"Wrong length!");                                //密码正确显示的信息
  320.                                           delay1(10);
  321.                                  }
  322.                                  if(Flag)                                                                                                                                        //输入错误提示和输入错误总次数判断,限定三次
  323.                                  {
  324.                                                 Write_LCD(0,1,"                ");                //清除该行
  325.                                                 delay1(10);
  326.                                                 Write_LCD(0,1,"Wrong Retry!");                                //输入错误提示
  327.                                           for(j=0;j<sizeof(passwordtemp);j++)   //清除输入的错误密码
  328.                                               passwordtemp[j]='\0';
  329.                                           inputtimes++;                                                                                                        //连续输入错误,则次数累加
  330.                                                 i=0;
  331.                                                         if(inputtimes==3)
  332.                                                                 {
  333.                                                                         Write_LCD(0,1,"                ");//清除该行
  334.                                                                         delay1(10);
  335.                                                                         Write_LCD(0,1,"Wrong 3 times!");//密码错误,提示重新输入
  336.                                                                         while(1)
  337.                                                                                 P2=light2;                                                                                                 //停止该位置,重启电源后才能输入,实际实用中则需要等到一定时间后才能再次输入。
  338.                                                                 }
  339.                                  }
  340.                                         else
  341.                                         {
  342.                                                                 Write_LCD(0,1,"                ");//清除该行
  343.                                                                 delay1(10);
  344.                                                                 Write_LCD(0,1,"Right Open!>>>>");//密码正确显示的信息
  345.                                                                 P2=light1;
  346.                                                                 inputtimes=0;//输入正确则次数清零,重新计数
  347.                                                                 Flag=0;      //清除正确标志
  348.                                                                 i=0;
  349.                                                                
  350.                                         }
  351. }

  352. //--------------------------------------------------------修改密码时的密码验证--------------------------------------------------------

  353. void SetPassword()                                                                                                                                                                                                                                        //设置新密码时,先验证
  354. { while(1)
  355.         { num=KeyPro();  //扫描键盘
  356.            if(num!=0xff)  //如果扫描是按键有效值则进行处理
  357.                         {
  358.                                 if(i==0)
  359.                                         Write_LCD(0,1,"                ");//清除该行
  360.                                 if(num=='f')                                                                                                                                                                                        //确定键按下,进入判断密码对错
  361.                                         {
  362.                                                 i=0;
  363.                                                 if(flag1)
  364.                                                         m=sizeof(newpassword);
  365.                                                 else
  366.                                                         m=sizeof(password);
  367.                                                         n=sizeof(passwordtemp);
  368.                                  
  369.                                                 if(m==n)                                                                                                        //长度判断
  370.                                                 { if(flag1)
  371.                                                                 for(j=0;j<sizeof(passwordtemp);j++)                                                                //是否一一对应
  372.                                                         { if(passwordtemp[j]==newpassword[j])
  373.                                                                         Flag=0;
  374.                                                                 else
  375.                                                                         { Flag=1;
  376.                                                                                 break;
  377.                                                                         }
  378.                                                         }
  379.                                                         for(j=0;j<sizeof(passwordtemp);j++)                                                                //是否一一对应
  380.                                                         { if(passwordtemp[j]==password[j])
  381.                                                                         Flag=0;
  382.                                                                 else
  383.                                                                         { Flag=1;
  384.                                                                                 break;
  385.                                                                         }
  386.                                                         }
  387.                                                 }
  388.                                  else
  389.                                  {  Flag=1;
  390.                                           Write_LCD(0,1,"                ");                //清除该行
  391.                                                 delay1(10);
  392.                                                 Write_LCD(0,1,"Wrong length!");                                //密码正确显示的信息
  393.                                           delay1(10);
  394.                                                 i=0;
  395.                                           P2=light2;
  396.                                           inputtimes++;
  397.                                          
  398.                                  }
  399.                                  if(Flag)                                                                                                                                        //输入错误提示和输入错误总次数判断,限定三次
  400.                                  {
  401.                                                 Write_LCD(0,1,"                ");                //清除该行
  402.                                                 delay1(10);
  403.                                                 Write_LCD(0,1,"Wrong Retry!");                                //密码错误
  404.                                           for(j=0;j<sizeof(passwordtemp);j++)
  405.                                               passwordtemp[j]='\0';
  406.                                           inputtimes++;                                                                                                        //连续输入错误,则次数累加
  407.                                                         if(inputtimes==3)
  408.                                                                 {
  409.                                                                         Write_LCD(0,1,"                ");//清除该行
  410.                                                                         delay1(10);
  411.                                                                         Write_LCD(0,1,"Wrong 3 times!");//密码错误,提示重新输入
  412.                                                                         while(1)
  413.                                                                                 P2=light2;                                                                                                 //停止该位置,重启电源后才能输入,实际实用中则需要等到一定时间后才能再次输入。
  414.                                                                 }
  415.                                  }
  416.                                         else
  417.                                         {
  418.                                                                 Write_LCD(0,1,"                ");//清除该行
  419.                                                                 delay1(10);
  420.                                                                 Write_LCD(0,1,"Right Password!");//密码正确
  421.                                                                 RuningLight();
  422.                                                                 i=0;
  423.                                                                 inputtimes=0;//输入正确则次数清零,重新计数
  424.                                                                 Flag=0;      //清除正确标志
  425.                                                                 break;
  426.                                         }
  427.                         }
  428.                                 
  429.                         else                                                                                                                                                                 //没有按确定键,保存键值
  430.                         {
  431.                                 if(i<16)
  432.                                 {
  433.                                         passwordtemp[i]=num;                                                                                //保存密码
  434.                                         DisplayOneChar(i,1,num);                                                                //输入的密码用"*"代替
  435.                                         i++;                                                                                                                                                //计数,不能超过16位
  436.                                 }
  437.                                 else
  438.                                 {        Write_LCD(0,1,"                ");//清除该行
  439.                                         delay1(10);
  440.                                         Write_LCD(0,1,"Too Many Retry");
  441.                                         inputtimes++;
  442.                                         i=0;        
  443.                                         P2=light2;
  444.                                 }
  445.                         }
  446. }
  447. }
  448. }

  449. //--------------------------------------------------------新密码输入--------------------------------------------------------

  450. void NewPasswordInput()                                                                                                                                                                                                        //新密码输入
  451. {
  452.                                 while(1)
  453.                                 {        num=KeyPro();  //扫描键盘
  454.                                         if(num!=0xff)  //如果扫描是按键有效值则进行处理
  455.                                         {
  456.                                                 if(i==0)
  457.                                                         Write_LCD(0,1,"                ");//清除该行
  458.                                                 if(num=='f')
  459.                                                   { i=0;
  460.                                                                 RuningLight();
  461.                                                                 break;
  462.                                                         }
  463.                                                 else if(i<16)                                                                                                                                                        //新密码不能超过16位
  464.                                                         {
  465.                                                                 newpassword[i]=num;                                                                                //保存密码
  466.                                                                 DisplayOneChar(i,1,num);                                                                //显示新密码
  467.                                                                 i++;                                                                                                                                                //计数,不能超过16位
  468.                                                         }
  469.                                                 else
  470.                                                         {        i=0;
  471.                                                                 Write_LCD(0,1,"                ");                        //清除该行
  472.                                                                 delay1(10);
  473.                                                                 Write_LCD(0,1,"Too Many Retry");                                //输入过多,报错
  474.                                                                 delay1(10);
  475.                                                                 for(j=0;j<sizeof(newpassword);j++)                        //清除新密码
  476.                                                                                 newpassword[j]='\0';
  477.                                                                 P2=light2;
  478.                                                                 Write_LCD(0,1,"                ");                                                                                        //清除该行
  479.                                                                 delay1(10);
  480.                                                                 Write_LCD(0,1,"new password!");                                                                                                 //重新输入新密码
  481.                                                                 delay1(10);
  482.                                                                
  483.                                                 }        
  484.                                         }
  485.                                 }
  486. }

  487. //--------------------------------------------------------确认修改的密码--------------------------------------------------------

  488. void AgainInput()                                                                                                                                                                                                                //新密码确认
  489. {
  490.         while(1)
  491.         {      
  492.                                         num=KeyPro();  //扫描键盘
  493.                                         if(num!=0xff)  //如果扫描是按键有效值则进行处理
  494.                                                         { if(i==0)
  495.                                                                         Write_LCD(0,1,"                ");//清除该行
  496.                                                                 if(num=='f')
  497.                                                                 {        
  498.                                                                                 i=0;
  499.                                                                                 n=sizeof(passwordtemp);
  500.                                                                                 m=sizeof(newpassword);
  501.                                                                                 if(m==n)                                                                                                        //长度判断
  502.                                                                                         {
  503.                                                                                                 for(j=0;j<sizeof(passwordtemp);j++)                                                                //是否一一对应
  504.                                                                                                         { if(passwordtemp[j]==newpassword[j])
  505.                                                                                                                 Flag=0;
  506.                                                                                                                 else
  507.                                                                                                                 { Flag=1;
  508.                                                                                                                         break;
  509.                                                                                                                 }
  510.                                                                                                         }
  511.                                                                                         }
  512.                                                                                 else
  513.                                                                                  Flag=1;
  514.                                                                                 if(Flag)                                                                                                                                        //输入错误提示和输入错误总次数判断,限定三次
  515.                                                                                         {
  516.                                                                                                 Write_LCD(0,1,"                ");                //清除该行
  517.                                                                                                 delay1(10);
  518.                                                                                                 Write_LCD(0,1,"Difference!!");                                //密码正确显示的信息
  519.                                                                                                 for(j=0;j<sizeof(passwordtemp);j++)                        //清除密码
  520.                                                                                                         passwordtemp[j]='\0';
  521.                                                                                                 i=0;
  522.                                                                                                 Flag=0;
  523.                                                                                                 P2=light2;
  524.                                                                                         }
  525.                                                                
  526.                                                                                 else
  527.                                                                                         {
  528.                                                                                                 Write_LCD(0,1,"                ");//清除该行
  529.                                                                                                 delay1(10);
  530.                                                                                                 Write_LCD(0,1,"Right!");                                        //密码正确显示的信息
  531.                                                                                                 delay1(10);
  532.                                                                                                 Write_LCD(0,1,"                ");//清除该行
  533.                                                                                                 delay1(10);
  534.                                                                                                 Write_LCD(0,1,"Finish!");        
  535.                                                                                                 RuningLight();
  536.                                                                                                 Write_LCD(0,1,"                ");//清除该行
  537.                                                                                                 delay1(10);
  538.                                                                                                 Write_LCD(0,1,"Right Open>>>");//清除该行
  539.                                                                                                 P2=light1;
  540.                                                                                                 inputtimes=0;//输入正确则次数清零,重新计数
  541.                                                                                                 Flag=0;      //清除正确标志
  542.                                                                                                 i=0;
  543.                                                                                                 break;
  544.                                                                                         }

  545.                                                                         }        
  546.                                                                 else if(i<16)                                                                                                                                                                                                        //密码不能超过16位
  547.                                                                                                 {
  548.                                                                                                         passwordtemp[i]=num;                                                                                //保存密码
  549.                                                                                                         DisplayOneChar(i,1,num);                                                                //显示新密码
  550.                                                                                                         i++;                                                                                                                                                //计数,不能超过16位
  551.                                                                                                 }
  552.                                                                                         else
  553.                                                                                                 {        Write_LCD(0,1,"                ");                        //清除该行
  554.                                                                                                         delay1(10);
  555.                                                                                                         Write_LCD(0,1,"Too Many Retry");                                //输入过多,报错
  556.                                                                                                         delay1(10);
  557.                                                                                                         for(j=0;j<sizeof(passwordtemp);j++)                        //清除密码
  558.                                                                                                         passwordtemp[j]='\0';
  559.                                                                                                         i=0;                                                                                                                                                //重新输入
  560.                                                                                                         P2=light2;
  561.                                                                                                         Write_LCD(0,1,"                ");                        //清除该行
  562.                                                                                                         delay1(10);
  563.                                                                                                         Write_LCD(0,1,"Input New Again!");                        //重新输入新密码
  564.                                                                                                         delay1(10);        
  565.                                                                                                 }
  566.                                                         }
  567.                                        
  568.                 }
  569.         }

  570. //--------------------------------------------------------主函数--------------------------------------------------------

  571. void main()
  572. {
  573.         initial();
  574.         Init_Lcd();         //初始化液晶屏
  575.         delay1(10);        //延时用于稳定,可以去掉
  576.         Write_LCD(0,0,"  Welcome! ");    //写入第一行信息,主循环中不再更改此信息,所以在while之前写入
  577.         delay1(10);
  578.         Write_LCD(0,1,"Input password!");    //写入第二行信息,提示输入密码
  579.         delay1(10);
  580. while (1)         //主循环
  581. {

  582.          num=KeyPro();  //扫描键盘
  583.          if(num!=0xff)  //如果扫描是按键有效值则进行处理
  584.            {
  585.                         if(i==0)
  586.                   Write_LCD(0,1,"                ");                                                                                                //清除该行
  587.                         if(num=='e')                                                                                                                                                                                        //设置新密码
  588.                         { P2=0xff;
  589.                                 for(j=0;j<sizeof(newpassword);j++)                                                                                        //释放存储新密码数组
  590.                                  newpassword[j] = '\0';                 
  591.                                 Write_LCD(0,1,"Set Password!");
  592.                                 delay1(10);
  593.                                 Write_LCD(0,1,"                ");                                                                                        //清除该行
  594.                                 delay1(10);
  595.                                 Write_LCD(0,1,"Input Password!");                                                                                                //用户验证
  596.                                 delay1(10);
  597.                                 SetPassword();                                                                                                                                                                        //验证密码
  598.                                 P2=0xff;
  599.                                         Write_LCD(0,1,"                ");                                                                                        //清除该行
  600.                                 delay1(10);
  601.                                 Write_LCD(0,1,"New Password!");                                                                                                         //新密码输入
  602.                                 delay1(10);
  603.                                 NewPasswordInput();                                                                                                                                                        //新密码输入
  604.                                 P2=0xff;
  605.                                 Write_LCD(0,1,"                ");               
  606.                                 delay1(10);
  607.                                 Write_LCD(0,1,"Again Input!!");
  608.                                 AgainInput();                                                                                                                                                                                //新密码确认
  609.                                 for(j=0;j<sizeof(passwordtemp);j++)                                                                                        //释放存储输入密码数组
  610.                                  passwordtemp[j] = '\0';
  611.                                  flag1=1;                                                                                                                                                                                                        //修改密码标志位        
  612.                         }
  613.                         else if(num=='f')                                                                                                                                                                                        //确定键按下,进入判断密码对错
  614.                                                 { i=0;                                                                                                                                                                                                        //清除输入标志
  615.                                                         VriefytPassword();                                                                                                                                                //密码认证
  616.                                                 }
  617.                                                 else if(num=='b')                                                                                                                                                                //上锁
  618.                                                 {
  619.                                                         P2=0xff;
  620.                                                         delay1(10);        
  621.                                                         Write_LCD(0,1,"                ");                                                                                        //清除该行
  622.                                                         delay1(10);
  623.                                                         Write_LCD(0,1,"Input password!");
  624.                                                         i=0;
  625.                                                         for(j=0;j<sizeof(passwordtemp);j++)
  626.                                                           passwordtemp[j] ='\0';                                                                        
  627.                                                 }
  628.                                                 else                                                                                                                                                                                                                //没有按确定键,上锁键,设置键,保存键值
  629.                                                 {
  630.                                                         if(i<16)
  631.                                                                 {
  632.                                                                         passwordtemp[i]=num;                                                                                //保存密码
  633.                                                                         DisplayOneChar(i,1,num);                                                                //输入的密码用"*"代替
  634.                                                                         i++;                                                                                                                                                //计数,不能超过16位
  635.                                                                 }
  636.                                                         else
  637.                                                                 {        Write_LCD(0,1,"                ");//清除该行
  638.                                                                         delay1(10);
  639.                                                                         Write_LCD(0,1,"Too Many Retry");
  640.                                                                         inputtimes++;
  641.                                                                         i=0;        
  642.                                                                 }
  643.                                                 }
  644.                 }
  645.         }
  646. }
复制代码

所有程序51hei提供下载:
基于STC51的简易密码锁.rar (50.08 KB, 下载次数: 19)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:510861 发表于 2020-7-30 21:26 | 只看该作者
沙发是我
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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