找回密码
 立即注册

QQ登录

只需一步,快速开始

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

根据别人的密码锁改成的红外遥控密码锁单片机源码

[复制链接]
跳转到指定楼层
楼主
可以使用键盘和红外遥控器切换使用



单片机源程序如下:
  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 <reg51.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=P3^7;                                //蜂鸣器
  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=1;break;
  73.                                 case 0xed:key=2;break;
  74.                                 case 0xeb:key=3;break;
  75.                                 case 0xe7:key=10;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=4;break;
  107.                                 case 0xdd:key=5;break;
  108.                                 case 0xdb:key=6;break;
  109.                                 case 0xd7:key=11;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=8;break;
  142.                                 case 0xbb:key=9;break;
  143.                                 case 0xb7:key=12;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=15;break;
  175.                                 case 0x7d:key=0;break;
  176.                                 case 0x7b:key=14;break;
  177.                                 case 0x77:key=13;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 0x12: key = 0 ;break;        //POWER        //ON                       
  199.                                                  case 0x09: key = 1 ;break;        //MUTE //OFF
  200.                                                  case 0x1d: key = 2 ;break;        //0-9键控制
  201.                                                  case 0x1F: key = 3 ;break;        //

  202.                                                  case 0x0d: key = 4 ;break;                                       
  203.                                                  case 0x19: key = 5 ;break;
  204.                                                  case 0x1b: key = 6 ;break;
  205.                         case 0x11: key = 7 ;break;
  206.                                
  207.                                                  case 0x15: key = 8 ;break;       
  208.                                                  case 0x17: key = 9 ;break;       
  209.                                                  case 0x14: key = 10;break;        //A
  210.                                                  case 0x57: key = 11;break; //B
  211.                                        
  212.                                              case 0x53: key = 12;break;
  213.                                //                case 0x41: key = 13;break; //D
  214.                         case 0x46: key = 14;break; //#
  215.                                               case 0x52: key = 15;break;
  216.                        }
  217.                                          biaozhi=0;
  218.                                          hongwai=1;
  219.      
  220.      }

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

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

  227.   
  228. /***************************************/
  229. uchar code line1_data[] = {"   KEY  LOCK    "};           //定义第1行显示的字符                              
  230. uchar code line2_data[] = {" MADE IN CHINA  "};                 //定义第2行显示的字符      
  231. /********以下是输入密码画面信息********/
  232. uchar code in_line1[] = {"  PLEASE INPUT  "};           //定义第1行显示的字符                              
  233. uchar code in_line2[] = {"PASSWORD:------ "};                 //定义第2行显示的字符      
  234. /********以下是密码输入正确信息********/
  235. uchar code inok_line1[] = {"INPUT PASSWORD "};           //定义第1行显示的字符                              
  236. uchar code inok_line2[] = {"   INOPUT OK    "};         //定义第2行显示的字符  
  237. /********以下是密码输入错误信息********/
  238. uchar code inerr_line1[] = {"INPUT PASSWORD "};           //定义第1行显示的字符                              
  239. uchar code inerr_line2[] = {"   INPUT ERR    "};                 //定义第2行显示的字符      
  240. /********以下是密码设置画面信息********/
  241. uchar code modify_line1[] = {"MODIFY PASSWORD "};           //定义第1行显示的字符                              
  242. uchar code modify_line2[] = {"PASSWORD:------ "};                 //定义第2行显示的字符      
  243. /********以下是密码设置正确信息********/
  244. uchar code setok_line1[] = {"MODIFY PASSWORD "};           //定义第1行显示的字符                              
  245. uchar code setok_line2[] = {"   MODIFY OK     "};                 //定义第2行显示的字符      
  246. /********以下是开机画面显示函数********/
  247. void StartDisp()
  248. {
  249.         uchar i;
  250.         lcd_clr();                                                  //调清屏函数
  251.         lcd_wcmd(0x00|0x80);                           //设置显示位置为第1行第0列
  252.           i = 0;                                                               
  253.           while(line1_data[i] != '\0')                      //若没有到达第1行字符串尾部
  254.           {                             
  255.                   lcd_wdat(line1_data[i]);               //显示第1行字符   
  256.                   i++;                               //指向下一字符                                         
  257.           }                                                                     
  258.           lcd_wcmd(0x40|0x80);                  //设置显示位置为第2行第0列            
  259.           i = 0;                                                               
  260.           while(line2_data[i] != '\0')                  //若没有到达第2行字符串尾部
  261.           {                                                                     
  262.                   lcd_wdat(line2_data[i]);               //显示第2行字符   
  263.                    i++;                                       //指向下一字符
  264.         }
  265. }
  266. /********以下是密码输入画面显示函数********/
  267. void CodeInDisp()
  268. {
  269.         uchar i;
  270.         lcd_clr();                                          //调清屏函数
  271.         lcd_wcmd(0x00|0x80);                   //设置显示位置为第1行第0列
  272.           i = 0;                                                               
  273.           while(in_line1[i] != '\0')              //若没有到达第1行字符串尾部
  274.           {                             
  275.                   lcd_wdat(in_line1[i]);      //显示第1行字符   
  276.                   i++;                     //指向下一字符                                         
  277.           }                                                                     
  278.           lcd_wcmd(0x40|0x80);          //设置显示位置为第2行第0列            
  279.           i = 0;                                                               
  280.           while(in_line2[i] != '\0')                  //若没有到达第2行字符串尾部
  281.           {                                                                     
  282.                   lcd_wdat(in_line2[i]);     //显示第2行字符   
  283.                    i++;                               //指向下一字符
  284.         }
  285. }
  286. /********以下是密码输入错误显示函数********/
  287. void CodeInErr()
  288. {
  289.         uchar i;
  290.         lcd_clr();                                                  //调清屏函数
  291.         lcd_wcmd(0x00|0x80);                           //设置显示位置为第1行第0列
  292.           i = 0;                                                               
  293.           while(inerr_line1[i] != '\0')                      //若没有到达第1行字符串尾部
  294.           {                             
  295.                   lcd_wdat(inerr_line1[i]);       //显示第1行字符   
  296.                   i++;                               //指向下一字符                                         
  297.           }                                                                     
  298.           lcd_wcmd(0x40|0x80);                  //设置显示位置为第2行第0列            
  299.           i = 0;                                                               
  300.           while(inerr_line2[i] != '\0')                  //若没有到达第2行字符串尾部
  301.           {                                                                     
  302.                   lcd_wdat(inerr_line2[i]);               //显示第2行字符   
  303.                    i++;                                       //指向下一字符
  304.         }
  305. }
  306. /********以下是密码输入正确显示函数********/
  307. void CodeInOk()
  308. {
  309.         uchar i;
  310.         lcd_clr();                                                  //调清屏函数
  311.         lcd_wcmd(0x00|0x80);                           //设置显示位置为第1行第0列
  312.           i = 0;                                                               
  313.           while(inok_line1[i] != '\0')                      //若没有到达第1行字符串尾部
  314.           {                             
  315.                   lcd_wdat(inok_line1[i]);       //显示第1行字符   
  316.                   i++;                               //指向下一字符                                         
  317.           }                                                                     
  318.           lcd_wcmd(0x40|0x80);                  //设置显示位置为第2行第0列            
  319.           i = 0;                                                               
  320.           while(inok_line2[i] != '\0')                  //若没有到达第2行字符串尾部
  321.           {                                                                     
  322.                   lcd_wdat(inok_line2[i]);       //显示第2行字符   
  323.                    i++;                                       //指向下一字符
  324.         }
  325. }
  326. /********以下是密码设置画面显示函数********/
  327. void CodeSetDisp()
  328. {
  329.         uchar i;
  330.         lcd_clr();                                                  //调清屏函数
  331.         lcd_wcmd(0x00|0x80);                           //设置显示位置为第1行第0列
  332.           i = 0;                                                               
  333.           while(modify_line1[i] != '\0')              //若没有到达第1行字符串尾部
  334.           {                             
  335.                   lcd_wdat(modify_line1[i]);       //显示第1行字符   
  336.                   i++;                               //指向下一字符                                         
  337.           }                                                                     
  338.           lcd_wcmd(0x40|0x80);                  //设置显示位置为第2行第0列            
  339.           i = 0;                                                               
  340.           while(modify_line2[i] != '\0')                  //若没有到达第2行字符串尾部
  341.           {                                                                     
  342.                   lcd_wdat(modify_line2[i]);       //显示第2行字符   
  343.                    i++;                                       //指向下一字符
  344.         }
  345. }
  346. /********以下是密码设置正确显示函数********/
  347. void CodeSetOk()
  348. {
  349.         uchar i;
  350.         lcd_clr();                                                  //调清屏函数
  351.         lcd_wcmd(0x00|0x80);                           //设置显示位置为第1行第0列
  352.           i = 0;                                                               
  353.           while(setok_line1[i] != '\0')                      //若没有到达第1行字符串尾部
  354.           {                             
  355.                   lcd_wdat(setok_line1[i]);       //显示第1行字符   
  356.                   i++;                               //指向下一字符                                         
  357.           }                                                                     
  358.           lcd_wcmd(0x40|0x80);                  //设置显示位置为第2行第0列            
  359.           i = 0;                                                               
  360.           while(setok_line2[i] != '\0')                  //若没有到达第2行字符串尾部
  361.           {                                                                     
  362.                   lcd_wdat(setok_line2[i]);       //显示第2行字符   
  363.                    i++;                                       //指向下一字符
  364.         }
  365. }
  366. /********以下是密码输入函数********/
  367. void PassIn()
  368. {
  369.         static        uchar lcd_x=0;                        //显示指针,注意是静态局部变量
  370.         static         uchar count=0;                        //密码计数器        ,注意是静态局部变量
  371.         static uchar code_n=0;                        //密码次数
  372. PASSWORD:        lcd_clr();                          //调清屏函数
  373.         CodeInDisp();//密码输入画面函数
  374.         do{  
  375. /**********修改1***********/
  376.                 P1=0xf0;
  377.                 if(P1!=0xf0)                                //若有按键按下
  378.                 {
  379.                         MatrixKey();                        //调矩阵按键扫描函数
  380.                         P1=0xf0;               
  381.                         while(P1!=0xf0);//等待按键松开
  382. /***************************/
  383.                         if((key>=0)&&(key<=9))        //若按下是的0~9键(即密码只能是数字,字母键A~F无效)
  384.                         {
  385.                                 incode_buf[count]=key;        //将键值存入数组
  386.                                 lcd_wcmd((0x49+lcd_x)|0x80);   //设置显示位置为第2行第9+lcd_x列
  387.                                 lcd_wdat(0x2a);                           //显示为"*",0x2a是"*"的LCD显示码
  388.                                         count++;                                //输入下一位密码
  389.                                         lcd_x++;                                //指向LCD的下一位置
  390.                                 }
  391.                         }
  392.                 }while(count<6);        //密码设置为6位
  393.                 if(count>=6){count=0;lcd_x=0;}       
  394.                 if(memcmp(incode_buf,code_buf,6)==0)        //若两个数组相等,则返回值为0,注意这里不能用strcmp函数进行比较
  395.                 {
  396.                         CodeInOk();                                //若输入的密码正确,则显示输入正确的信息
  397.                         beep();beep();beep();                //输入正确后,蜂鸣器响三声
  398.                         flag_comp=1;                        //密码比较标志位置1
  399.                         code_n=0;                                //密码计数器清0
  400.                         RELAY=0;                                //打开继电器,开锁
  401.                 }
  402.                 else if(memcmp(incode_buf,code_buf,6)!=0)//若输入的密码不正确
  403.                 {
  404.                         code_n++;                                //密码计数器加1       
  405.                         if(code_n>=3)                        //有三次输入的机会
  406.                         {
  407.                                 CodeInErr();                        //若三次输入均错误,显示密码错误信息
  408.                                 flag_comp=0;                //密码比较标志位清0
  409.                                 code_n=0;                        //密码计数器清0
  410.                         }
  411.                         else goto PASSWORD;                        //若还有机会输入密码,则跳转到标号PASSWORD处继续输入
  412.                 }       
  413. }
  414. /********以下是红外线密码输入函数**********************************************************************************/

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

  463. /********以下是密码设置函数*******************************************************************************************************/
  464. void PassSet()
  465. {
  466.         static        uchar  lcd_x=0;                        //显示指针,注意是静态局部变量
  467.         static         uchar count=0;                        //密码计数器        ,注意是静态局部变量
  468.         lcd_clr();                                          //调清屏函数
  469.         CodeSetDisp();                                //密码设置画面函数
  470.         do{
  471. /********修改2**************/
  472.                 P1=0xf0;
  473.                 if(P1!=0xf0)                                //若有按键按下
  474.                 {
  475.                         MatrixKey();                        //调矩阵按键扫描函数
  476.                         P1=0xf0;               
  477.                         while(P1!=0xf0);//等待按键松开
  478. /**********************/
  479.                         if((key>=0)&&(key<=9))        //若按下是的0~9键(即密码只能是数字,字母键A~F无效)
  480.                         {
  481.                                 code_buf[count]=key;                //将键值存入数组code_buf[]中
  482.                                 lcd_wcmd((0x49+lcd_x)|0x80);   //设置显示位置为第2行第9+lcd_x列
  483.                                 lcd_wdat(code_buf[count]+0x30);        //将输入的密码通过LCD显示出来       
  484.                                 count++;                                //输入下一位密码
  485.                                 lcd_x++;                                //指向LCD的下一位置
  486.               
  487.                         }
  488.                 }
  489.         }while(count<6);                //密码设置为6位
  490.         if(count>=6){count=0;lcd_x=0;}
  491.         beep();beep();beep();        //输入完毕后,蜂鸣器响三声
  492.         write_nbyte(0xa0,0x00,code_buf,6);        //将数组code_buf[]中的6位密码写入24cxx从00开始的单元中
  493.         lcd_clr();                                          //调清屏函数
  494.         CodeSetOk();                                        //密码设置正确画面函数
  495. }
  496. /********************************************红外密码设置函数****************************************************************/
  497. void PassSethongwai()

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

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

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

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

  575.                
  576.                 }

  577. }
  578. /********以下是主函数********/
  579. void main()
  580. {
  581.         EA=1;EX0=1;                 //允许总中断中断,使能 INT0 外部中断
  582.   IT0 = 1;                               //触发方式为脉冲负边沿触发
  583.   IRIN=1;                            //遥控输入脚置1

  584.         TMOD=0x01;                         //定时器T0方式1
  585.   TH0=0xee; TL0=0x00;              //5ms定时初值
  586.    ET0=1;                        //开总中断,开定时器T0中断
  587.         Delay_ms(10);                                                            
  588.         lcd_init();                                  //调LCD初始化函数
  589.   I2C_init();                                //调I2C总线初始化函数(在I2C总线驱动程序软件包中)

  590.    kaijimoshi();
  591. START:        RELAY=1;                        //继电器关断
  592.         lcd_clr();
  593.         StartDisp();                                //开机画面显示函数
  594.         read_nbyte (0xa0,0x00,code_buf,6);//从24Cxx的0x00开始的单元中读出6个密码存入code_buf[]数组中
  595.         P1=0xf0;

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

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

  632.    DSCAN:        MatrixKey();                        //调矩阵按键扫描函数
  633.         if(key!=0x0a)goto DSCAN;                //若按下的不是A键,跳转到标号SCAN处继续扫描
  634.         TR0=1;                                //启动定时器T0
  635.         Delay_ms(500);                        //延时500ms               
  636.         beep();                                //蜂鸣器响一声
  637.         if(flag_2s==1)flag_2s=0;                //若2s到,则将 2s标志位清0
  638.         else goto  DSCAN;                        //若2s未到,则跳转到标号SCAN处继续扫描
  639.         PassIn();                                //调密码输入函数
  640.         /******************************************/
  641.         while(1)
  642.         {
  643.                 if(flag_comp==1)                //若输入的密码正确
  644.                 {
  645.                         MatrixKey();                //扫描按键
  646.                         if(key==0x0b)        //在密码正确的情况下若按下了B键
  647.                         {
  648.                                 PassSet();        //若按下的是B键,调密码设置函数
  649.                                 MatrixKey();        //扫描按键
  650.                                 if(key==0x0e)goto START;//若按下了E键,则跳转到标志START处重新开始
  651.                         }
  652.                         if(key==0x0e)goto START;        //若按下了E键,则跳转到标志START处重新开始
  653.                 }
  654.                 if(flag_comp==0)                                //若输入的密码不正确
  655.                 {
  656.                         MatrixKey();                        //扫描按键
  657.                         if(key==0x0e)goto START;//若按下的是E键,跳转到标号START处重新开始
  658.                 }
  659.         }

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



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

  719.   
  720. /******************************************************************/
  721.   hongwai=0;
  722. ……………………

  723. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
1602_lock.rar (7.2 KB, 下载次数: 100)


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

使用道具 举报

沙发
ID:244988 发表于 2019-3-12 11:50 | 只看该作者
我是直接复制程序过来的,一编译就这样了。。。求教

微信图片_20190312114700.png (17.87 KB, 下载次数: 34)

错误提示截图

错误提示截图
回复

使用道具 举报

板凳
ID:244988 发表于 2019-3-12 14:04 | 只看该作者
大佬,能不能教我解决这个问题呀,超出了限制我要改哪里呀??是改工程还是改程序?程序我就真的不会了,我现在是用的AT89C52来创建的工程。

微信图片_20190312114700.png (17.87 KB, 下载次数: 23)

微信图片_20190312114700.png
回复

使用道具 举报

地板
ID:362792 发表于 2019-11-10 12:18 来自手机 | 只看该作者
这个程序的密码存入了202可是没找到密码到底是多少
回复

使用道具 举报

5#
ID:842473 发表于 2020-11-18 09:27 来自手机 | 只看该作者
能发一下proteus的仿真图嘛
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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