找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 415|回复: 9
收起左侧

51单片机密码锁,有代码有原理图,继电器和蜂鸣器没有反应

[复制链接]
ID:1152013 发表于 2025-5-28 20:46 | 显示全部楼层 |阅读模式
屏幕截图 2025-05-28 204021.png

单片机源程序如下:
  1. #include<REG51.h>
  2. #include<intrins.h>


  3. #define LCM_Data P0   //将P0口定义为LCM_Data
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. //1602的控制脚
  7. sbit lcd1602_rs=P2^5;//RS引脚为寄存器(1-数据寄存器,0-命令寄存器)
  8. sbit lcd1602_rw=P2^6;//RW为读写操作引脚(1-读,0-写)
  9. sbit lcd1602_en=P2^7;//使能信号
  10. sbit Scl=P3^4;       //24c02串行时钟
  11. sbit Sda=P3^5;       //24c02串行数据
  12. sbit ALAM=P2^1;      //报警,蜂鸣器
  13. sbit KEY=P3^6;       //开锁
  14. bit pass=0;          //密码正确标志
  15. bit ReInputEn=0;     //重置输入允许标志
  16. bit s3_keydown=0;    //3秒按键标志位
  17. bit key_disable=0;   //锁定键盘标志

  18. unsigned char countt0,second; //t0中断次数,秒计数
  19. //void Delay5Ms(void);      //声明延时函数
  20. unsigned char code a[]={0xFE,0xFD,0xFB,0xF7};//控盘扫描控制表
  21. //液晶显示数据数组
  22. unsigned char code start_line[] = {"password:       "};
  23. unsigned char code name[]       = {"===Coded Lock==="}; //显示名称
  24. unsigned char code Correct[]    = {"     correct    "};//输入正确
  25. unsigned char code Error[]      = {"      error     "};//输入错误
  26. unsigned char code codepass[]   = {"       pass     "};
  27. unsigned char code LockOpen[]   = {"       open     "};//open
  28. unsigned char code SetNew[]     = {"SetNewWordEnable"};
  29. unsigned char code Input[]      = {"input:          "};//input
  30. unsigned char code ResetOK[]    = {"ResetPasswordOK "};
  31. unsigned char code initword[]   = {"Init password..."};
  32. unsigned char code Er_try[]     = {"error,try again!"};
  33. unsigned char code again[]      = {"input again     "};

  34. unsigned char InputData[6];//输入密码暂存区
  35. unsigned char CurrentPassword[6]={0,0,0,0,0,0};//读取EEPROM密码暂存数组
  36. unsigned char TempPassword[6];
  37. unsigned char N=0;//密码输入位数计数
  38. unsigned char ErrorCont;//错误次数计数
  39. unsigned char CorrectCont;//正确输入计数
  40. unsigned char ReInputCont;//重新输入计数
  41. unsigned char code initpassword[6]={0,0,0,0,0,0};//输入管理员密码后将密码初始为000000
  42. unsigned char code adminpassword[6]={1,3,1,4,2,0};//输入管理员密码后将密码初始为000000

  43. #include<delay.h>

  44. //=========================5ms延时==========================
  45. void Delay5Ms(void)
  46. {
  47.         unsigned int TempCyc = 5552;
  48.         while(TempCyc--);
  49. }

  50. //===========================400ms延时============================
  51. void Delay400Ms(void)
  52. {
  53.         unsigned char TempCycA = 5;
  54.         unsigned int TempCycB;
  55.         while(TempCycA--)
  56.         {
  57.                 TempCycB=7269;
  58.                 while(TempCycB--);
  59.         }
  60. }

  61. //===========================24c02===========================

  62. void mDelay(uint t)//延时
  63. {
  64.         uchar i;
  65.         while(t--)
  66.         {
  67.                 for(i=0;i<125;i++)
  68.                 {;}
  69.         }
  70. }
  71. void Nop(void)//空操作
  72. {
  73.         _nop_();       //仅作延时用一条语句大约1us
  74.         _nop_();
  75.         _nop_();
  76.         _nop_();
  77. }




  78. /*****24c02程序参照24c02时序图
  79. /*起始条件*/

  80. void Start(void)
  81. {
  82.         Sda=1;
  83.         Scl=1;
  84.         Nop();
  85.         Sda=0;
  86.         Nop();
  87. }

  88. //停止条件
  89. void Stop(void)
  90. {
  91.         Sda=0;
  92.         Scl=1;
  93.         Nop();
  94.         Sda=1;
  95.         Nop();
  96. }

  97. //应答位
  98. void Ack(void)
  99. {
  100.         Sda=0;
  101.         Nop();
  102.         Scl=1;
  103.         Nop();
  104.         Scl=0;
  105. }

  106. //反向应答位
  107. void NoAck(void)
  108. {
  109.         Sda=1;
  110.         Nop();
  111.         Scl=1;
  112.         Nop();
  113.         Scl=0;
  114. }




  115. //发送数据子程序,Data为要求发送的数据
  116. void Send(uchar Data)
  117. {
  118.         uchar BitCounter=8;
  119.         uchar temp;
  120.         do
  121.         {
  122.                 temp=Data;//将待发送数据暂存temp
  123.                 Scl=0;
  124.                 Nop();
  125.                 if((temp&0x80)==0x80)//将读到的数据&0x80
  126.                         Sda=1;
  127.                 else
  128.                         Sda=0;
  129.                 Scl=1;
  130.                 temp=Data<<1;//数据左移
  131.                 Data=temp;//数据左移后重新赋值Data
  132.                 BitCounter--;//该变量减到0时,数据也就传送完成了
  133.         }
  134.         while(BitCounter);//判断是否传送完成
  135.         Scl=0;
  136. }

  137. //读一字节的数据,并返回该字节值
  138. uchar Read(void)
  139. {
  140.         uchar temp=0;
  141.         uchar temp1=0;
  142.         uchar BitCounter=8;
  143.         Sda=1;
  144.         do
  145.         {
  146.                 Scl=0;
  147.                 Nop();
  148.                 Scl=1;
  149.                 Nop();
  150.                 if(Sda)              //数据位是否为1
  151.                         temp=temp|0x01;    //为1 temp的最低位为1(|0x01,就是将最低位变为1)
  152.                 else                 //如果为0
  153.                         temp=temp&0xfe;    //temp最低位为0(&0xfe(11111110)最地位就是0)
  154.                 if(BitCounter-1)     //BitCounter减1后是否为真
  155.                 {
  156.                         temp1=temp<<1;     //temp左移
  157.                         temp=temp1;
  158.                 }
  159.                 BitCounter--;        //BitCounter减到0时,数据就接收完了
  160.         }while(BitCounter);    //判断是否接收完成
  161.         return(temp);
  162. }



  163. void WrToROM(uchar Data[],uchar Address,uchar Num)
  164. {
  165.         uchar i;
  166.         uchar *PData;
  167.         PData=Data;
  168.         for(i=0;i<Num;i++)
  169.         {
  170.                 Start();
  171.                 Send(0xa0);
  172.                 Ack();
  173.                 Send(Address+i);
  174.                 Ack();
  175.                 Send(*(PData+i));
  176.                 Ack();
  177.                 Stop();
  178.                 mDelay(20);
  179.         }
  180. }
  181. void RdFromROM(uchar Data[],uchar Address,uchar Num)
  182. {
  183.         uchar i;
  184.         uchar *PData;
  185.         PData=Data;
  186.         for(i=0;i<Num;i++)
  187.         {
  188.                 Start();
  189.                 Send(0xa0);
  190.                 Ack();
  191.                 Send(Address+i);
  192.                 Ack();
  193.                 Start();
  194.                 Send(0xa1);
  195.                 Ack();
  196.                 *(PData+i)=Read();
  197.                 Scl=0;
  198.                 NoAck();
  199.                 Stop();
  200.         }
  201. }





  202. //=============================LCD1603==============================
  203. #define yi 0x80   //LCD第一行的初始位置,因为LCD1602字符地址首位D7恒定为1
  204. #define er 0x80+0x40   //LCD第二行初始位置(因为第二行第一个字符位置地址是0x40)

  205. //-----------------延时函数,后面经常调用-------------------------------
  206. void delay(uint xms)//延时函数,有参函数
  207. {
  208.   uint x,y;
  209.         for(x=xms;x>0;x--)
  210.         for(y=110;y>0;y--);
  211. }

  212. //===============写指令======================
  213. void write_1602com(uchar com)   //液晶写入指令函数
  214. {
  215.         lcd1602_rs=0;   //数据/指令选择置为指令
  216.         lcd1602_rw=0;   //读写选择置为写
  217.         P0=com;         //送入数据
  218.         delay(1);
  219.         lcd1602_en=1;  //拉高使能端,为制造有效的下降沿做准备
  220.         delay(1);
  221.         lcd1602_en=0;  //en由高变低。产生下降沿,液晶执行命令
  222. }


  223. //=============================写数据==================================
  224. void write_1602dat(uchar dat)   //液晶写入数据函数
  225. {
  226.         lcd1602_rs=1;  //数据/指令选择置为数据
  227.         lcd1602_rw=0;  //读写选择置为写
  228.   P0=dat;        //送入数据
  229.         delay(1);
  230.         lcd1602_en=1;  //en置高电平,为制造下降沿做准备
  231.         delay(1);
  232.         lcd1602_en=0;  //en由高变低,产生下降沿,液晶执行命令
  233. }
  234. //===================================初始化=========================================
  235. void lcd_init(void)
  236. {
  237.         write_1602com(0x38);  //设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据
  238.         write_1602com(0x0c);  //开显示不显示光标
  239.   write_1602com(0x06);  //整屏不移动,光标自动右移
  240.   write_1602com(0x01);  //清显示
  241. }
  242. //========================================
  243. //=================================================================
  244. //===============将按键值编码为数值============================
  245. unsigned char coding(unsigned char m)
  246. {
  247.         unsigned char k;
  248.         switch(m)
  249.         {
  250.                 case(0x11):k=1;break;
  251.                 case(0x21):k=2;break;
  252.                 case(0x41):k=3;break;
  253.           case(0x81):k='A';break;
  254.           case(0x12):k=4;break;
  255.           case(0x22):k=5;break;
  256.           case(0x42):k=6;break;
  257.           case(0x82):k='B';break;
  258.           case(0x14):k=7;break;
  259.           case(0x24):k=8;break;
  260.           case(0x44):k=9;break;
  261.           case(0x84):k='C';break;
  262.           case(0x18):k='*';break;
  263.           case(0x28):k=0;break;
  264.           case(0x48):k='#';break;
  265.           case(0x88):k='D';break;
  266.         }
  267.         return(k);
  268. }



  269. //====================按键检测并返回按键值========================
  270. unsigned char keynum(void)
  271. {
  272.         unsigned char row,col,i;
  273.         P1=0xf0;  //所有行线为0,列线为输入
  274.         if((P1&0xf0)!=0xf0)  //一旦有键被按下,列线上的四位便不再全为1
  275.         {
  276.                 Delay5Ms();
  277.                 Delay5Ms();
  278.                 if((P1&0xf0)!=0xf0)  //如果有键被按下
  279.                 {
  280.                         col=P1^0xf0;   //确定列线,任何一个数(0,1)与1异或,结果取反,与0异或,结果为其本身
  281.                   i=0;
  282.                   P1=a[i];  //精确定位
  283.                   while(i<4)  //逐行扫描
  284.                         {
  285.                                 if((P1&0xf0)!=0xf0)
  286.                                 {
  287.                                         row=~(P1&0xff);  //确定行线
  288.                             break;  //已定位后提前退出
  289.                                 }
  290.                                 else
  291.                                 {
  292.                                          i++;
  293.                              P1=a[i];
  294.                                 }
  295.                         }
  296.                 }
  297.                 else
  298.                 {
  299.                         return 0;
  300.                 }
  301.                 while((P1&0xf0)!=0xf0);
  302.     return(col|row);  //行线与列线组合后返回
  303.         }
  304.         else return 0;  //无键按下时返回0
  305. }


  306. //===================一声提示音,表示有效输入=============================
  307. void OneAlam(void)
  308. {
  309.         ALAM=0;
  310.         Delay5Ms();
  311.         ALAM=1;
  312. }
  313. //====================两声提示音,表示操作成功===============================
  314. void TwoAlam(void)
  315. {
  316.         ALAM=0;
  317.         Delay5Ms();
  318.         ALAM=1;
  319.         Delay5Ms();
  320.         ALAM=0;
  321.         Delay5Ms();
  322.         ALAM=1;
  323. }
  324. //====================三声提示音,表示错误=============================
  325. void ThreeAlam(void)
  326. {
  327.         ALAM=0;
  328.         Delay5Ms();
  329.         ALAM=1;
  330.         Delay5Ms();
  331.         ALAM=0;
  332.         Delay5Ms();
  333.         ALAM=1;
  334.         Delay5Ms();
  335.         ALAM=0;
  336.         Delay5Ms();
  337.         ALAM=1;
  338. }
  339. //====================一直响,表示错误=============================

  340. void Alam_KeyUnable(void){
  341.                 ALAM=0;         //提示音一直响
  342. }


  343. //==================显示提示输入==============================
  344. void DisplayChar(void)
  345. {
  346.         unsigned char i;
  347.         if(pass==1)
  348.         {
  349.                 write_1602com(er);   //在二行开始显示
  350.                 for(i=0;i<16;i++)
  351.                 {
  352.                         write_1602dat(LockOpen[i]);   //显示open,开锁成功
  353.                 }
  354.         }
  355.         else
  356.         {
  357.                 if(N==0)   //输入密码位数
  358.                 {
  359.                         write_1602com(er);
  360.                   for(i=0;i<16;i++)
  361.                         {
  362.                                 write_1602dat(Error[i]);  //显示错误
  363.                         }
  364.                 }
  365.                 else
  366.                 {
  367.                         write_1602com(er);
  368.                         for(i=0;i<16;i++)
  369.                         {
  370.                                 write_1602dat(start_line[i]);   //显示开始输入
  371.                         }
  372.                 }
  373.         }
  374. }
  375.                         



  376. //========================确认键,并通过相应标志位执行相应功能
  377. void Ensure(void)
  378. {
  379.         unsigned char i,j;
  380.         RdFromROM(CurrentPassword,0,6);  //从24c02里读出存储密码
  381.         if(N==6)
  382.         {
  383.             if(ReInputEn==0)   //重置密码功能未开启
  384.                         {
  385.                                 if((CurrentPassword[0]==InputData[0])&&(CurrentPassword[1]==InputData[1])&&(CurrentPassword[2]==InputData[2])&&(CurrentPassword[3]==InputData[3])&&(CurrentPassword[4]==InputData[4]))
  386.                                 {
  387.                                         ErrorCont=0;   //只要密码正确了就将错误次数清零
  388.                                         CorrectCont++;   //输入正确变量++
  389.                                         if(CorrectCont==1)
  390.                                         {
  391.                                           write_1602com(er);
  392.                                           for(j=0;j<16;j++)
  393.                                           {
  394.                                                   write_1602dat(LockOpen[j]);  //显示open开锁画面
  395.                                           }
  396.                                           TwoAlam();   //操作成功提示音
  397.                                           KEY=0;   //开锁
  398.                                           pass=1;   //密码正确标志位置1
  399.                                           for(j=0;j<6;j++)  //将输入清除
  400.                                           {
  401.                                                   InputData[i]=0;   //开锁后将输入位清零
  402.                                           }
  403.                                   }
  404.                                         else  //当两次输入正确时,开启重置密码功能
  405.                                         {
  406.                                                 write_1602com(er);
  407.                                                 for(j=0;j<16;j++)
  408.                                                 {
  409.                                                         write_1602dat(SetNew[j]);  //显示重置密码界面
  410.                                                 }
  411.                                                 TwoAlam();   //操作成功提示
  412.                                                 ReInputEn=1;   //允许重置密码输入
  413.                                                 CorrectCont=0;  //正确计数器清零
  414.                                         }
  415.                                 }
  416.                                         else if((InputData[0]==adminpassword[0])&&(InputData[1]==adminpassword[1])&&(InputData[2]==adminpassword[2])&&(InputData[3]==adminpassword[3])&&(InputData[4]==adminpassword[4]))
  417.                                         {
  418.                                                 WrToROM(initpassword,0,6);   //强制将初始密码写入24c02存储
  419.                                                 write_1602com(er);
  420.                                                 for(j=0;j<16;j++)
  421.                                                 {
  422.                                                         write_1602dat(initword[j]);  //显示初始化密码
  423.                                                 }
  424.                                                 TwoAlam();  //成功提示音
  425.                                                 Delay400Ms();  //延时400ms
  426.                                                 N=0;
  427.                                         }
  428.                                         else   //密码错误时
  429.                                         {
  430.                                                 CorrectCont=0;   //正确计数器清零,密码一旦错误,对密码正确次数重新清零
  431.                                                 ErrorCont++;   //错误次数++
  432.                                                 write_1602com(er);
  433.                                                 for(j=0;j<16;j++)
  434.                                                 {
  435.                                                         write_1602dat(Error[j]);   //显示错误信息
  436.                                                 }
  437.                                                 pass=0;
  438.                                                 TR0=1;   //开启定时
  439.                                                 key_disable=1;   //锁定键盘
  440.                                                 KEY=1;   //关闭锁
  441.                                                 if(ErrorCont==3)   //错误输入连续达3次时,报警并锁定键盘
  442.                                                 {
  443.                                                         write_1602com(er);
  444.                                                         for(i=0;i<16;i++)
  445.                                                         {
  446.                                                                 write_1602dat(Error[i]);
  447.                                                         }
  448.                                                 do
  449.                                                         Alam_KeyUnable();
  450.                                                 while(1);   //死循环,超过三次密码错误则一直报警并锁定键盘,直到重新运行或按下复位键
  451.                                           }
  452.                                 }
  453.                         }
  454.         else   //当已经开启重置密码功能时,而按下确认键
  455.         {
  456.                 write_1602com(er);
  457.                 for(j=0;j<16;j++)
  458.                 {
  459.                         write_1602dat(Er_try[j]);   //错误,请重新输入
  460.                 }
  461.                 ThreeAlam();   //错误提示音
  462.         }
  463. }
  464. else    //密码没有输入到6位时,按下确认键
  465. {
  466.         write_1602com(er);
  467.         for(j=0;j<16;j++)
  468.         {
  469.                 write_1602dat(Error[j]);   //显示错误
  470.         }
  471.         ThreeAlam();    //错误提示音
  472.         pass=0;
  473. }
  474. N=0;   //将输入数据计数器清零,为下一次输入做准备
  475. }
  476. void ResetPassword(void)
  477. {
  478.         unsigned char i;
  479.         unsigned char j;
  480.         if(pass==0)   //没开锁时
  481.         {
  482.                 pass=0;
  483.                 DisplayChar();   //显示开始输入password
  484.                 ThreeAlam();    //没开锁时按下重置密码报警3声
  485.         }
  486.         else   //开锁状态下才能进行密码重置
  487.         {
  488.                 if(ReInputEn==1)    //开锁状态下,ReInputEn置1,重置密码允许
  489.                 {
  490.                         if(N==6)   //输入6位密码
  491.                         {
  492.                                 ReInputCont++;    //重置密码次数计数
  493.                                 if(ReInputCont==1)   //输入一次密码时
  494.                                 {
  495.                                         OneAlam();
  496.                                         for(i=0;i<6;i++)
  497.                                         {
  498.                                                 TempPassword[i]=InputData[i];    //将第一次输入的数据暂存起来
  499.                                         }
  500.                                         write_1602com(er);
  501.                                         for(j=0;j<16;j++)
  502.                                         {
  503.                                                 write_1602dat(again[j]);    //显示再输入一次
  504.                                         }
  505.                                 }
  506.                                 if(ReInputCont==2)    //输入两次密码时
  507.                                 {
  508.                                         if((TempPassword[0]==InputData[0])&&(TempPassword[1]==InputData[1])&&(TempPassword[2]==InputData[2])&&(TempPassword[3]==InputData[3])&&(TempPassword[4]==InputData[4]))
  509.                                         {
  510.                                                 write_1602com(er);
  511.                                                 for(j=0;j<16;j++)
  512.                                                 {
  513.                                                         write_1602dat(ResetOK[j]);   //密码修改成功,显示
  514.                                                 }
  515.                                                 TwoAlam();     //操作成功显示
  516.                                                 WrToROM(TempPassword,0,6);   //将新密码写入24c02存储
  517.                                                 ReInputEn=0;   //关闭重置功能
  518.                                         }
  519.                                         else     //如果两次的密码不同
  520.                                         {
  521.                                                 write_1602com(er);
  522.                                                 for(j=0;j<16;j++)
  523.                                                 {
  524.                                                         write_1602dat(Error[j]);   //显示错误Error
  525.                                                 }
  526.                                                 ThreeAlam();   //错误提示
  527.                                                 pass=0;    //关锁
  528.                                                 ReInputEn=0;   //关闭重置功能
  529.                                                 ReInputCont=0;   //重置密码次数清零
  530.                                                 KEY=1;     //关闭锁
  531.                                                 DisplayChar();
  532.                                         }
  533.                                         ReInputCont=0;
  534.                                         CorrectCont=0;
  535.                                 }
  536.                                 N=0;   //输入数据位数计数器清零
  537.                         }
  538.                         else     //密码没有输入到6位时,按下重置键时
  539.                         {
  540.                                 write_1602com(er);
  541.                                 for(j=0;j<16;j++)
  542.                                 {
  543.                                         write_1602dat(Error[j]);  //显示错误
  544.                                 }
  545.                                 ThreeAlam();   //错误提示音
  546.                                 N=0;
  547.                         }
  548.                 }
  549.         }
  550. }



  551. //===========================输入密码错误超过三次,报警并锁死键盘======================================================================


  552. //========================取消所有操作=======================================================================
  553. void Cancel(void)
  554. {
  555.         unsigned char i;
  556.         unsigned char j;
  557.         //DisplayListChar(0,1,start_line);
  558.         write_1602com(er);
  559.         for(j=0;j<16;j++)
  560.         {
  561.                 write_1602dat(start_line[j]);   //显示开机输入密码界面
  562.         }
  563.         TwoAlam();   //提示音
  564.         for(i=0;i<6;i++)
  565.         {
  566.                 InputData[i]=0;   //将输入密码清零
  567.         }
  568.         KEY=1;   //关闭锁
  569.         ALAM=1;   //报警关
  570.         pass=0;   //密码正确标志清零
  571.         ReInputEn=0;   //重置输入允许标志清零
  572.         ErrorCont=0;   //密码错误输入次数清零
  573.         CorrectCont=0;   //密码正确输入次数清零
  574.         ReInputCont=0;   //重置密码输入次数清理
  575.         s3_keydown=0;
  576.         key_disable=0;    //锁定键盘标志清零
  577.          N=0;      //输入位数计数器清零
  578. }
  579. //=========================主函数=======================================================================================================================================

  580. void main(void)
  581. {
  582.         unsigned char KEY,NUM;
  583.         unsigned char i,j;
  584.         P1=0xFF;     //P1口复位
  585.         TMOD=0x01;   //定义工作方式
  586.         TL0=0xB0;  
  587.         TH0=0x3C;    //定时器赋初值,定时50ms
  588.         EA=1;        //打开中断总开关
  589.         ET0=1;       //打开中断允许开关
  590.         TR0=1;       //打开定时器开关
  591.         Delay400Ms();           //启动等待,等LCM讲入工作状态
  592.         lcd_init();            //LCD初始化
  593.         write_1602com(yi);    //日历显示固定符号从第一行第0个位置之后开始显示
  594.         for(i=0;i<16;i++)
  595.         {
  596.                 write_1602dat(name[i]);   //向液晶屏写开机画面
  597.         }
  598.         write_1602com(er);
  599.         for(i=0;i<16;i++)
  600.         {
  601.                 write_1602dat(start_line[i]);    //写输入密码等待界面
  602.         }
  603.         write_1602com(er+9);    //设置光标位置
  604.         write_1602com(0x0f);     //设置光标为闪烁
  605.         Delay5Ms();   //延时片刻(可不要)
  606.         N=0;   //初始化数据输入位数
  607.         while(1)   //进入循环
  608.         {
  609.                 if(key_disable==1)     //锁定键盘标志为1时
  610.                         Alam_KeyUnable();    //报警键盘锁
  611.                 else
  612.                         ALAM=1;             //关报警
  613.                 KEY=keynum();         //读按键的位置码
  614.                 if(KEY!=0)            //当有按键按下时
  615.                 {
  616.                         if(key_disable==1)   //锁定键盘标志为1时
  617.                         {
  618.                                 second=0;    //秒清零
  619.                         }
  620.                         else    //没有锁定键盘时
  621.                         {
  622.                                 NUM=coding(KEY);    //根据按键的位置将其编码,编码值赋值给NUM
  623.                                 {
  624.                                         switch(NUM)   //判断按键值
  625.                                         {
  626.                                                 case ('A'):      ;                   break;
  627.                                                 case ('B'):      ;                   break;
  628.                                                 case ('C'):      ;                   break;   //ABC是无意义按键
  629.                                                 case ('D'):ResetPassword();          break;   //重新设置密码
  630.                                                 case ('*'):Cancel();                 break;   //取消当前输入
  631.                                                 case ('#'):Ensure();                 break;   //确认键
  632.                                                 default:      //如果不是功能键按下时,就是数字键按下
  633.                                                 {
  634.                                                         if(N<6)   //当输入密码少于6位时,接受输入并保存,大于6位时则无效
  635.                                                         {
  636.                                                                 write_1602com(er);
  637.                                                                 for(i=0;i<16;i++)
  638.                                                                 {
  639.                                                                         write_1602dat(Input[i]);   //显示输入画面
  640.                                                                 }
  641.                                                                 OneAlam();   //按键提示音
  642.                                                                 for(j=0;j<=N;j++)
  643.                                                                 {
  644.                                                                         write_1602com(er+6+j);   //显示位数随输入增加而增加
  645.                                                                         write_1602dat('*');     //但不显示实际数字,用*代替
  646.                                                                 }
  647.                                                                 InputData[N]=NUM;   //将数字键的码赋值给InputData【】数组暂存
  648.                                                                 N++;   //密码位数加
  649.                                                         }
  650.                                                         else   //输入数据位数大于6后,忽略输入
  651.                                                         {
  652.                                                                 N=6;     //密码输入大于6位时,不接受输入
  653.                                                                 break;
  654.                                                         }
  655.                                                 }
  656.                                         }
  657.                                 }
  658.                         }
  659.                 }
  660.         }
  661. }
  662. //=========================中断服务函数=======================================================================================================================================
  663. void time0_int(void) interrupt 1    //定时器T0
  664. {
  665.         TL0=0xB0;
  666.         TH0=0x3C;    //定时器重新赋初值
  667.         countt0++;    //计时器变量加,加1次时50ms
  668.         if(countt0==20)   //加到20次就是1s
  669.         {
  670.                 countt0=0;   //变量清零
  671.                 second++;    //秒加
  672.                 if(!pass)    //不在开锁状态时
  673.                 {
  674.                         if(second==3)   //秒加到3时
  675.                         {
  676.                                 TR0=0;    //关闭定时器
  677.                                 second=0;   //秒清零
  678.                                 key_disable=0;    //锁定键盘清零
  679.                                 s3_keydown=0;   //3秒键盘标志位清0
  680.                                 TL0=0xB0;   
  681.                                 TH0=0x3C;    //重新赋初值
  682.                         }
  683.                         else
  684.                                 TR0=1;        //打开定时器
  685.                 }
  686.         }
  687. }
