找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2066|回复: 1
收起左侧

这个一个单片机密码锁程序请教这里面的密码是怎样的设置的?

[复制链接]
ID:362792 发表于 2019-11-10 13:35 | 显示全部楼层 |阅读模式
  1. /***************************************************************
  2. 此程序是在电子密码锁的基础上增加的红外遥控功能
  3. 采用STC89C52单片机
  4. 外中断口P3.2为红外接收头接口
  5. 红外和键盘两种模式转换用P2.3控制,0为键盘模式,1为红外输入
  6. 遥控器使用常用的HT6122核心的
  7. 液晶用1602         引脚定义在I2C_drive.h中
  8. 存储器采用的24C04 引脚定义在I2C_drive.h中
  9. P1口接4X4矩阵按键
  10. ****************************************************************/
  11. #include<reg52.h>
  12. #include <string.h>
  13. #include "I2C_drive.h"                        //包含I2C总线驱动程序软件包
  14. #include "LCD_drive.h"                        //包含I2C总线驱动程序软件包
  15. #define uchar unsigned char
  16. #define uint unsigned int
  17. uchar code_buf[6];                                //存储器密码缓冲区
  18. uchar incode_buf[6];                                //输入密码缓冲区
  19. uchar IR_buf[4]={0x00,0x00,0x00,0x00};//IR_buf[0]、IR_buf[1]为用户码低位、用户码高位接收缓冲区
  20.                                                 // IR_buf[2]、IR_buf[3]为键数据码和键数据码反码接收缓冲区
  21. uchar  key;                               //键顺序码
  22. uchar  temp;                                        //暂存
  23. sbit  BEEP=P1^5;                                //蜂鸣器
  24. sbit  RELAY=P3^6;                                //继电器
  25. sbit IRIN = P3^2;                         //遥控输入脚   红外
  26. sbit panduan=P2^3;         //红外,键盘转换引脚,接地为键盘模式,悬空为红外模式

  27. uchar count_5ms,sec;                                //5ms和1s计数器
  28. bit flag_2s=0;                                        //2s标志位,2s时间到,该位置1
  29. bit flag_comp=0;                                //比较对错标志位,比较正确,该标志位置1
  30. bit biaozhi=0;
  31. bit hongwai=1;
  32. bit jianpan=1;
  33. /******************************************************************************/
  34. void Delay(int num){//延时函数
  35.         while(num--) ;
  36. }        



  37. void  beep(){//-扬声器--按键音
  38.         unsigned char a;//定义变量用于发声的长度设置
  39.         for(a=100;a>0;a--){//声音的长度
  40.                 BEEP = ~BEEP;
  41.                 Delay(50);//音调设置延时
  42.         }
  43.         BEEP = 1;//音乐结束后扬声器拉高关闭
  44. }               
  45. /********以下是0.14ms的x倍延时函数********/
  46. void delayy(uchar x)            //延时x*0.14ms
  47. {
  48. uchar i;
  49. while(x--)
  50.    for (i = 0; i<13; i++);
  51. }
  52. /********以下是矩阵按键扫描函数********/
  53. void  MatrixKey()
  54. {
  55.         P1=0xff;                                
  56.         P1=0xef;                                //置第1行P1.4为低电平,开始扫描第1行
  57.         temp=P1;                                //读P1口按键
  58.         temp=temp & 0x0f;                        //判断低4位是否有0,即判断列线(P1.0~P1.3)是否有0
  59.         if (temp!=0x0f)                        //若temp不等于0x0f,说明有键按下
  60.         {
  61.                 Delay_ms(20);                //延时10ms去抖               
  62.                 temp=P1;                        //再读取P1口按键
  63.                 temp=temp & 0x0f;                //再判断列线(P1.0~P1.3)是否有0
  64.                 if (temp!=0x0f)                //若temp不等于0x0f,说明确实有键按下
  65.                 {
  66.                         temp=P1;                        //读取P1口按键,开始判断键值
  67.                         biaozhi=1;
  68.                         hongwai=1;
  69.          jianpan=0;
  70.                         switch(temp)
  71.                         {
  72.                                 case 0xee:key=15;break;
  73.                                 case 0xed:key=14;break;
  74.                                 case 0xeb:key=13;break;
  75.                                 case 0xe7:key=12;break;
  76.                         }
  77.                         temp=P1;                        //将读取的键值送temp
  78.                         beep();                        //蜂鸣器响一声
  79.                         temp=temp & 0x0f;                //取出列线值(P1.0~P1.3)
  80.                         while(temp!=0x0f)                //若temp不等于0x0f,说明按键还没有释放,继续等待
  81.                         {
  82.                   biaozhi=0;
  83.             jianpan=1;
  84.                                 temp=P1;                //若按键释放,再读取P1口
  85.                                 temp=temp & 0x0f;// 判断列线(P1.0~P1.3)是否有0
  86.                         }
  87.                 }
  88.         }
  89.         P1=0xff;
  90.         P1=0xdf;                                        //置第2行P1.5为低电平,开始扫描第2行
  91.         temp=P1;
  92.         temp=temp & 0x0f;
  93.         if (temp!=0x0f)
  94.         {
  95.                 Delay_ms(20);        
  96.                 temp=P1;
  97.                 temp=temp & 0x0f;
  98.                 if (temp!=0x0f)
  99.                 {
  100.                         temp=P1;
  101.                         biaozhi=1;
  102.                                hongwai=1;
  103.                                          jianpan=0;
  104.                         switch(temp)
  105.                         {
  106.                                 case 0xde:key=11;break;
  107.                                 case 0xdd:key=10;break;
  108.                                 case 0xdb:key=9;break;
  109.                                 case 0xd7:key=8;break;
  110.                         }
  111.                         temp=P1;
  112.                         beep();
  113.                         temp=temp & 0x0f;
  114.                         while(temp!=0x0f)
  115.                         {
  116.                           biaozhi=0;
  117.                           jianpan=1;
  118.                           temp=P1;
  119.                           temp=temp & 0x0f;
  120.                         }
  121.                 }
  122.         }
  123.         P1=0xff;
  124.         P1=0xbf;                                                //置第3行P1.6为低电平,开始扫描第3行
  125.         temp=P1;
  126.         temp=temp & 0x0f;
  127.         if (temp!=0x0f)
  128.         {
  129.                 Delay_ms(20);        
  130.                 temp=P1;
  131.                 temp=temp & 0x0f;
  132.                 if (temp!=0x0f)
  133.                 {
  134.                         temp=P1;
  135.                         biaozhi=1;
  136.                          hongwai=1;
  137.                          jianpan=0;
  138.                         switch(temp)
  139.                         {
  140.                                 case 0xbe:key=7;break;
  141.                                 case 0xbd:key=6;break;
  142.                                 case 0xbb:key=5;break;
  143.                                 case 0xb7:key=4;break;
  144.                         }
  145.                         temp=P1;
  146.                         beep();
  147.                         temp=temp & 0x0f;
  148.                         while(temp!=0x0f)
  149.                         {
  150.                           biaozhi=0;
  151.                           jianpan=1;
  152.                                 temp=P1;
  153.                                 temp=temp & 0x0f;
  154.                         }
  155.                 }
  156.         }
  157.         P1=0xff;
  158.         P1=0x7f;                                        //置第4行P1.7为低电平,开始扫描第4行
  159.         temp=P1;
  160.         temp=temp & 0x0f;
  161.         if (temp!=0x0f)
  162.         {
  163.                 Delay_ms(20);
  164.                 temp=P1;
  165.                 temp=temp & 0x0f;
  166.                 if (temp!=0x0f)
  167.                 {
  168.                         temp=P1;
  169.                         biaozhi=1;
  170.          hongwai=1;
  171.                         jianpan=0;
  172.                         switch(temp)
  173.                         {
  174.                                 case 0x7e:key=3;break;
  175.                                 case 0x7d:key=2;break;
  176.                                 case 0x7b:key=1;break;
  177.                                 case 0x77:key=0;break;
  178.                         }
  179.                         temp=P1;
  180.                         beep();
  181.                         temp=temp & 0x0f;
  182.                         while(temp!=0x0f)
  183.                         {
  184.                           biaozhi=0;
  185.                           jianpan=1;
  186.                                 temp=P1;
  187.                                 temp=temp & 0x0f;
  188.                         }
  189.                 }
  190.         }
  191. }
  192. /*********************红外按键矩阵函数*************************************************************************************************/
  193. void hongwaijvzhen ()
  194. {

  195.   if(hongwai==0)
  196.    {
  197.        switch (IR_buf[2]){
  198.                                                  case 0x16: key = 0 ;break;        //POWER        //ON                        
  199.                                                  case 0x0c: key = 1 ;break;        //MUTE //OFF
  200.                                                  case 0x18: key = 2 ;break;        //0-9键控制
  201.                                                  case 0x5e: key = 3 ;break;        //

  202.                                                  case 0x08: key = 4 ;break;                                       
  203.                                                  case 0x1c: key = 5 ;break;
  204.                                                  case 0x5a: key = 6 ;break;
  205.                                                  case 0x11: key = 7 ;break;

  206.                                                  case 0x52: key = 8 ;break;        
  207.                                                  case 0x4a: key = 9 ;break;        
  208.                                                  case 0x45: key = 10;break;        //A
  209.                                                  case 0x46: key = 11;break; //B
  210.                                                  case 0x47: key = 12;break;
  211.                                                  case 0x44: key = 13;break; //D
  212.                                                  case 0x40: key = 14;break; //#
  213.                                                  case 0x43: key = 15;break;
  214.                        }
  215.                                          biaozhi=0;
  216.                                          hongwai=1;

  217.      }

  218. }
  219. /********以下是开机画面信息********/
  220. uchar code jianpan1_data[] = {"    << KEY >>   "};           //定义第1行显示的字符                              
  221. uchar code jianpan2_data[] = {"   PATTERN(1)   "};                 //定义第2行显示的字符  

  222. uchar code hongwai1_data[] = {"  << REMOTE >>  "};           //定义第1行显示的字符                              
  223. uchar code hongwai2_data[] = {"   PATTERN(2)   "};                 //定义第2行显示的字符  


  224. /***************************************/
  225. uchar code line1_data[] = {"   KEY  LOCK    "};           //定义第1行显示的字符                              
  226. uchar code line2_data[] = {" MADE IN  CHINA  "};                 //定义第2行显示的字符      
  227. /********以下是输入密码画面信息********/
  228. uchar code in_line1[] = {"  PLEASE INPUT  "};           //定义第1行显示的字符                              
  229. uchar code in_line2[] = {"PASSWORD:------ "};                 //定义第2行显示的字符      
  230. /********以下是密码输入正确信息********/
  231. uchar code inok_line1[] = {"INPUT PASSWORD "};           //定义第1行显示的字符                              
  232. uchar code inok_line2[] = {"   INOPUT OK    "};         //定义第2行显示的字符  
  233. /********以下是密码输入错误信息********/
  234. uchar code inerr_line1[] = {"INPUT PASSWORD "};           //定义第1行显示的字符                              
  235. uchar code inerr_line2[] = {"   INPUT ERR    "};                 //定义第2行显示的字符      
  236. /********以下是密码设置画面信息********/
  237. uchar code modify_line1[] = {"MODIFY PASSWORD "};           //定义第1行显示的字符                              
  238. uchar code modify_line2[] = {"PASSWORD:------ "};                 //定义第2行显示的字符      
  239. /********以下是密码设置正确信息********/
  240. uchar code setok_line1[] = {"MODIFY PASSWORD "};           //定义第1行显示的字符                              
  241. uchar code setok_line2[] = {"   MODIFY OK     "};                 //定义第2行显示的字符      
  242. /********以下是开机画面显示函数********/
  243. void StartDisp()
  244. {
  245.         uchar i;
  246.         lcd_clr();                                                  //调清屏函数
  247.         lcd_wcmd(0x00|0x80);                           //设置显示位置为第1行第0列
  248.           i = 0;                                                               
  249.           while(line1_data[i] != '\0')                      //若没有到达第1行字符串尾部
  250.           {                             
  251.                   lcd_wdat(line1_data[i]);               //显示第1行字符   
  252.                   i++;                               //指向下一字符                                         
  253.           }                                                                     
  254.           lcd_wcmd(0x40|0x80);                  //设置显示位置为第2行第0列            
  255.           i = 0;                                                               
  256.           while(line2_data[i] != '\0')                  //若没有到达第2行字符串尾部
  257.           {                                                                     
  258.                   lcd_wdat(line2_data[i]);               //显示第2行字符   
  259.                    i++;                                       //指向下一字符
  260.         }
  261. }
  262. /********以下是密码输入画面显示函数********/
  263. void CodeInDisp()
  264. {
  265.         uchar i;
  266.         lcd_clr();                                          //调清屏函数
  267.         lcd_wcmd(0x00|0x80);                   //设置显示位置为第1行第0列
  268.           i = 0;                                                               
  269.           while(in_line1[i] != '\0')              //若没有到达第1行字符串尾部
  270.           {                             
  271.                   lcd_wdat(in_line1[i]);      //显示第1行字符   
  272.                   i++;                     //指向下一字符                                         
  273.           }                                                                     
  274.           lcd_wcmd(0x40|0x80);          //设置显示位置为第2行第0列            
  275.           i = 0;                                                               
  276.           while(in_line2[i] != '\0')                  //若没有到达第2行字符串尾部
  277.           {                                                                     
  278.                   lcd_wdat(in_line2[i]);     //显示第2行字符   
  279.                    i++;                               //指向下一字符
  280.         }
  281. }
  282. /********以下是密码输入错误显示函数********/
  283. void CodeInErr()
  284. {
  285.         uchar i;
  286.         lcd_clr();                                                  //调清屏函数
  287.         lcd_wcmd(0x00|0x80);                           //设置显示位置为第1行第0列
  288.           i = 0;                                                               
  289.           while(inerr_line1[i] != '\0')                      //若没有到达第1行字符串尾部
  290.           {                             
  291.                   lcd_wdat(inerr_line1[i]);       //显示第1行字符   
  292.                   i++;                               //指向下一字符                                         
  293.           }                                                                     
  294.           lcd_wcmd(0x40|0x80);                  //设置显示位置为第2行第0列            
  295.           i = 0;                                                               
  296.           while(inerr_line2[i] != '\0')                  //若没有到达第2行字符串尾部
  297.           {                                                                     
  298.                   lcd_wdat(inerr_line2[i]);               //显示第2行字符   
  299.                    i++;                                       //指向下一字符
  300.         }
  301. }
  302. /********以下是密码输入正确显示函数********/
  303. void CodeInOk()
  304. {
  305.         uchar i;
  306.         lcd_clr();                                                  //调清屏函数
  307.         lcd_wcmd(0x00|0x80);                           //设置显示位置为第1行第0列
  308.           i = 0;                                                               
  309.           while(inok_line1[i] != '\0')                      //若没有到达第1行字符串尾部
  310.           {                             
  311.                   lcd_wdat(inok_line1[i]);       //显示第1行字符   
  312.                   i++;                               //指向下一字符                                         
  313.           }                                                                     
  314.           lcd_wcmd(0x40|0x80);                  //设置显示位置为第2行第0列            
  315.           i = 0;                                                               
  316.           while(inok_line2[i] != '\0')                  //若没有到达第2行字符串尾部
  317.           {                                                                     
  318.                   lcd_wdat(inok_line2[i]);       //显示第2行字符   
  319.                    i++;                                       //指向下一字符
  320.         }
  321. }
  322. /********以下是密码设置画面显示函数********/
  323. void CodeSetDisp()
  324. {
  325.         uchar i;
  326.         lcd_clr();                                                  //调清屏函数
  327.         lcd_wcmd(0x00|0x80);                           //设置显示位置为第1行第0列
  328.           i = 0;                                                               
  329.           while(modify_line1[i] != '\0')              //若没有到达第1行字符串尾部
  330.           {                             
  331.                   lcd_wdat(modify_line1[i]);       //显示第1行字符   
  332.                   i++;                               //指向下一字符                                         
  333.           }                                                                     
  334.           lcd_wcmd(0x40|0x80);                  //设置显示位置为第2行第0列            
  335.           i = 0;                                                               
  336.           while(modify_line2[i] != '\0')                  //若没有到达第2行字符串尾部
  337.           {                                                                     
  338.                   lcd_wdat(modify_line2[i]);       //显示第2行字符   
  339.                    i++;                                       //指向下一字符
  340.         }
  341. }
  342. /********以下是密码设置正确显示函数********/
  343. void CodeSetOk()
  344. {
  345.         uchar i;
  346.         lcd_clr();                                                  //调清屏函数
  347.         lcd_wcmd(0x00|0x80);                           //设置显示位置为第1行第0列
  348.           i = 0;                                                               
  349.           while(setok_line1[i] != '\0')                      //若没有到达第1行字符串尾部
  350.           {                             
  351.                   lcd_wdat(setok_line1[i]);       //显示第1行字符   
  352.                   i++;                               //指向下一字符                                         
  353.           }                                                                     
  354.           lcd_wcmd(0x40|0x80);                  //设置显示位置为第2行第0列            
  355.           i = 0;                                                               
  356.           while(setok_line2[i] != '\0')                  //若没有到达第2行字符串尾部
  357.           {                                                                     
  358.                   lcd_wdat(setok_line2[i]);       //显示第2行字符   
  359.                    i++;                                       //指向下一字符
  360.         }
  361. }
  362. /********以下是密码输入函数********/
  363. void PassIn()
  364. {
  365.         static        uchar lcd_x=0;                        //显示指针,注意是静态局部变量
  366.         static         uchar count=0;                        //密码计数器        ,注意是静态局部变量
  367.         static uchar code_n=0;                        //密码次数
  368. PASSWORD:

  369.       lcd_clr();                          //调清屏函数
  370.         CodeInDisp();//密码输入画面函数
  371.         do{  
  372. /**********修改1***********/
  373.                 P1=0xf0;
  374.                 if(P1!=0xf0)                                //若有按键按下
  375.                 {
  376.                         MatrixKey();                        //调矩阵按键扫描函数
  377.                         P1=0xf0;               
  378.                         while(P1!=0xf0);//等待按键松开
  379. /***************************/
  380.                         if((key>=0)&&(key<=9))        //若按下是的0~9键(即密码只能是数字,字母键A~F无效)
  381.                         {
  382.                                 incode_buf[count]=key;        //将键值存入数组
  383.                                 lcd_wcmd((0x49+lcd_x)|0x80);   //设置显示位置为第2行第9+lcd_x列
  384.                                 lcd_wdat(0x2a);                           //显示为"*",0x2a是"*"的LCD显示码
  385.                                         count++;                                //输入下一位密码
  386.                                         lcd_x++;                                //指向LCD的下一位置
  387.                                 }
  388.                         }
  389.                 }while(count<6);        //密码设置为6位
  390.                 if(count>=6){count=0;lcd_x=0;}        
  391.                 if(memcmp(incode_buf,code_buf,6)==0)        //若两个数组相等,则返回值为0,注意这里不能用strcmp函数进行比较
  392.                 {
  393.                         CodeInOk();                                //若输入的密码正确,则显示输入正确的信息
  394.                         beep();beep();beep();                //输入正确后,蜂鸣器响三声
  395.                         flag_comp=1;                        //密码比较标志位置1
  396.                         code_n=0;                                //密码计数器清0
  397.                         RELAY=0;                                //打开继电器,开锁
  398.                 }
  399.                 else if(memcmp(incode_buf,code_buf,6)!=0)//若输入的密码不正确
  400.                 {
  401.                         code_n++;                                //密码计数器加1        
  402.                         if(code_n>=3)                        //有三次输入的机会
  403.                         {
  404.                                 CodeInErr();                        //若三次输入均错误,显示密码错误信息
  405.                                 flag_comp=0;                //密码比较标志位清0
  406.                                 code_n=0;                        //密码计数器清0
  407.                         }
  408.                         else goto PASSWORD;                        //若还有机会输入密码,则跳转到标号PASSWORD处继续输入
  409.                 }        
  410. }
  411. /********以下是红外线密码输入函数**********************************************************************************/

  412. void PassInhongwai()
  413. {
  414.         static        uchar lcd_x=0;                        //显示指针,注意是静态局部变量
  415.         static         uchar count=0;                        //密码计数器        ,注意是静态局部变量
  416.         static uchar code_n=0;                        //密码次数
  417. PASSWORD:       lcd_clr();                          //调清屏函数
  418.         CodeInDisp();//密码输入画面函数
  419.         do{  
  420. /**********修改1***********/

  421.                 if(hongwai==0)                                //若有按键按下
  422.                 {
  423.                   hongwaijvzhen();                        //调矩阵按键扫描函数

  424.                         while(!hongwai);//等待按键松开
  425. /***************************/
  426.                         if((key>=0)&&(key<=9))        //若按下是的0~9键(即密码只能是数字,字母键A~F无效)
  427.                         {
  428.                                 incode_buf[count]=key;        //将键值存入数组
  429.                                 lcd_wcmd((0x49+lcd_x)|0x80);   //设置显示位置为第2行第9+lcd_x列
  430.                                 lcd_wdat(0x2a);                           //显示为"*",0x2a是"*"的LCD显示码
  431.                                         count++;                                //输入下一位密码
  432.                                         lcd_x++;                                //指向LCD的下一位置
  433.                beep();
  434.                                 }
  435.                         }
  436.                 }while(count<6);        //密码设置为6位
  437.                 if(count>=6){count=0;lcd_x=0;}        
  438.                 if(memcmp(incode_buf,code_buf,6)==0)        //若两个数组相等,则返回值为0,注意这里不能用strcmp函数进行比较
  439.                 {
  440.                         CodeInOk();                                //若输入的密码正确,则显示输入正确的信息
  441.                         beep();beep();beep();                //输入正确后,蜂鸣器响三声
  442.                         flag_comp=1;                        //密码比较标志位置1
  443.                         code_n=0;                                //密码计数器清0
  444.                         RELAY=0;                                //打开继电器,开锁
  445.                 }
  446.                 else if(memcmp(incode_buf,code_buf,6)!=0)//若输入的密码不正确
  447.                 {
  448.                         code_n++;                                //密码计数器加1        
  449.                         if(code_n>=3)                        //有三次输入的机会
  450.                         {
  451.                                 CodeInErr();                        //若三次输入均错误,显示密码错误信息
  452.                                 flag_comp=0;                //密码比较标志位清0
  453.                                 code_n=0;                        //密码计数器清0
  454.                         }
  455.                         else goto PASSWORD;                        //若还有机会输入密码,则跳转到标号PASSWORD处继续输入
  456.                 }        
  457. }

  458. /********以下是密码设置函数*******************************************************************************************************/
  459. void PassSet()
  460. {
  461.         static        uchar  lcd_x=0;                        //显示指针,注意是静态局部变量
  462.         static         uchar count=0;                        //密码计数器        ,注意是静态局部变量
  463.         lcd_clr();                                          //调清屏函数
  464.         CodeSetDisp();                                //密码设置画面函数
  465.         do{
  466. /********修改2**************/
  467.                 P1=0xf0;
  468.                 if(P1!=0xf0)                                //若有按键按下
  469.                 {
  470.                         MatrixKey();                        //调矩阵按键扫描函数

  471.                                         P1=0xf0;               
  472.                         while(P1!=0xf0);//等待按键松开
  473. /**********************/
  474.                         if((key>=0)&&(key<=9))        //若按下是的0~9键(即密码只能是数字,字母键A~F无效)
  475.                         {
  476.                                 code_buf[count]=key;                //将键值存入数组code_buf[]中
  477.                                 lcd_wcmd((0x49+lcd_x)|0x80);   //设置显示位置为第2行第9+lcd_x列
  478.                                 lcd_wdat(code_buf[count]+0x30);        //将输入的密码通过LCD显示出来        
  479.                                 count++;                                //输入下一位密码
  480.                                 lcd_x++;                                //指向LCD的下一位置

  481.                         }
  482.                 }
  483.         }while(count<6);                //密码设置为6位
  484.         if(count>=6){count=0;lcd_x=0;}
  485.         beep();beep();beep();        //输入完毕后,蜂鸣器响三声
  486.         write_nbyte(0xa0,0x00,code_buf,6);        //将数组code_buf[]中的6位密码写入24cxx从00开始的单元中
  487.         lcd_clr();                                          //调清屏函数
  488.         CodeSetOk();                                        //密码设置正确画面函数
  489. }
  490. /********************************************红外密码设置函数****************************************************************/
  491. void PassSethongwai()

  492. {
  493.         static        uchar  lcd_x=0;                        //显示指针,注意是静态局部变量
  494.         static         uchar count=0;                        //密码计数器        ,注意是静态局部变量
  495.         lcd_clr();                                          //调清屏函数
  496.         CodeSetDisp();                                //密码设置画面函数
  497.         do{
  498. /********修改2**************/

  499.                 if(hongwai==0)                                //若有按键按下
  500.                 {
  501.                   hongwaijvzhen();                        //调矩阵按键扫描函数

  502.                         while(!hongwai);//等待按键松开
  503. /**********************/
  504.                         if((key>=0)&&(key<=9))        //若按下是的0~9键(即密码只能是数字,字母键A~F无效)
  505.                         {
  506.                                 code_buf[count]=key;                //将键值存入数组code_buf[]中
  507.                                 lcd_wcmd((0x49+lcd_x)|0x80);   //设置显示位置为第2行第9+lcd_x列
  508.                                 lcd_wdat(code_buf[count]+0x30);        //将输入的密码通过LCD显示出来        
  509.                                 count++;                                //输入下一位密码
  510.                                 lcd_x++;                                //指向LCD的下一位置
  511.                                 beep();
  512.                         }
  513.                 }
  514.         }while(count<6);                //密码设置为6位
  515.         if(count>=6){count=0;lcd_x=0;}
  516.         beep();beep();beep();        //输入完毕后,蜂鸣器响三声
  517.         write_nbyte(0xa0,0x00,code_buf,6);        //将数组code_buf[]中的6位密码写入24cxx从00开始的单元中
  518.         lcd_clr();                                          //调清屏函数
  519.         CodeSetOk();                                        //密码设置正确画面函数
  520. }
  521. /****************开机初始模式显示函数******************************************/
  522. void kaijimoshi()
  523.     {

  524.     if(panduan==0) //如果P2.3脚接地显示《KEY》
  525.            {           //                 PATTERN(1)

  526.         uchar i;
  527.         lcd_clr();                                                  //调清屏函数
  528.         lcd_wcmd(0x00|0x80);                           //设置显示位置为第1行第0列
  529.           i = 0;                                                               
  530.           while(jianpan1_data[i] != '\0')                      //若没有到达第1行字符串尾部
  531.           {                             
  532.                   lcd_wdat(jianpan1_data[i]);               //显示第1行字符   
  533.                   i++;                               //指向下一字符                                         
  534.           }                                                                     
  535.           lcd_wcmd(0x40|0x80);                  //设置显示位置为第2行第0列            
  536.           i = 0;                                                               
  537.           while(jianpan2_data[i] != '\0')                  //若没有到达第2行字符串尾部
  538.           {                                                                     
  539.                   lcd_wdat(jianpan2_data[i]);               //显示第2行字符   
  540.                    i++;                                       //指向下一字符
  541.         }
  542.    Delay_ms(3000);     //延时3秒
  543.    lcd_clr();

  544.                 }


  545.           if(panduan==1)   //如果P2.3脚悬空显示《REMOTE》
  546.             {             //                  PATTERN(2)
  547.         uchar i;
  548.         lcd_clr();                                                  //调清屏函数
  549.         lcd_wcmd(0x00|0x80);                           //设置显示位置为第1行第0列
  550.           i = 0;                                                               
  551.           while(hongwai1_data[i] != '\0')                      //若没有到达第1行字符串尾部
  552.           {                             
  553.                   lcd_wdat(hongwai1_data[i]);               //显示第1行字符   
  554.                   i++;                               //指向下一字符                                         
  555.           }                                                                     
  556.           lcd_wcmd(0x40|0x80);                  //设置显示位置为第2行第0列            
  557.           i = 0;                                                               
  558.           while(hongwai2_data[i] != '\0')                  //若没有到达第2行字符串尾部
  559.           {                                                                     
  560.                   lcd_wdat(hongwai2_data[i]);               //显示第2行字符   
  561.                    i++;                                       //指向下一字符
  562.         }
  563.       Delay_ms(3000);      //延时3秒
  564.        lcd_clr();


  565.                 }

  566. }
  567. /********以下是主函数********/
  568. void main()
  569. {
  570.    EA=1;EX0=1;                 //允许总中断中断,使能 INT0 外部中断
  571.    IT0 = 1;                               //触发方式为脉冲负边沿触发
  572.    IRIN=1;                            //遥控输入脚置1
  573.    TMOD=0x01;                         //定时器T0方式1
  574.    TH0=0xee;
  575.    TL0=0x00;              //5ms定时初值
  576.    ET0=1;                        //开总中断,开定时器T0中断
  577.    Delay_ms(10);                                                            
  578.    lcd_init();                                  //调LCD初始化函数
  579.    I2C_init();                                //调I2C总线初始化函数(在I2C总线驱动程序软件包中)
  580.    kaijimoshi();
  581. START:  RELAY=1;                        //继电器关断
  582.         lcd_clr();
  583.         StartDisp();                                //开机画面显示函数
  584.         read_nbyte (0xa0,0x00,code_buf,6);//从24Cxx的0x00开始的单元中读出6个密码存入code_buf[]数组中
  585.         P1=0xf0;

  586.         while((P1==0xf0)&&(hongwai==0));                        //如果红外和键盘不是同时按下,就进入到下一步,否则等待
  587. MatrixKey();

  588. /*******************************执行红外模式密码锁方式****************************************************************************/
  589. if(panduan==1)
  590.   {
  591.      SCAN:        hongwaijvzhen ();                        //调矩阵按键扫描函数
  592.         if(key!=0x0a)goto SCAN;                //若按下的不是A键,跳转到标号SCAN处继续扫描
  593.         TR0=1;                                //启动定时器T0
  594.         Delay_ms(500);                        //延时500ms               
  595.         beep();                                //蜂鸣器响一声
  596.         if(flag_2s==1)flag_2s=0;                //若2s到,则将 2s标志位清0
  597.         else goto SCAN;                        //若2s未到,则跳转到标号SCAN处继续扫描        
  598.          PassInhongwai();                                          //调红外密码输入函数
  599.         while(1)
  600.         {
  601.                 if(flag_comp==1)                //若输入的密码正确
  602.                 {        
  603.          hongwaijvzhen ();
  604.                         if(key==0x0b)        //在密码正确的情况下若按下了B键
  605.                         {                        
  606.           PassSethongwai();          //        调红外密码设置函数               
  607.             hongwaijvzhen ();
  608.                                 if(key==0x0e)goto START;//若按下了E键,则跳转到标志START处重新开始
  609.                         }
  610.                         if(key==0x0e)goto START;        //若按下了E键,则跳转到标志START处重新开始
  611.                 }
  612.                 if(flag_comp==0)                                //若输入的密码不正确
  613.                 {                        
  614.         hongwaijvzhen ();
  615.                          if(key==0x0e)goto START;//若按下的是E键,跳转到标号START处重新开始
  616.                 }
  617.         }
  618. }
  619. /************************执行键盘输入密码锁模式**********************************************************************************************/
  620. if(panduan==0)
  621.   {

  622.    DSCAN:        MatrixKey();                        //调矩阵按键扫描函数
  623.         if(key!=0x0a)goto DSCAN;                //若按下的不是A键,跳转到标号SCAN处继续扫描
  624.         TR0=1;                                //启动定时器T0
  625.         Delay_ms(500);                        //延时500ms               
  626.         beep();                                //蜂鸣器响一声
  627.         if(flag_2s==1)flag_2s=0;                //若2s到,则将 2s标志位清0
  628.         else goto  DSCAN;                        //若2s未到,则跳转到标号SCAN处继续扫描
  629.         PassIn();                                //调密码输入函数
  630.         /******************************************/
  631.         while(1)
  632.         {
  633.                 if(flag_comp==1)                //若输入的密码正确
  634.                 {

  635.                         MatrixKey();                //扫描按键
  636.                         if(key==0x0b)        //在密码正确的情况下若按下了B键
  637.                         {
  638.                                 PassSet();        //若按下的是B键,调密码设置函数
  639.                                 MatrixKey();        //扫描按键
  640.                                 if(key==0x0e)goto START;//若按下了E键,则跳转到标志START处重新开始
  641.                         }
  642.                         if(key==0x0e)goto START;        //若按下了E键,则跳转到标志START处重新开始
  643.                 }
  644.                 if(flag_comp==0)                                //若输入的密码不正确
  645.                 {
  646.                         MatrixKey();                        //扫描按键
  647.                          if(key==0x0e)goto START;//若按下的是E键,跳转到标号START处重新开始
  648.                 }
  649.         }

  650. }
  651. }
  652. /********以下是定时器T0中断函数********/
  653. void timer0() interrupt 1
  654. {
  655.         TH0=0xee;TL0=0x00;                //重装5ms定时初值
  656.   count_5ms++;                        //5ms 计数值加1
  657.   if(count_5ms==200)                //若count_5ms为200,说明1s到(200×0ms=1000ms)
  658.   {
  659.           count_5ms=0;                // count_5ms清0
  660.                 sec++;                           //秒计数器加1
  661.         }
  662.   if(sec==2)
  663.         {
  664.                 flag_2s=1;                        //若2s到,将2s标志位置1
  665.                 TR0=0;                        //关断定时器T0
  666.         }
  667. }
  668. /********以下是外中断0函数********/
  669. void IR_decode() interrupt 0
  670. {
  671.         uchar j,k,count=0;
  672.   EX0 = 0;                           //暂时关闭外中断0中断请求



  673.         delayy(20);                        //延时20*0.14=2.8ms
  674.         if (IRIN==1)                         //等待 IRIN低电平出现
  675.   {
  676.                  EX0 =1;                //开外中断0
  677.                    return;                //中断返回
  678.         }                                                            
  679.   while (!IRIN) delayy(1);   //等待IRIN变为高电平,跳过9ms的低电平引导码
  680.         for (j=0;j<4;j++)         //收集四组数据,即用户码低位、用户码高位、键值数据码和键值数码反码
  681.          {
  682.           for (k=0;k<8;k++)                        //每组数据有8位
  683.           {
  684.                    while (IRIN)            //等待IRIN变为低电平,跳过4.5ms的高电平引导码信号。
  685.                      delayy(1);
  686.                         while (!IRIN)          //等待IRIN变为高电平
  687.                      delayy(1);
  688.                      while (IRIN)           //对IRIN高电平时间进行计数
  689.                       {
  690.                             delayy(1);                //延时0.14ms
  691.                             count++;          //对0.14ms延时时间进行计数
  692.                             if (count>=30)        
  693.                                  {
  694.                                         EX0=1;                //开外中断0
  695.                                          return;        //0.14ms计数过长则返回
  696.                                 }                  
  697.                       }   
  698.                      IR_buf[j]=IR_buf[j] >> 1;                  //若计数小于6,数据最高位补"0",说明收到的是"0"
  699.                      if (count>=6) {IR_buf[j] = IR_buf[j] | 0x80;}  //若计数大于等于6,数据最高位补"1",说明收到的是"1"
  700.                      count=0;                                        //计数器清0        
  701.           }
  702. }
  703.         if (IR_buf[2]!=~IR_buf[3])                //将键数据反码取反后与键数据码码比较,若不等,表示接收数据错误,放弃
  704.          {

  705.      EX0 = 1;                         //开外中断0
  706.         return;
  707. }


  708. /******************************************************************/
  709.   hongwai=0;
  710.           beep();                        //蜂鸣器响一声
  711.   EX0 = 1;                         //开外中断0
  712.   biaozhi=1;
  713.   jianpan=1;
  714. }
复制代码
回复

使用道具 举报

ID:702039 发表于 2020-3-3 22:31 | 显示全部楼层
带验证码的怎么设置
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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