找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 27266|回复: 86
收起左侧

你从未见过的单片机密码锁设计(基本版)

  [复制链接]
回帖奖励 20 黑币 回复本帖可获得 1 黑币奖励! 每人限 1 次
ID:362076 发表于 2018-12-5 10:18 | 显示全部楼层 |阅读模式
本帖最后由 凌净清河 于 2018-12-11 12:04 编辑

重新编辑说明:取消了回复才能下载的限制,取消了下载付黑币的设置。
另外我建立了一个STC 51单片机初学者提升qq群,如果你想在单片机的道路上从菜鸟走到入门,欢迎加群和大家共同成长。群刚开始建立,人数尚少,内有资料不断完善中。群聊号码:873434536
特注:群不盈利、无广告、没有强制活动、没有潜规则,仅为个人兴趣和专业方向使然。

声明:
0.基本版代码相对冗余,但仍然请大家在转载、分享时提及原作者,非常感谢
1.设计使用STC15W4K48S4制作,在无需修改管理员密码的版本中可以使用IAP的单片机代替
2.本程序和设计为最基本版,只有简单的密码开锁和管理功能,更多更完善功能的版本请期待本人的后续帖子(虽然已经设计完成,但还是预计2019年1月份,考完研之后才能够整理发出)
3.由于是初稿,所以程序的结构上比较混乱,本人只保证其可以运行并且没有明显的BUG、不保证程序可读性,但是大家可以自取所需功能
4.本版本只是一个“预热”,请高手勿喷,至少也请看完1、2个月后的第二版之后再说;
请初学者不要仿制,毕竟这个版本还非常非常LOW,远远没有达到使用标准,也没有进行功能的优化、逻辑的论证、程序的精简,这些将在第二版中体现出来。

设计亮点:
1.使用OLED12864屏幕显示,具有用户菜单和管理员菜单,直观明了的设置使用流程(菜单未使用结构体或链表)
2.用户密码存储加密,使用BKDR哈希值计算并存储,防止从24C02中窃取密码
3.放弃传统的矩阵键盘,使用ADC键盘,连接上更加方便
4.如3项所示,密码为16进制,最大输入16位
5.对于添加了管理员密码的版本,使用内部EEPROM存储管理员密码(在本版本中,管理员密码明文存储)

简易操作说明:
上电进入用户模式锁定状态,在锁定状态下输入密码后,使用KEY1键确认,KEY2键取消,若密码正确,在按下确认键的时候会显示正确提示信息,松开按键进入用户菜单
如果用户模式下密码连续输入错误5次则自动锁死,此时可以重新上电清空错误计数或者进入管理员模式立即解锁,这种锁定不会自动解锁
在用户菜单下不进行任何操作5秒则自动上锁,使用KEY3、KEY4键进行选项的上下选择,KEY1键执行,KEY2键取消,在用户模式下按KEY2键取消会返回上锁状态
在用户模式锁定状态下,若硬件开关Hardware_Switch(P4^5)置0,按下KEY1键进入管理员认证,管理员密码输入流程与用户相同,密码正确则进入管理菜单
在管理员菜单下可以进行各样高权限操作,这些操作在程序上对用户模式屏蔽。
在管理模式菜单中各项选项的功能和操作说明如下:
1.立即解除锁定
    该选项将用户模式错误计数变量清零,没有提示信息,按下确认键即可
2.修改用户密码
    在管理员状态下修改用户密码不需要确认,直接输入新密码确定即立即生效,在输入密码时按下取消键原密码不改变
3.修改管理密码
    修改管理密码需要两步:身份认证和输入新密码。在任何一步按下取消键原密码不改变
4.常开常关选项
    当停用密码锁时返回用户状态时继电器常开
    当启用密码锁时用户模式正常
5.版本信息
    用于记录或显示某些信息,这些信息允许在编程阶段修改
6.退出管理模式
    选择此项按确定键和在任意项上按返回键效果一致,均回到管理员身份验证状态,希望回到用户模式时可以在管理员非密码修改模式下拔除Hardware_Switch(P4^5)跳帽或将其置高

考虑到的意外情况:
如果在关机时将AT24C02替换,且没有存储准确的信息,开机上电用户模式会自动锁死,需要管理员重置用户密码
实现机制:在AT24C02中不仅存放了用户密码的HASH值,也存入了4个字节的用户ID信息,这信息与烧录在程序中的用户ID信息必须一致,才能够通过上电检测,否则使用户锁定标志位有效

版本缺陷:

由于本版本是最初学习时尝试设计的,所以有一些问题和缺陷,随着后续的修改和测试逐渐发现的,但是已经无心更改。现列出所有问题如下所示:
1.继电器控制引脚的位定义未在包含文件语句(#include)之前,使得其他文件中对继电器的操作是直接给P00赋值,而非使用JDQ这个位定义名称,修改时需要注意;
2.继电器的控制三极管采用了NPN型,但是后来发现这样会导致上电吸合一次,在第二版中修正了这个错误但是本版本仍然保留;
3.本版本中设定密码开锁后5秒自动关锁,这个在程序中可以修改,需要注意一下;
4.按键按下会导致程序死循环,原因是仅仅使用了最简单的按键判断:即假设每个独立按键按下之后都会立即松开;
5.本版本中未添加时间修改函数,程序的时间是在下载程序的时候掐点矫正的,第二版会添加该功能。

IMG_20181205_100715.jpg

IMG_20181205_100731.jpg

IMG_20181205_100905.jpg

IMG_20181205_100918.jpg

1543975978866.jpg

1543976026767.jpg
单片机源程序如下:
  1. #include<STC15.H>
  2. #include<intrins.h>

  3. sbit LED1=P3^0;
  4. sbit LED2=P3^1;
  5. sbit KEY1=P3^2;
  6. sbit KEY2=P3^3;
  7. sbit KEY3=P2^1;
  8. sbit KEY4=P2^2;
  9. //由于后续包含的文件中可能用到上述位定义故将这部分位定义放在包含文件的语句之前
  10. #include"OLED_Display.c"
  11. #include"DS1302_Driver.c"
  12. #include"AT24C02_Driver.c"
  13. #include"BKDR_HASH_Fuction.c"

  14. sbit JDQ=P0^0;//继电器引脚

  15. sbit Hardware_Switch=P4^5;//管理员/用户硬件开关 用户:1 管理员:0

  16. //扩展作用域
  17. extern unsigned char hash_result[4];

  18. //运行数组
  19. unsigned char user_ID[4]={0x92,0x5A,0xA0,0xC1};
  20. unsigned char version[4]={0,9,0,8};//版本信息(自定义)
  21. unsigned char Administrator_Password[16]={0,1,0,15,0,0,0,0,0,0,0,0,0,0,0,0};//管理员密码存放数组
  22. unsigned char User_Password_Putin[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//用户密码输入临时存放数组
  23. unsigned char Admin_Password_Putin[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//管理员密码输入临时存放数组
  24. unsigned char Admin_Password_New_Temp[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//管理员密码修改时,新密码临时存放数组,可以考虑与输入临时存放数组复用

  25. //运行变量
  26. unsigned int ADC_DATA;//读取到的ADC转换值
  27. unsigned char ADC_value=0;//设置一个读取到的按键位置值。位置值由电路连接确定,各个按键位置值由所连电阻分压大小依次顺序排列
  28. unsigned char ADC_keyvalue=0;//读取到的ADC按键设定值。按键位置由电路而定可能并不规整,设定值为自定的各按键数值
  29. unsigned char first_num=1;//管理模式第一项菜单标号

  30. //运行计数
  31. unsigned char choose=1;//用户菜单选择号,用于记录当前选中的菜单项目序号,默认在第一项位置
  32. unsigned char cnt_user_putin_wrong=0;//用户输入错误计数
  33. unsigned char t1_cnt=0;//定时器1运行计数

  34. //运行标志位
  35. bit flag_Identity=1;//身份标志位,表明当前所处身份状态 用户:1 管理员:0
  36. bit En_Standby=1;//待机状态有效标志位(使能) 有效:1 无效:0
  37. bit En_Admin=0;//管理员模式下管理有效标志位(使能) 有效:1 无效:0
  38. bit User_Locker=0;//用户输入错误导致的锁定有效 有效:1 无效:0
  39. bit Admin_Info=0;//管理员提示开关,在用户待机状态下显示某些信息 有效:1 无效:0
  40. bit _ReLock=0;//自动锁定标志位,显示定时器是否已经到达计时时间 是:1 否:0

  41. /*##############################################################################################
  42. 设计名称:电子锁设计
  43. 设计者:清河

  44. 版本:9.8.1
  45. 详情:已经初步完成功能设定,添加自动锁定功能,并排除BUG。丰富了注释内容。
  46.         添加用户的断电密码记忆功能和密码加密存储功能,添加开机AT24C02判断

  47. 掉电存储构想:
  48.         在每一次更新用户密码时将新密码hash值存放进存储器中,管理员密码明文存储

  49. 加密存储构想:
  50.         使用加密函数将用户密码加密后存储,核对密码时通过加密函数求出特征值和存储器中的比对

  51. 存储安全性保证:为防止换用AT24C02导致使用不便或达到非法开锁的目的,分别使用AT24C02存储用户的密码HASH值
  52. 片外EEPROM:存放用户密码的HASH值,并存入检测字节,在系统启动时检测AT24C02是否有被改动过以提高系统安全性
  53. 扩展:如果有用户个性化的设置,也可以如此存放,便于管理

  54. 平台:STC15W4K48S4
  55. 硬件部分
  56. 独立按键:共4个,用于进行各项调整
  57. ADC键盘:用于输入密码,本作品中可以输入16进制的密码,较平常10位密码更加安全,只要程序和电路做相应的修改,也可以实现在AD可分辨的情况下上百的按键键位
  58. DS1302:配电池,实现断电走时,用于待机显示,如果在关机时取下电池或者替换DS1302则会出错,需要重新烧录程序初始化DS1302
  59. LED指示灯:指示所处状态,本作品中进入用户模式则LED1亮,进入管理员模式则LED2亮
  60. AT24C02:实现断电密码记忆功能,用于记录用户密码的HASH值

  61. 软件部分
  62. 使用定时器0实现对DS1302数据的定时读取,间隔50ms,以便更新当前的显示值
  63. 使用定时器1在用户解锁成功时定时上锁,设置的超时时间为5秒

  64. 操作说明:
  65. 上电进入用户模式锁定状态,在锁定状态下输入密码后,使用KEY1键确认,KEY2键取消,若密码正确,在按下确认键的时候会显示正确提示信息,松开按键进入用户菜单
  66. 如果用户模式下密码连续输入错误5次则自动锁死,此时可以重新上电清空错误计数或者进入管理员模式立即解锁,这种锁定不会自动解锁
  67. 在用户菜单下不进行任何操作5秒则自动上锁,使用KEY3、KEY4键进行选项的上下选择,KEY1键执行,KEY2键取消,在用户模式下按KEY2键取消会返回上锁状态
  68. 在用户模式锁定状态下,若硬件开关Hardware_Switch(P4^5)置0,按下KEY1键进入管理员认证,管理员密码输入流程与用户相同,密码正确则进入管理菜单
  69. 在管理员菜单下可以进行各样高权限操作,这些操作在程序上对用户模式屏蔽。
  70. 在管理模式菜单中各项选项的功能和操作说明如下:
  71. 1.立即解除锁定
  72.         该选项将用户模式错误计数变量清零,没有提示信息,按下确认键即可
  73. 2.修改用户密码
  74.         在管理员状态下修改用户密码不需要确认,直接输入新密码确定即立即生效,在输入密码时按下取消键原密码不改变
  75. 3.修改管理密码
  76.         修改管理密码需要两步:身份认证和输入新密码。在任何一步按下取消键原密码不改变
  77. 4.常开常关选项
  78.         当停用密码锁时返回用户状态时继电器常开
  79.         当启用密码锁时用户模式正常
  80. 5.版本信息
  81.         用于记录或显示某些信息,这些信息允许在编程阶段修改
  82. 6.退出管理模式
  83.         选择此项按确定键和在任意项上按返回键效果一致,均回到管理员身份验证状态,希望回到用户模式时可以在管理员非密码修改模式下拔除Hardware_Switch(P4^5)跳帽或将其置高

  84. 考虑到的意外情况:
  85. 如果在关机时将AT24C02替换,且没有存储准确的信息,开机上电用户模式会自动锁死,需要管理员重置用户密码
  86. 实现机制:在AT24C02中不仅存放了用户密码的HASH值,也存入了4个字节的用户ID信息,这信息与烧录在程序中的用户ID信息必须一致,才能够通过上电检测,否则使用户锁定标志位有效

  87. 特别注意:继电器部分在本版本程序中没有考虑到上电初始控制电平的问题,上电瞬间会吸合一次,建议将所有JDQ位反向控制,并将OLED_Display.c中对P00的控制相应更改。
  88. 更改后外围电路上应采用PNP典型控制电路即P口低电平时继电器打开,否则关闭

  89. 经过再三考虑,不添加密码重置功能,即在添加掉电存储的程序版本中,一旦忘记用户密码和管理密码则无法找回,只能通过刷固件的方式重置密码以提高整体安全性
  90. 但是后期若能够添加指纹识别等模块,通过该个人生物识别的机制更改管理密码会使安全性得到很大的提升
  91. ##############################################################################################*/

  92. void delay(unsigned int cnt)//调用该函数进行一段时间的延时
  93. {
  94.         while(cnt--);
  95. }

  96. unsigned char KeyScan()
  97. {
  98.         unsigned char ADC_keyvalue=0;//读取到的ADC按键设定值
  99.         ADC_CONTR=0xea;//开始转换
  100.         delay(1000);//这段暂停的时间用于等待AD转换完成
  101.         switch(ADC_value)
  102.         {
  103.                 case 0:ADC_keyvalue=12;break;
  104.                 case 1:ADC_keyvalue=13;break;
  105.                 case 2:ADC_keyvalue=14;break;
  106.                 case 3:ADC_keyvalue=15;break;
  107.                 case 4:ADC_keyvalue=11;break;
  108.                 case 5:ADC_keyvalue=10;break;
  109.                 case 6:ADC_keyvalue=9;break;
  110.                 case 7:ADC_keyvalue=8;break;
  111.                 case 8:ADC_keyvalue=4;break;
  112.                 case 9:ADC_keyvalue=5;break;
  113.                 case 10:ADC_keyvalue=6;break;
  114.                 case 11:ADC_keyvalue=7;break;
  115.                 case 12:ADC_keyvalue=3;break;
  116.                 case 13:ADC_keyvalue=2;break;
  117.                 case 14:ADC_keyvalue=1;break;
  118.                 case 15:ADC_keyvalue=0;break;
  119.                 default:ADC_keyvalue=16;break;
  120.         }
  121.         return ADC_keyvalue;
  122. }

  123. unsigned char Modify_User_Password()//用户密码更改函数,用于获取新值赋给用户密码数组
  124. {
  125.         unsigned char i;
  126.         OLED_Clear();
  127.         OLED_Show_CHinese(0,CCTitle7,1);//显示标题:修改密码
  128.         for(i=0;i<16;i++)
  129.         {
  130.                 OLED_Show_sChar(i*8,2,sChar3,1);//显示横线
  131.         }
  132.         OLED_Show_CHinese(4,CCInfo5,1);//显示说明文字:请输入新密码:
  133.         
  134.         for(i=0;i<16;)//进入输密码的环节
  135.         {
  136.                 OLED_Show_Number(0,6,User_Password_Putin,i,1);//显示输入的值
  137.                 if(KeyScan()!=16)
  138.                 {
  139.                         delay(5000);
  140.                         if(KeyScan()!=16)
  141.                         {
  142.                                 User_Password_Putin[i]=KeyScan();//记录每一次输入的值
  143.                                 i++;
  144.                         }
  145.                         while(KeyScan()!=16);//等待按键松开
  146.                 }
  147.                
  148.                 if(KEY1==0||i==16)//如果确定键按下或输满16位
  149.                 {
  150.                         delay(5000);
  151.                         if(KEY1==0||i==16)
  152.                         {
  153.                                 unsigned char k=0;
  154.                                 Password_BKDRHASH_Calculation(User_Password_Putin,16);//对输入的值求HASH值,保存在hash_result数组中
  155.                                 Save_User_Password();//保存新数据
  156.                                 for(k=0;k<16;k++)
  157.                                 {
  158.                                         User_Password_Putin[k]=0;//清空用户输入
  159.                                 }
  160.                         }
  161.                         while(!KEY1);
  162.                         OLED_Clear();//清屏,清屏放在此处可以使密码正确的提示信息在按键松开前一直显示
  163.                         break;//立即退出输入密码的环节
  164.                 }
  165.                
  166.                 if(KEY2==0)//如果取消键按下
  167.                 {
  168.                         delay(5000);
  169.                         if(KEY2==0)
  170.                         {
  171.                                 unsigned char j;
  172.                                 for(j=0;j<16;j++)
  173.                                 {
  174.                                         User_Password_Putin[j]=0;//清空用户输入
  175.                                 }
  176.                                 OLED_Clear();//清屏                        
  177.                         }
  178.                         while(!KEY2);
  179.                         break;//立即退出输入密码的环节
  180.                 }
  181.         }
  182.         return 0;
  183. }

  184. unsigned char Modify_Admin_Password()//管理员密码修改,包括2个步骤:身份认证、密码修改,其中任何一步都可以由取消键退出
  185. {
  186.         unsigned char i;
  187.         OLED_Clear();
  188.         OLED_Display_Administrator_Onload();
  189.         
  190.         for(i=0;i<16;)//进入输密码的环节
  191.         {
  192.                 if(KeyScan()!=16)
  193.                 {
  194.                         delay(5000);
  195.                         if(KeyScan()!=16)
  196.                         {
  197.                                 Admin_Password_Putin[i]=KeyScan();//记录每一次输入的值
  198.                                 OLED_Show_sChar(i*8,6,sChar1,1);//显示*
  199.                                 i++;
  200.                         }
  201.                         while(KeyScan()!=16);//等待按键松开
  202.                 }
  203.         
  204.                 if(KEY1==0||i==16)//如果确定键按下或输入位数满
  205.                 {
  206.                         delay(5000);
  207.                         if(KEY1==0||i==16)
  208.                         {
  209.                                 unsigned char k=0,t=0;
  210.                                 for(k=0;k<16;k++)
  211.                                 {
  212.                                         if(Admin_Password_Putin[k]==Administrator_Password[k])//核对明文密码
  213.                                         {
  214.                                                 t++;//每有一个位置同,则t自增
  215.                                         }
  216.                                 }
  217.                                 
  218.                                 if(t==16)//密码正确,可以进行修改密码的操作
  219.                                 {
  220.                                         OLED_Clear();
  221.                                         OLED_Show_CHinese(0,CCTitle7,1);//显示标题:修改密码
  222.                                         for(i=0;i<16;i++)
  223.                                         {
  224.                                                 OLED_Show_sChar(i*8,2,sChar3,1);//显示横线
  225.                                         }
  226.                                         OLED_Show_CHinese(4,CCInfo5,1);//显示说明文字:请输入新密码:
  227.                                         while(!KEY1);
  228.                                        
  229.                                         for(i=0;i<16;)//进入输密码的环节
  230.                                         {
  231.                                                 OLED_Show_Number(0,6,Admin_Password_New_Temp,i,1);//显示输入的值
  232.                                                 if(KeyScan()!=16)
  233.                                                 {
  234.                                                         delay(5000);
  235.                                                         if(KeyScan()!=16)
  236.                                                         {
  237.                                                                 Admin_Password_New_Temp[i]=KeyScan();//记录每一次输入的值
  238.                                                                 i++;
  239.                                                         }
  240.                                                         while(KeyScan()!=16);//等待按键松开
  241.                                                 }
  242.                                                 
  243.                                                 if(KEY1==0||i==16)//如果确定键按下或输满16位
  244.                                                 {
  245.                                                         delay(5000);
  246.                                                         if(KEY1==0||i==16)
  247.                                                         {
  248.                                                                 unsigned char k=0,t=0;
  249.                                                                 for(k=0;k<16;k++)
  250.                                                                 {
  251.                                                                         Administrator_Password[k]=Admin_Password_New_Temp[k];//存入新密码
  252.                                                                         Admin_Password_New_Temp[k]=0;//清空输入
  253.                                                                 }
  254.                                                         }
  255.                                                         while(!KEY1);
  256.                                                         OLED_Clear();//清屏,清屏放在此处可以使密码正确的提示信息在按键松开前一直显示
  257.                                                         break;//立即退出输入密码的环节
  258.                                                 }
  259.                                                 
  260.                                                 if(KEY2==0)//如果取消键按下
  261.                                                 {
  262.                                                         delay(5000);
  263.                                                         if(KEY2==0)
  264.                                                         {
  265.                                                                 unsigned char j;
  266.                                                                 for(j=0;j<16;j++)
  267.                                                                 {
  268.                                                                         Admin_Password_New_Temp[j]=0;//清空用户输入
  269.                                                                 }
  270.                                                                 OLED_Clear();//清屏                        
  271.                                                         }
  272.                                                         while(!KEY2);
  273.                                                         break;//立即退出输入密码的环节
  274.                                                 }
  275.                                         }
  276.                                 }
  277.                                 else//密码错误
  278.                                 {
  279.                                         for(k=0;k<16;k++)
  280.                                         {
  281.                                                 Admin_Password_Putin[k]=0;//清空管理员输入
  282.                                         }
  283.                                         OLED_Clear();
  284.                                 }
  285.                         }
  286.                         while(!KEY1);
  287.                         goto END;//结束输入
  288.                 }
  289.                
  290.                 if(KEY2==0)//如果取消键按下
  291.                 {
  292.                         delay(5000);
  293.                         if(KEY2==0)
  294.                         {
  295.                                 unsigned char j;
  296.                                 for(j=0;j<16;j++)
  297.                                 {
  298.                                         Admin_Password_Putin[j]=0;//清空管理员输入
  299.                                 }
  300.                                 OLED_Clear();
  301.                         }
  302.                         while(!KEY2);
  303.                         goto END;//结束输入
  304.                 }
  305.         }
  306. END:return 0;
  307. }

  308. void sys_init()//系统初始化
  309. {
  310.         P1M1=0x00;
  311.         P1M0=0x00;
  312.         P3M1=0x00;
  313.         P3M0=0x00;
  314.         P2M1=0x00;
  315.         P2M0=0x00;
  316.         P4M1=0x00;
  317.         P4M0=0x00;
  318.         P5M0=0x00;
  319.         P5M1=0x00;
  320.         P0M1=0x00;
  321.         P0M0=0x00;//对于STC15W4K32S4系列的单片机,对IO的初始化操作必须要有
  322.         
  323.         TMOD=0x11;//设置定时器模式
  324.         EA=1;//开启总中断
  325.         TL0=0x00;//设置定时初值
  326.         TH0=0x28;//设置定时初值
  327.         ET0=1;//允许定时器0中断
  328.         TR0=1;//定时器0开始计时
  329.         
  330.         TL1=0x00;//设置定时初值
  331.         TH1=0x28;//设置定时初值
  332.         ET1=1;//允许定时器1中断
  333.         TR1=0;//定时器1开始计时
  334.         
  335.         P1ASF=0x04;//将P1^2设置为模拟输入
  336.         ADC_CONTR=0xe7;//开启ADC电源,设置为最快转换速度,停止转换,选取P1^2作为ADC输入
  337.         ADC_RES=0;//清除结果寄存器
  338.         /*ADRJ=0;//ADC_RES[7:0]存放高8位ADC结果,ADC_RES[1:0]存放低2位ADC结果    EADC=1;//A/D转换中断允许    PADC=1;//设置A/D转换中断优先级为最高*/
  339.         //CLK_DIV=0X20;
  340.         EADC=1;
  341.         PADC=1;
  342. }

  343. void sys_Pretreat()//系统预处理
  344. {
  345.         //Ds1302Init();//首次上电对DS1302做初始化
  346.         OLED_Init();//初始化OLED
  347.         OLED_Clear();//OLED清屏
  348.         JDQ=0;//继电器给低电平
  349.         
  350.         /*在此处添加上电AT24C02检测*/
  351.         for(t1_cnt=0;t1_cnt<8;t1_cnt++)//将t1_cnt作为临时计时变量
  352.         {
  353.                 AT24C02_Read_Array[t1_cnt]=AT24C02_Read(0xA0,t1_cnt+1);
  354.                 Delay1ms();
  355.         }

  356.         for(t1_cnt=0;t1_cnt<4;t1_cnt++)//将t1_cnt作为临时计时变量
  357.         {
  358.                 if(AT24C02_Read_Array[t1_cnt]!=user_ID[t1_cnt])//如果从AT24C02中读出的用户ID和程序中设定值不同说明器件被更替,用户锁定,需要重新设置密码
  359.                 {
  360.                         User_Locker=1;
  361.                 }
  362.         }
  363.         t1_cnt=0;//使用后重置t1_cnt
  364. }

  365. void main()
  366. {
  367.         sys_init();
  368.         sys_Pretreat();
  369.         while(1)
  370.         {
  371.                 if(flag_Identity)//身份状态
  372.                 {//用户模式
  373.                         if(En_Standby)
  374.                         {//上锁的待机状态
  375.                                 LED1=1;LED2=1;
  376.                                 if(Admin_Info)
  377.                                 {
  378.                                         unsigned char i;
  379.                                         OLED_Show_CHinese(0,CCInfo6,1);//显示说明文字:继电器已启用
  380.                                         for(i=0;i<16;i++)
  381.                                         {
  382.                                                 OLED_Show_sChar(i*8,2,sChar4,1);//显示横线
  383.                                         }
  384.                                         OLED_Show_CHinese(4,CCText1,1);//显示说明文字:解锁由管理员初始
  385.                                 }
  386.                                 else
  387.                                 {
  388.                                         OLED_Display_Standby();//用户模式下,上锁时的待机显示
  389.                                 }
  390.                                 
  391.                                 if(KeyScan()!=16&&En_Standby&&(!User_Locker))//如果在某一时刻ADC键盘有了输入并且用户没有锁定则继续探测
  392.                                 {
  393.                                         delay(5000);
  394.                                         if(KeyScan()!=16&&En_Standby)
  395.                                         {
  396.                                                 unsigned char i;
  397.                                                 User_Password_Putin[0]=KeyScan();//那么重新捕获这个值
  398.                                                 while(KeyScan()!=16);//等待按键松开
  399.                                                 OLED_Clear();//OLED清屏
  400.                                                 OLED_Display_Put_In_Password();//显示密码输入界面
  401.                                                 OLED_Show_sChar(0,6,sChar1,1);//显示*
  402.                                                 for(i=1;i<16;)//进入输密码的环节
  403.                                                 {
  404.                                                         if(KeyScan()!=16)
  405.                                                         {
  406.                                                                 delay(5000);
  407.                                                                 if(KeyScan()!=16)
  408.                                                                 {
  409.                                                                         User_Password_Putin[i]=KeyScan();//记录每一次输入的值
  410.                                                                         OLED_Show_sChar(i*8,6,sChar1,1);//显示*
  411.                                                                         i++;
  412.                                                                 }
  413.                                                                 while(KeyScan()!=16);//等待按键松开
  414.                                                         }
  415.                                                         
  416.                                                         if(KEY1==0||i==16)//如果确定键按下或输满16位
  417.                                                         {
  418.                                                                 delay(5000);
  419.                                                                 if(KEY1==0||i==16)
  420.                                                                 {
  421.                                                                         unsigned char k=0,t=0;
  422.                                                                         Password_BKDRHASH_Calculation(User_Password_Putin,16);//对输入的值求HASH值,保存在hash_result数组中
  423.                                                                         
  424.                                                                         if(HASH_Compare())//密码正确
  425.                                                                         {
  426.                                                                                 En_Standby=0;//不再是待机状态
  427.                                                                                 JDQ=1;//开启继电器
  428.                                                                                 OLED_Clear();
  429.                                                                                 OLED_Display_Right_Password();
  430.                                                                                 t1_cnt=0;
  431.                                                                                 TR1=1;//定时器1开始计时
  432.                                                                         }
  433.                                                                         else//密码错误
  434.                                                                         {
  435.                                                                                 En_Standby=1;//仍在待机状态
  436.                                                                                 cnt_user_putin_wrong++;//错误计数增加一次
  437.                                                                                 if(cnt_user_putin_wrong==5)
  438.                                                                                 {
  439.                                                                                         User_Locker=1;//用户锁定有效
  440.                                                                                         cnt_user_putin_wrong=0;//但错误计数置0,这样一来在管理员模式下只需要关心用户锁定标志位即可
  441.                                                                                 }
  442.                                                                         }
  443.                                                                         
  444.                                                                         for(k=0;k<16;k++)
  445.                                                                         {
  446.                                                                                 User_Password_Putin[k]=0;//清空用户输入
  447.                                                                         }
  448.                                                                         
  449.                                                                         HASH_Result_Clear();//清空哈希计算结果
  450.                                                                 }
  451.                                                                 while(!KEY1);
  452.                                                                 OLED_Clear();//清屏,清屏放在此处可以使密码正确的提示信息在按键松开前一直显示
  453.                                                                 goto A;//立即退出输入密码的环节
  454.                                                         }
  455.                                                         
  456.                                                         if(KEY2==0)//如果取消键按下
  457.                                                         {
  458.                                                                 delay(5000);
  459.                                                                 if(KEY2==0)
  460.                                                                 {
  461.                                                                         unsigned char j;
  462.                                                                         for(j=0;j<16;j++)
  463.                                                                         {
  464.                                                                                 User_Password_Putin[j]=0;//清空用户输入
  465.                                                                         }
  466.                                                                         OLED_Clear();//清屏
  467.                                                                         HASH_Result_Clear();//清空哈希计算结果
  468.                                                                 }
  469.                                                                 while(!KEY2);
  470.                                                                 goto A;//立即退出输入密码的环节
  471.                                                         }
  472.                                                 }
  473. A:                                                _nop_();
  474.                                         }
  475.                                 }
  476.                                 
  477.                                 if(KEY1==0)//待机状态下KEY1是管理员入口开关
  478.                                 {
  479.                                         delay(8000);
  480.                                         if(KEY1==0)
  481.                                         {
  482.                                                 if(Hardware_Switch==0)
  483.                                                 {
  484.                                                         OLED_Clear();
  485.                                                         flag_Identity=0;
  486.                                                 }
  487.                                         }
  488.                                         while(!KEY1);
  489.                                 }
  490.                         }
  491.                         else
  492.                         {//解锁的待机状态
  493.                                 OLED_User_Mode();//用户模式菜单动态显示
  494.                                 LED1=0;LED2=1;
  495.                                 if(KEY1==0)//确定按键
  496.                                 {
  497.                                         delay(5000);
  498.                                         if(KEY1==0)
  499.                                         {
  500.                                                 switch(choose)
  501.                                                 {
  502.                                                         case 1:
  503.                                                                 JDQ=0;//关闭继电器
  504.                                                                 TR1=0;//定时器1停止计时
  505.                                                                 TL1=0x00;//设置定时初值
  506.                                                                 TH1=0x28;//设置定时初值
  507.                                                                 t1_cnt=0;
  508.                                                                 En_Standby=1;//重新回到上锁状态
  509.                                                                 break;
  510.                                                         case 2:
  511.                                                                 while(!KEY1);//等待按键松开,若不加此句可能导致Modify_User_Password()瞬间运行完,用户密码变为0
  512.                                                                 choose=1;//重置菜单选择位
  513.                                                                 TR1=0;//定时器1停止计时
  514.                                                                 TL1=0x00;//设置定时初值
  515.                                                                 TH1=0x28;//设置定时初值
  516.                                                                 t1_cnt=0;
  517.                                                                 Modify_User_Password();
  518.                                                                 TR1=1;//定时器1开始计时
  519.                                                                 break;
  520.                                                 }
  521.                                         }
  522.                                         while(!KEY1);
  523.                                         OLED_Clear();
  524.                                 }
  525.                                 
  526.                                 if(KEY2==0)//取消按键
  527.                                 {
  528.                                         delay(5000);
  529.                                         if(KEY2==0)
  530.                                         {
  531.                                                 choose=1;//重置菜单选择位
  532.                                                 JDQ=0;//关闭继电器
  533.                                                 TR1=0;//定时器1停止计时
  534.                                                 TL1=0x00;//设置定时初值
  535.                                                 TH1=0x28;//设置定时初值
  536.                                                 t1_cnt=0;
  537.                                                 En_Standby=1;//重新回到上锁状态
  538.                                         }
  539.                                         while(!KEY2);
  540.                                         OLED_Clear();
  541.                                 }
  542.                                 
  543.                                 if(_ReLock)//自动上锁判断
  544.                                 {
  545.                                         En_Standby=1;//重新回到上锁状态
  546.                                         _ReLock=0;//重置标志位
  547.                                         TR1=0;//关闭定时器1
  548.                                         TL1=0x00;//设置定时初值
  549.                                         TH1=0x28;//设置定时初值
  550.                                         t1_cnt=0;//重置定时器1运行计数
  551.                                         OLED_Clear();//此处的清屏使用户菜单在待机界面没有残留
  552.                                 }
  553.                         }
  554.                 }
  555.                 else
  556.                 {//管理员状态确认
  557.                         if(Hardware_Switch==0)
  558.                         {//管理员模式
  559.                                 if(En_Admin)//管理有效
  560.                                 {
  561.                                         OLED_Admin_Mode();//管理模式菜单动态显示
  562.                                         LED1=1;LED2=0;
  563.                                         if(KEY1==0)//确定按键
  564.                                         {
  565.                                                 delay(5000);
  566.                                                 if(KEY1==0)
  567.                                                 {
  568.                                                         switch(choose)
  569.                                                         {
  570.                                                                 case 1:
  571.                                                                         User_Locker=0;//解除用户锁定
  572.                                                                         break;
  573.                                                                 case 2:
  574.                                                                         while(!KEY1);//等待按键松开,若不加此句可能导致Modify_User_Password()瞬间运行完,用户密码变为0
  575.                                                                         Modify_User_Password();
  576.                                                                         break;
  577.                                                                 case 3:
  578.                                                                         while(!KEY1);//等待按键松开,若不加此句可能导致Modify_Admin_Password()瞬间运行完,管理密码变为0
  579.                                                                         Modify_Admin_Password();
  580.                                                                         break;
  581.                                                                 case 4:
  582.                                                                         OLED_Admin_onoff_Mode();//常开常关选项
  583.                                                                         break;
  584.                                                                 case 5:
  585.                                                                         OLED_Display_System_Information();//显示版本信息
  586.                                                                         break;
  587.                                                                 case 6:
  588.                                                                         En_Admin=0;//管理无效
  589.                                                                         break;
  590.                                                         }
  591.                                                 }
  592.                                                 while(!KEY1);
  593.                                                 OLED_Clear();
  594.                                         }
  595.                                        
  596.                                         if(KEY2==0)//取消按键
  597.                                         {
  598.                                                 delay(5000);
  599.                                                 if(KEY2==0)
  600.                                                 {
  601.                                                         En_Admin=0;//管理无效
  602.                                                 }
  603.                                                 while(!KEY2);
  604.                                                 OLED_Clear();
  605.                                         }
  606.                                 }
  607.                                 else//管理无效
  608.                                 {
  609.                                         OLED_Display_Administrator_Onload();
  610.                                         LED1=1;LED2=1;
  611.                                         if(KeyScan()!=16&&(!En_Admin))//如果在某一时刻ADC键盘有了输入
  612.                                         {
  613.                                                 delay(5000);
  614.                                                 if(KeyScan()!=16&&(!En_Admin))
  615.                                                 {
  616.                                                         unsigned char i;
  617.                                                         Admin_Password_Putin[0]=KeyScan();//那么重新捕获这个值
  618.                                                         while(KeyScan()!=16);//等待按键松开
  619.                                                         OLED_Show_sChar(0,6,sChar1,1);//显示*
  620.                                                         
  621.                                                         for(i=1;i<16;)//进入输密码的环节,如果前面有对第一位密码的捕获操作,则此处的循环从1开始15次
  622.                                                         {
  623.                                                                 if(KeyScan()!=16)
  624.                                                                 {
  625.                                                                         delay(5000);
  626.                                                                         if(KeyScan()!=16)
  627.                                                                         {
  628.                                                                                 Admin_Password_Putin[i]=KeyScan();//记录每一次输入的值
  629.                                                                                 OLED_Show_sChar(i*8,6,sChar1,1);//显示*
  630.                                                                                 i++;
  631.                                                                         }
  632.                                                                         while(KeyScan()!=16);//等待按键松开
  633.                                                                 }
  634.                                                                
  635.                                                                 if(KEY1==0||i==16)//如果确定键按下或输入位数满
  636.                                                                 {
  637.                                                                         delay(5000);
  638.                                                                         if(KEY1==0||i==16)
  639.                                                                         {
  640.                                                                                 unsigned char k=0,t=0;
  641.                                                                                 for(k=0;k<16;k++)
  642.                                                                                 {
  643.                                                                                         if(Admin_Password_Putin[k]==Administrator_Password[k])//核对明文密码
  644.                                                                                         {
  645.                                                                                                 t++;//每有一个位置同,则t自增
  646.                                                                                         }
  647.                                                                                 }
  648.                                                                                 
  649.                                                                                 if(t==16)//密码正确
  650.                                                                                 {
  651.                                                                                         En_Admin=1;//管理有效
  652.                                                                                 }
  653.                                                                                 else//密码错误
  654.                                                                                 {
  655.                                                                                         En_Admin=0;//管理无效
  656.                                                                                 }
  657.                                                                                 
  658.                                                                                 for(k=0;k<16;k++)
  659.                                                                                 {
  660.                                                                                         Admin_Password_Putin[k]=0;//清空管理员输入
  661.                                                                                 }
  662.                                                                                 OLED_Clear();
  663.                                                                         }
  664.                                                                         while(!KEY1);
  665.                                                                         goto B;//立即退出输入密码的环节
  666.                                                                 }
  667.                                                                
  668.                                                                 if(KEY2==0||Hardware_Switch==1)//如果取消键按下或硬件标志位被置1
  669.                                                                 {
  670.                                                                         delay(5000);
  671.                                                                         if(KEY2==0||Hardware_Switch==1)
  672.                                                                         {
  673.                                                                                 unsigned char j;
  674.                                                                                 for(j=0;j<16;j++)
  675.                                                                                 {
  676.                                                                                         Admin_Password_Putin[j]=0;//清空管理员输入
  677.                                                                                 }
  678.                                                                                 OLED_Clear();
  679.                                                                         }
  680.                                                                         while(!KEY2);
  681.                                                                         goto B;//立即退出输入密码的环节
  682.                                                                 }
  683.                                                         }
  684.                                                 }
  685.                                         }
  686. B:                                        _nop_();
  687.                                 }
  688.                         }
  689.                         else//如果硬件标志位被置1
  690.                         {
  691.                                 OLED_Clear();
  692.                                 En_Admin=0;//管理无效
  693.                                 choose=1;//由于管理模式菜单和用户模式共用一个选择项,并且菜单显示和choose有关,所以如果不重置菜单选中位,菜单长度的不同会导致用户显示的失败
  694.                                 first_num=1;/*如果第一项菜单标号first_num改为全局变量,那么在此处将它置1可以保证每一次进入管理菜单是默认选中第一项*/
  695.                                 flag_Identity=1;//返回用户状态
  696.                         }
  697.                 }
  698.         }
  699. }
  700. ……………………

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

所有资料51hei提供下载:
密码锁基本版 凌净清河.zip (260.4 KB, 下载次数: 227)

评分

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

查看全部评分

回复

使用道具 举报

ID:362076 发表于 2019-1-7 16:12 | 显示全部楼层
第二版的密码锁设计已经上传到本站,但是被移动到“单片机DIY”区域了,特此说明,本帖子的承诺没有鸽!
回复

使用道具 举报

ID:71421 发表于 2018-12-5 21:13 | 显示全部楼层
感谢分享!!!!!!!!!!

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15

查看全部评分

回复

使用道具 举报

ID:102963 发表于 2018-12-6 08:51 | 显示全部楼层
相当不错的设计!!

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 受到了相当大的鼓励!

查看全部评分

回复

使用道具 举报

ID:295874 发表于 2018-12-6 09:45 | 显示全部楼层
强大,学习的动力

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载补贴黑币

查看全部评分

回复

使用道具 举报

ID:328014 发表于 2018-12-11 16:06 | 显示全部楼层
设计思路很新颖,这个完善一下可以用于实际了

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 感谢回帖评价

查看全部评分

回复

使用道具 举报

ID:444537 发表于 2018-12-11 23:08 | 显示全部楼层
很强,感谢分享!!!

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载黑币补贴

查看全部评分

回复

使用道具 举报

ID:358930 发表于 2018-12-12 03:37 | 显示全部楼层
这么专业,让人向往,请教。有颜色高速识别的传感器例程吗?或者是方向。就是一段电线从传感器通过,有一小段几厘米不同色能快速识别吗?如TCS3200,好像要用些高级算法才能用于生产,还有什么传感器吗?
回复

使用道具 举报

ID:362076 发表于 2018-12-12 10:26 | 显示全部楼层
冰冰洁洁 发表于 2018-12-12 03:37
这么专业,让人向往,请教。有颜色高速识别的传感器例程吗?或者是方向。就是一段电线从传感器通过,有一小 ...

抱歉,颜色传感器我还没有用过。不过有一点是不变的,一分钱一分货,想要高性能,一定程度上就要多花钱,TCS3200的颜色好像需要再矫正一下才能达到精度,要不试试TCS34725?
关于TCS3200,这一篇文章说的挺详细的,不知道你看没看过
https://blog.csdn.net/b108074013/article/details/50240219
回复

使用道具 举报

ID:358930 发表于 2018-12-12 18:21 | 显示全部楼层
谢谢,正在想办法,看来运用的不太多,但是方向很重要,不行先试试TCS34725,改天做过去测试,这个好像是串口通信,内部有MCU计算,看来有点像18b20,相信能简单点。祝考研顺利,真想知道了您考研的是什么课题……
回复

使用道具 举报

ID:362076 发表于 2018-12-13 11:11 | 显示全部楼层
冰冰洁洁 发表于 2018-12-12 18:21
谢谢,正在想办法,看来运用的不太多,但是方向很重要,不行先试试TCS34725,改天做过去测试,这个好像是串 ...

感谢祝愿,如果我考研初试顺利,复试的科目就是单片机。
回复

使用道具 举报

ID:445711 发表于 2018-12-13 16:36 | 显示全部楼层
本科的时候也设计过一个密码锁,只是没有成功。

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载补贴15黑币

查看全部评分

回复

使用道具 举报

ID:445380 发表于 2018-12-13 16:51 | 显示全部楼层
这个比较牛叉对于初学者而言有参考价值

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载补贴15黑币

查看全部评分

回复

使用道具 举报

ID:362076 发表于 2018-12-13 22:23 | 显示全部楼层
知守 发表于 2018-12-13 16:36
本科的时候也设计过一个密码锁,只是没有成功。

密码锁还是比较简单的一个实例,本科不成功,现在也可以再做一个试试呀
回复

使用道具 举报

ID:362076 发表于 2018-12-13 22:24 | 显示全部楼层
电子学系 发表于 2018-12-13 16:51
这个比较牛叉对于初学者而言有参考价值

这只是有基本功能,在机制上还要在完善一下,另外可以增加射频卡的功能,这个功能在第二版里添加上了
回复

使用道具 举报

ID:354282 发表于 2018-12-14 08:18 | 显示全部楼层
支持,很好,喜欢加油,做自己喜欢的硬件,方便的话,大家一起交流学习。

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 感谢支持!

查看全部评分

回复

使用道具 举报

ID:237159 发表于 2018-12-14 10:50 | 显示全部楼层
好东西,谢谢分享

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载补贴

查看全部评分

回复

使用道具 举报

ID:228888 发表于 2018-12-17 17:27 | 显示全部楼层
我是新手,喜欢,谢谢楼主

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载补贴黑币~

查看全部评分

回复

使用道具 举报

ID:448297 发表于 2018-12-17 20:18 | 显示全部楼层
gnez 发表于 2018-12-5 21:13
感谢分享!!!!!!!!!!

棒 啊,特别好吧

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载黑币补贴!

查看全部评分

回复

使用道具 举报

ID:448333 发表于 2018-12-17 20:32 | 显示全部楼层
感谢分享

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载黑币补贴!

查看全部评分

回复

使用道具 举报

ID:448333 发表于 2018-12-17 20:32 | 显示全部楼层
非常新颖

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载黑币补贴!

查看全部评分

回复

使用道具 举报

ID:446953 发表于 2018-12-17 21:05 | 显示全部楼层
感谢楼主分享源码,正愁没东西参考呢

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载黑币补贴!

查看全部评分

回复

使用道具 举报

ID:449175 发表于 2018-12-18 19:39 | 显示全部楼层
楼主真厉害  够新颖

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载黑币补贴!

查看全部评分

回复

使用道具 举报

ID:449978 发表于 2018-12-19 17:58 | 显示全部楼层
可以哦6666

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载黑币补贴!

查看全部评分

回复

使用道具 举报

ID:449175 发表于 2018-12-21 17:15 来自手机 | 显示全部楼层
明天加油  一切顺利(ò  ó)

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 哈哈,我考完才看见,是不是有点晚咯?

查看全部评分

回复

使用道具 举报

ID:454478 发表于 2018-12-25 15:59 | 显示全部楼层
这也太棒了吧

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载补贴黑币

查看全部评分

回复

使用道具 举报

ID:409674 发表于 2019-1-7 21:49 | 显示全部楼层
感谢楼主分享源码

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载黑币补贴

查看全部评分

回复

使用道具 举报

ID:417702 发表于 2019-1-9 10:28 | 显示全部楼层
流弊,感谢楼主的分享!

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载黑币补贴

查看全部评分

回复

使用道具 举报

ID:471227 发表于 2019-1-23 17:22 | 显示全部楼层
学习了,感谢分享!

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载补贴

查看全部评分

回复

使用道具 举报

ID:60656 发表于 2019-1-23 20:29 | 显示全部楼层
学习一下,感谢分享

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载补贴

查看全部评分

回复

使用道具 举报

ID:472369 发表于 2019-1-24 17:38 | 显示全部楼层
厉害厉害!我有一个学长学完课程自己摸索出来一个,都没有你这个厉害!

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 非常感谢~笔芯~

查看全部评分

回复

使用道具 举报

ID:318309 发表于 2019-1-24 20:56 | 显示全部楼层
楼主好强啊,谢谢楼主分享

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载补贴

查看全部评分

回复

使用道具 举报

ID:470892 发表于 2019-1-24 22:25 | 显示全部楼层
感谢楼主分享

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载补贴

查看全部评分

回复

使用道具 举报

ID:470892 发表于 2019-1-24 22:45 | 显示全部楼层
感谢楼主分享

评分

参与人数 1黑币 +15 收起 理由
凌净清河 + 15 下载补贴

查看全部评分

回复

使用道具 举报

ID:486236 发表于 2019-3-7 14:24 | 显示全部楼层
感谢楼主分享

评分

参与人数 1黑币 +12 收起 理由
NPC-1024 + 12 下载补贴

查看全部评分

回复

使用道具 举报

ID:248611 发表于 2019-3-8 00:11 | 显示全部楼层
感谢楼主分享,很好的学习资料

评分

参与人数 1黑币 +16 收起 理由
凌净清河 + 16 黑币补贴

查看全部评分

回复

使用道具 举报

ID:458411 发表于 2019-3-8 15:46 | 显示全部楼层
很好的学习资料,感谢楼主分享
回复

使用道具 举报

ID:338565 发表于 2019-4-11 19:51 | 显示全部楼层
哇!学长厉害了,请问考研结果怎么样了呢?
回复

使用道具 举报

ID:539581 发表于 2019-5-30 08:26 | 显示全部楼层
对于我们这种初学者太有用了吧!赞!
回复

使用道具 举报

ID:466896 发表于 2019-5-30 09:47 | 显示全部楼层
15系列的单片机不是有内部存储吗?为啥要写到外部哎?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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