复制代码

回复

使用道具 举报

ID:1023753 发表于 2025-5-29 08:27 | 显示全部楼层
蜂鸣器是不是选的无源的,需要2K方波才能响
回复

使用道具 举报

ID:1023753 发表于 2025-5-29 08:29 | 显示全部楼层
继电器用的是12V的  你的VCC应该是5v,电压不够,改用5V的继电器
回复

使用道具 举报

ID:76027 发表于 2025-5-29 08:52 | 显示全部楼层
这个例程是论坛上的,我试过无法重置密码。其它的都正常。
回复

使用道具 举报

ID:76027 发表于 2025-5-29 08:57 | 显示全部楼层
还有这个数组是6位密码,你用5位输入进行比较,能开锁吗?
回复

使用道具 举报

ID:1133081 发表于 2025-5-29 09:39 | 显示全部楼层
蜂鸣器要正确选择和正确设置
无标题.jpg

回复

使用道具 举报

ID:1151978 发表于 2025-5-29 10:12 | 显示全部楼层
没配置好
回复

使用道具 举报

ID:1152013 发表于 2025-5-29 12:40 | 显示全部楼层
haiyang201 发表于 2025-5-29 08:29
继电器用的是12V的  你的VCC应该是5v,电压不够,改用5V的继电器

是的,跟同学弄了好久弄不明白
回复

使用道具 举报

ID:1152013 发表于 2025-5-29 12:40 | 显示全部楼层
WL0123 发表于 2025-5-29 09:39
蜂鸣器要正确选择和正确设置

嗷嗷好的好的谢谢
回复

使用道具 举报

ID:1152013 发表于 2025-5-29 12:41 | 显示全部楼层
发表于 2025-5-29 08:57
还有这个数组是6位密码,你用5位输入进行比较,能开锁吗?

这个地方后面修改了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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