找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4699|回复: 4
收起左侧

51单片机24C04密码锁(C程序+Proteus仿真)

[复制链接]
ID:408617 发表于 2018-10-12 15:53 | 显示全部楼层 |阅读模式
由于放假没有准备,现在做了发现IIC总线不会用,对1602液晶和同类的手册可以看懂也会使用。不用24存储,所以就没有密码更改的功能。还有,看其他的资料,在使用IIC总线14芯片时,有的使用  .BIN文件,不理解。

24C04密码锁仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png

根据设定好的密码, 采用六个按键实现密码的输入功能
当密码输入完后,按确认键验证,正确之后,锁就打开
如果输入的三次的密码不正确, 就锁定按键 3 秒钟
同时发出报警声,直到没有按键按下 3 秒后
才打开按键锁定功能否则在 3 秒钟内仍有按键按下,就重新锁

初值密码2 0 1 6 5 7
重置密码在输入正确的原始密码后
提示输入新密码后按重置保存按键保存密码

单片机源程序如下:
  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #include<string.h>
  4. #define uint unsigned int
  5. #define uchar unsigned char
  6. #define NOP4() {_nop_();_nop_();_nop_();_nop_();}
  7. sbit lcdrs=P2^0;                         //1602液晶控制端
  8. sbit lcdrw=P2^1;
  9. sbit lcden=P2^2;
  10. sbit Beep=P2^3;
  11. sbit Red=P2^4;
  12. sbit Green=P2^5;
  13. sbit Lamp=P2^6;

  14. sbit SCL=P3^0;
  15. sbit SDA=P3^1;

  16. uchar num=0;                                //按键次数
  17. uchar Wrong=0;                         //错误次数
  18. uchar Count=0;                          //开锁次数
  19. uchar Timer=0;                           //中断计数器
  20. uchar k=0;                                         //数组累加        
  21. uchar Sure_temp,Cancel_temp;//保存按下确认键和取消键P1的值

  22. /**************************各数组定义*******************************/
  23. //按键次数码表
  24. uchar code Count_Table[]="123456789";
  25. //键盘特征码
  26. uchar code Key_Table[]={0xee,0xde,0xbe,0x7e,
  27.                                                   0xed,0xdd,0xbd,0x7d,
  28.                                                   0xeb,0xdb,0xbb,0x7b,
  29.                                                   0xe7,0xd7,0xb7,0x77};        
  30. uchar Buffer[]={0,0,0,0,0,0};         //按键数值缓存数组
  31. uchar Buffer_Reset[]={0,0,0,0,0,0};        //重置密码缓存
  32. uchar Passedword[]={0,0,0,0,0,0};//密码数组                         (这里开始出厂密码为比赛日期201657)
  33. /*************************************************/

  34. //声光报警
  35. void Alarm()
  36. {
  37.         uchar i;
  38.         Red=0;
  39.         for(i=0;i<120;i++)
  40.         {
  41.                 Beep=~Beep;
  42.                 Delay(2);               
  43.         }
  44. }
  45. void Delay(uchar z)
  46. {
  47.         uchar x,y;
  48.         for(x=z;x>0;x--)
  49.                 for(y=110;y>0;y--);
  50. }
  51. /**********************1602液晶显示器初始化函数********************/
  52. void write_com(uchar com)
  53. {
  54.         lcdrs=0;                   //发送指令RS置低电平
  55.         lcdrw=0;
  56.         P0=com;
  57.         Delay(5);
  58.         lcden=1;
  59.         Delay(5);
  60.         lcden=0;
  61. }
  62. void write_data(uchar dat)
  63. {
  64.         lcdrs=1;                  //发送数据RS置高电平
  65.         lcdrw=0;
  66.         P0=dat;
  67.         Delay(5);
  68.         lcden=1;                  //EN向下脉冲
  69.         Delay(5);
  70.         lcden=0;
  71. }
  72. void lcd_initial()
  73. {
  74.         lcden=0;
  75.         lcdrw=0;
  76.         write_com(0x38);         //设置16*2显示,5*7点阵,8为显示
  77.         Delay(1);
  78.         write_com(0x0c);        //设置开显示,不显示光标
  79.         Delay(1);
  80.         write_com(0x06);        //写一个字符后地址指针加1
  81.         Delay(1);
  82.         write_com(0x01);        //显示清0,数据指针清0
  83.         Delay(1);
  84. }
  85. void write_string(uchar *str)
  86. {
  87.         uchar i;
  88.         write_com(0x80);                                 //第一行显示,主要用于密码重置时的提示
  89.         for(i=0;i<strlen(str);i++)
  90.         {
  91.                  write_data(str[i]);        
  92.         }        
  93. }
  94. /****************IIC24C04A初始化函数****************************/


  95. void Start()
  96. {
  97.          SDA=1;SCL=1;NOP4();SDA=0;NOP4();SCL=0;
  98. }

  99. void Stop()
  100. {
  101.          SDA=0;SCL=0;NOP4();SCL=1;NOP4();SDA=1;NOP4();
  102. }

  103. void RACK()
  104. {
  105.          SDA=1;NOP4();SCL=1;NOP4();SCL=0;
  106. }

  107. void NO_ACK()
  108. {
  109.          SDA=1;SCL=1;NOP4();SCL=0;SDA=0;
  110. }

  111. void Write_A_Byte(uchar b)
  112. {
  113.          uchar i;
  114.         for(i=0;i<8;i++)
  115.         {
  116.                  b<<=1;SDA=CY;_nop_();SCL=1;NOP4();SCL=0;
  117.         }
  118.         RACK();
  119. }

  120. uchar Receive_A_Byte()
  121. {
  122.          uchar i,d;
  123.         for(i=0;i<8;i++)
  124.         {
  125.                  SCL=1;d<<=1;d|=SDA;SCL=0;
  126.         }
  127.         return d;
  128. }

  129. void Write_Random_Address_Byte(uchar add,uchar dat)
  130. {
  131.          Start();
  132.         Write_A_Byte(0xa0);
  133.         Write_A_Byte(add);
  134.         Write_A_Byte(dat);
  135.         Stop();
  136.         Delay(10);
  137. }

  138. uchar Read_Current_Address_Data()
  139. {
  140.          uchar d;
  141.         Start();
  142.         Write_A_Byte(0xa1);
  143.         d=Receive_A_Byte();
  144.         NO_ACK();
  145.         Stop();
  146.         return d;
  147. }

  148. uchar Random_Read(uchar addr)
  149. {
  150.          Start();
  151.         Write_A_Byte(0xa0);
  152.         Write_A_Byte(addr);
  153.         Stop();
  154.         return Read_Current_Address_Data();               
  155. }
  156. /********************按键处理函数***********************/
  157. //确认键处理 按键检测
  158. void Sure_Key()
  159. {        
  160.         uchar flag;
  161.         uchar i;
  162.         write_com(0x80);                                                 //第一行0x80+0x00
  163.         write_data(Count_Table[Count++]);                                           //显示输入次数
  164.         Delay(200);
  165.         if(Count>=10){P0=0XC0;Count=0;}
  166.         for(i=0;i<6;i++)
  167.         {
  168.                 if(Buffer[i]==Passedword[i]){flag=1;continue;}
  169.                 else {flag=0;break;}
  170.         }
  171.         //结果处理
  172.         if(flag==1){k=0;Green=0;Lamp=0;Red=1;write_com(0x80+0x40);for(i=0;i<16;i++)write_data('\0');Delay(200);}                 //正确绿灯亮,锁打开
  173.         else {k=0;Alarm();Wrong++;Green=1;Lamp=1;write_com(0x80+0x40);for(i=0;i<16;i++)write_data('\0');Delay(200);}         //错误则声光报警
  174.         if(Wrong==3) {Sure_temp=P1;TR0=1;Wrong=0;}                        //错误三次则锁定键盘3秒钟
  175. }
  176. //取消键处理
  177. void Cancel_Key()
  178. {        
  179.         uchar i;
  180.         k=0;
  181.         for(i=0;i<6;i++)Buffer[i]=0;Delay(100);
  182.         write_com(0x80+0x40);
  183.         for(i=0;i<16;i++)write_data('\0');
  184. }
  185. //锁定键
  186. void Lock()
  187. {
  188.         uchar i;
  189.         k=0;Alarm();Green=1;Lamp=1;Delay(200);
  190.         Cancel_Key();        
  191. }
  192. //清屏键
  193. void Clear_Lcd()
  194. {
  195.         k=0;Cancel_Key();
  196.         write_com(0x01);
  197. }
  198. //重置键
  199. void Reset_Key()
  200. {
  201.         uchar i;
  202.         k=0;
  203.         write_com(0x10);
  204.         write_string("Input Passedword:");
  205. }
  206. //重置确认键
  207. void Reset_Sure_Key()
  208. {
  209.         uchar i,flag;
  210.         for(i=0;i<6;i++){if(Buffer[i]==Passedword[i]){flag=1;continue;}        else {flag=0;break;}}//输入老密码并判断
  211.                                         if(flag==1)        {write_com(0x01);write_string("Input Newword:");Cancel_Key();}
  212.                                         else {Reset_Key();}
  213.         /*                 最初的想法是用一个按键来进行重置键处理
  214.         uchar state=1;          //重置按键第一次为判断是否与老密码一样,第二次进行新密码的保存
  215.         state=~state;          //初始为state=1;
  216.         k=0;
  217.         switch(state)
  218.         {
  219.                 case 0:                for(i=0;i<6;i++)                                                                                  //输入老密码并判断
  220.                                         {if(Buffer[i]==Passedword[i]){flag=1;continue;}
  221.                                         else {flag=0;break;}}
  222.                                         if(flag==1)        {write_com(0x01);write_string("Input Newword:");}
  223.                                         else {state=~state;Reset_Key();}break;
  224.                 case 1:     if(flag==1)        {for(i=0;i<6;i++)                                                          //老密码正确再保存新密码
  225.                                                                 Write_Random_Address_Byte(i,Buffer[i]);}
  226.         }
  227.         */
  228. }
  229. //重置保存
  230. void Reset_Save()
  231. {
  232.         uchar i;
  233.         k=0;
  234.         for(i=0;i<6;i++) Write_Random_Address_Byte(i,Buffer[i]); //老密码正确再保存新密码
  235.         for(i=0;i<6;i++)Passedword[i]=Random_Read(i);
  236.         write_com(0x01);write_string("Succeed!");Delay(1000);write_com(0x01);
  237.                
  238.                                                         
  239. }
  240. /**************************按键扫描函数***********************************/
  241. //按键扫描
  242. void Key_Play()
  243. {        
  244.         uchar i=0;
  245.         uchar num;
  246.         uchar temp;
  247.         uchar Key,c;
  248.         P1=0xf0;
  249.         if(P1!=0xf0)
  250.         {
  251.                 Delay(5);
  252.                 if(P1!=0xf0)
  253.                 {
  254.                         temp=P1;
  255.                         P1=0x0f;
  256.                         Key=temp|P1;
  257.                         for(i=0;i<16;i++)
  258.                         if(Key==Key_Table[i]) {num=i;break;}
  259.                         Buffer[k++]=num;
  260.                         switch(num)
  261.                         {
  262.                                 case 10:Sure_Key();break;         //确认
  263.                                 case 11:Cancel_Key();break;         //取消
  264.                                 case 12:Reset_Key();break;         //重置
  265.                                 case 13:Reset_Sure_Key();break;//重置确认
  266.                                 case 14:Reset_Save();break;           //上锁
  267.                                 case 15:Lock();;           //清屏
  268.                         }               
  269.                         write_com(0x80+0x40);        //第二行0x80+0x40
  270.                         for(i=0;i<k;i++)
  271.                         write_data('*');
  272.                 }
  273.                 do{                                           //等待按键抬起
  274.                           temp=P1;
  275.                          temp=temp&0x0f;
  276.                  }         
  277.                   while(temp!=0x0f);
  278.         }
  279. }
  280.         
  281. //************************主函数************************//
  282. void main()
  283. {        
  284.         uchar i;
  285.         lcd_initial();
  286.         P0=0x3f;//次数默认为0
  287.         P2=0XFF;//初始全关
  288.         TMOD=0X01;               
  289.         TH0=(65536-50000)/256;               
  290.         TL0=(65536-50000)%256;
  291.         EA=1;
  292.         ET0=1;                                                 //密码错误定时器中断0
  293.         for(i=0;i<6;i++)Passedword[i]=Random_Read(i);
  294.         while(1)
  295.         {        
  296.                 Key_Play();
  297.                 Delay(2);        
  298.         }
  299. }

  300. //定时器0中断 键盘锁定3秒
  301. void Inter_Timer0() interrupt 1
  302. {
  303.                 uchar temp;
  304.                 Timer++;
  305.                 TH0=(65536-50000)/256;               
  306.                 TL0=(65536-50000)%256;
  307.                 Beep=~Beep;Delay(20);
  308.                 P1=0xf0;
  309.                 if(P1!=0xf0)
  310.                 {
  311.                         Delay(5);
  312.                         Timer=0;
  313.                 }
  314.                  //如果3秒内无按键则回复正常
  315.                 if(Timer==60){Timer=0;Beep=0;Red=1;TR0=0;}
  316. }
复制代码
0.png

所有资料51hei提供下载:
实训任务-3.zip (1.33 MB, 下载次数: 97)

评分

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

查看全部评分

回复

使用道具 举报

ID:719630 发表于 2020-3-31 16:52 | 显示全部楼层
这也太黑了吧?不但源程序与设计图不能用,连芯片手册的PDF文档都是坏的?
回复

使用道具 举报

ID:408617 发表于 2018-10-12 15:53 | 显示全部楼层
稍后把题目要求和具体的文档补充
回复

使用道具 举报

ID:719630 发表于 2020-3-31 16:49 | 显示全部楼层
下载了一个,但是文件被破坏
回复

使用道具 举报

ID:328014 发表于 2020-3-31 18:07 | 显示全部楼层
xuweiye 发表于 2020-3-31 16:52
这也太黑了吧?不但源程序与设计图不能用,连芯片手册的PDF文档都是坏的?

推荐这个:http://www.51hei.com/bbs/dpj-178815-1.html
51hei搜索密码锁 至少有好几百个呢
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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