找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6453|回复: 19
收起左侧

自己做的单片机密码锁课程设计,内附视频,电路图,keil及hex文件

  [复制链接]
ID:257868 发表于 2017-12-16 22:11 | 显示全部楼层 |阅读模式
       分享一个自己上周做的课程设计:密码锁不仅有基本的功能,还有实现密码正确电机正转三圈,反转三圈。
以下是电路仿真截图及工程文件截图以及视频演示。有需要的可以自行下载。
0.jpg
开机时实物照片
0.jpg

密码正确时实物照片
0.jpg

仿真电路原理图如下(proteus仿真工程文件可到本帖附件中下载)
proteus仿真截图.png 工程文件截图.png

单片机源程序(hex文件):

  1. #include<reg51.h>
  2. #include"lcd.h"

  3. #define GPIO_KEY P1
  4. #define uint unsigned int
  5. #define INT8U unsigned char
  6. unsigned char KeyValue,flag,key;
  7. //用来存放读取到的键值
  8. unsigned char KeyState;
  9. //用来存放按键状态
  10. unsigned char PuZh[]="H082";
  11. unsigned char time[]=" TIME5 ";
  12. unsigned char key_right[]="right";
  13. unsigned char key_error[]="error";
  14. unsigned char right_dat[]="9999";
  15. unsigned char dat[]="0123456789HBCDEF";
  16. unsigned char key_dat[4]={0};
  17. void Delay10ms(char time);   //延时10ms
  18. void KeyDown();                 //检测按键函数
  19. void test();         //密码检测函数
  20. void STEP_MOTOR_FFW(INT8U n);
  21. void STEP_MOTOR_REV(INT8U n);

  22. void clock_write(uchar ad,uint s);
  23. sbit   LED0= P2^3;
  24. sbit   BEEP= P2^2;
  25. unsigned char FFW[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};
  26. unsigned char REV[]={0X09,0X08,0X0C,0X04,0X06,0X02,0X03,0X01};
  27. INT8U second;
  28. INT8U        second=5;
  29. INT8U int_time;
  30. /*******************************************************************************
  31. * 函 数 名         : main
  32. * 函数功能                   : 主函数
  33. * 输    入         : 无
  34. * 输    出         : 无
  35. *******************************************************************************/
  36. void main(void)
  37. {
  38.         unsigned char i,j;
  39.         LcdInit();
  40.         KeyState=0;
  41.         TMOD=0X01;
  42.         EA=1;
  43.         ET0=1;
  44.         TH0=(65536-46083)/256;
  45.     TL0=(65536-46083)%256;
  46.         TR0=0;
  47.         int_time=0;
  48.         for(i=0;i<16;i++)
  49.         {
  50.          LcdWriteData(PuZh[i]);}
  51.          Delay10ms(3000);                //等待3秒
  52.            LcdWriteCom(0x01);        
  53.         while(1)
  54.         {
  55.                 KeyDown();
  56.                 if(KeyValue==11)   //  密码不显示
  57.                 {
  58.                         LcdWriteCom(0x01);
  59.                         LcdWriteCom(0x80+0x40);
  60.                         key=0;
  61.                 }
  62.                 if(KeyState)
  63.                 {
  64.                         KeyState=0;
  65.                         LcdWriteCom(0x80+0x40+key);
  66.                         if(KeyValue<11)
  67.                         {
  68.                                 LcdWriteData(dat[KeyValue]);
  69.                                 key_dat[key]=dat[KeyValue];
  70.                                 key++;
  71.                                 if(key==4)
  72.                             {        
  73.                                     test();key=0;
  74.                                         }
  75.                             }
  76.                 }
  77.          }                                
  78. }
  79. /*******************************************************************************
  80. * 函 数 名         : KeyDown
  81. * 函数功能                   : 检测有按键按下并读取键值
  82. * 输    入         : 无
  83. * 输    出         : 无
  84. *******************************************************************************/
  85. void KeyDown(void)
  86. {
  87.         char a,j;
  88.         GPIO_KEY=0x0f;
  89.         if(GPIO_KEY!=0x0f)
  90.         {
  91.                 Delay10ms(1);
  92.                 if(GPIO_KEY!=0x0f)
  93.                 {
  94.                         KeyState=1;
  95.                         //测试列
  96.                         GPIO_KEY=0X0F;
  97.                         switch(GPIO_KEY)
  98.                         {
  99.                                 case(0X07):        KeyValue=0;break;
  100.                                 case(0X0b):        KeyValue=1;break;
  101.                                 case(0X0d): KeyValue=2;break;
  102.                                 case(0X0e):        KeyValue=3;break;
  103.                         }
  104.                         //测试行
  105.                         GPIO_KEY=0XF0;
  106.                         Delay10ms(1);
  107.                         switch(GPIO_KEY)
  108.                         {
  109.                                 case(0X70):        KeyValue=KeyValue;break;
  110.                                 case(0Xb0):        KeyValue=KeyValue+4;break;
  111.                                 case(0Xd0): KeyValue=KeyValue+8;break;
  112.                                 case(0Xe0):        KeyValue=KeyValue+12;break;
  113.                         }
  114.                         if(KeyValue==12) //密码显示
  115.                         {
  116.                            LcdWriteCom(0x80);
  117.                            for(j=0;j<10;j++)  LcdWriteData(PuZh[j]);        
  118.                            for(j=0;j<4;j++)
  119.                            {
  120.                              LcdWriteCom(0x80+0x40+j);
  121.                                  LcdWriteData(key_dat[j]);
  122.                            }
  123.                         }
  124.                         if(KeyValue==13)   // 重新输入密码
  125.                         {
  126.                                 LcdWriteCom(0x01);
  127.                                 LcdWriteCom(0x80); key=0;flag=0;
  128.                                 for(j=0;j<10;j++) LcdWriteData(PuZh[j]);
  129.                                 for(j=0;j<4;j++)  key_dat[j]=0;
  130.                         }
  131.                         while((a<50)&&(GPIO_KEY!=0xf0))         //检测按键松手检测
  132.                         {
  133.                                 Delay10ms(1);
  134.                                 a++;
  135.                         }
  136.                         a=0;
  137.                 }
  138.         }
  139. }
  140. /*******************************************************************************
  141. * 函 数 名         : Delay10ms
  142. * 函数功能                   : 延时函数,延时10ms
  143. * 输    入         : 无
  144. * 输    出         : 无
  145. *******************************************************************************/
  146. void Delay10ms(char time)   //误差 0us
  147. {
  148.     unsigned char a,b,c;
  149.     for(c=time;c>0;c--)
  150.         for(b=38;b>0;b--)
  151.             for(a=130;a>0;a--);
  152. }
  153. /*******************************************************************************
  154. * 函 数 名         : test
  155. * 函数功能                   : 密码检测函数
  156. * 输    入         : 无
  157. * 输    出         : 无
  158. *******************************************************************************/
  159. void test()
  160. {        uint x;
  161.     INT8U N=3;
  162.         char i,j;
  163.         for(i=0;i<4;i++)//密码检测
  164.         {
  165.             if(right_dat[i]==key_dat[i]) flag++;
  166.         }
  167.         if(flag==4)  //密码正确
  168.         {   
  169.                
  170.             for(j=0;j<5;j++)  LcdWriteData(key_right[j]);               
  171.                   for(x=0;x<100;x++)                                //光声控制
  172.                   {Delay10ms(1);BEEP=~BEEP;}
  173.                   BEEP=1;   
  174.                   LED0=0;
  175.                   STEP_MOTOR_FFW(N);                                //电机
  176.                   TR0=1;
  177.                   for(j=0;j<16;j++)                 //倒计时
  178.               {   
  179.                         LcdWriteData(time[j]);}
  180.                 clock_write(0x80,second);        
  181.         }
  182.         else             //密码错误
  183.         {
  184.             flag=0;
  185.             LcdWriteCom(0x80+0x46);
  186.             Delay10ms(50);
  187.             for(j=0;j<5;j++)  LcdWriteData(key_error[j]);
  188.         }
  189. }

  190. void STEP_MOTOR_FFW(INT8U n)                //电机
  191. { INT8U i,j;
  192. for(i=0;i<5*n;i++)
  193. { for(j=0;j<8;j++)
  194.    {P3=FFW[j];
  195.    Delay10ms(25);}}        }
  196. void STEP_MOTOR_REV(INT8U n)
  197. { INT8U i,j;
  198. for(i=0;i<5*n;i++)
  199. { for(j=0;j<8;j++)
  200.    {P3=REV[j];
  201.    Delay10ms(25);}}        }


  202. void clock_write(uchar ad,uint second)           //倒计时
  203. { LcdWriteCom(ad);
  204.   LcdWriteData(second);
  205.   Delay10ms(100);}
  206. void T0_interserve(void) interrupt 1
  207. {         INT8U N=3;
  208.    TH0=(65536-46083)/256;
  209.    TL0=(65536-46083)%256;
  210.    int_time++;
  211.   if(int_time==20)
  212.    { int_time=0;
  213.      second--;}
  214.          if(second==0)
  215.          {STEP_MOTOR_REV(N);}
  216.   
  217.    }
  218.     #include"lcd.h"

  219. /*******************************************************************************
  220. * 函 数 名         : Lcd1602_Delay1ms
  221. * 函数功能                   : 延时函数,延时1ms
  222. * 输    入         : c
  223. * 输    出         : 无
  224. * 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时。
  225. *******************************************************************************/

  226. void Lcd1602_Delay1ms(uint c)   //误差 0us
  227. {
  228.     uchar a,b;
  229.         for (; c>0; c--)
  230.         {
  231.                  for (b=199;b>0;b--)
  232.                  {
  233.                           for(a=1;a>0;a--);
  234.                  }      
  235.         }
  236.             
  237. }

  238. /*******************************************************************************
  239. * 函 数 名         : LcdWriteCom
  240. * 函数功能                   : 向LCD写入一个字节的命令
  241. * 输    入         : com
  242. * 输    出         : 无
  243. *******************************************************************************/
  244. #ifndef         LCD1602_4PINS         //当没有定义这个LCD1602_4PINS时
  245. void LcdWriteCom(uchar com)          //写入命令
  246. {
  247.         LCD1602_E = 0;     //使能
  248.         LCD1602_RS = 0;           //选择发送命令
  249.         LCD1602_RW = 0;           //选择写入
  250.         
  251.         LCD1602_DATAPINS = com;     //放入命令
  252.         Lcd1602_Delay1ms(1);                //等待数据稳定

  253.         LCD1602_E = 1;                  //写入时序
  254.         Lcd1602_Delay1ms(5);          //保持时间
  255.         LCD1602_E = 0;
  256. }
  257. #else
  258. void LcdWriteCom(uchar com)          //写入命令
  259. {
  260.         LCD1602_E = 0;         //使能清零
  261.         LCD1602_RS = 0;         //选择写入命令
  262.         LCD1602_RW = 0;         //选择写入

  263.         LCD1602_DATAPINS = com;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
  264.         Lcd1602_Delay1ms(1);

  265.         LCD1602_E = 1;         //写入时序
  266.         Lcd1602_Delay1ms(5);
  267.         LCD1602_E = 0;

  268. //        Lcd1602_Delay1ms(1);
  269.         LCD1602_DATAPINS = com << 4; //发送低四位
  270.         Lcd1602_Delay1ms(1);

  271.         LCD1602_E = 1;         //写入时序
  272.         Lcd1602_Delay1ms(5);
  273.         LCD1602_E = 0;
  274. }
  275. #endif
  276. /*******************************************************************************
  277. * 函 数 名         : LcdWriteData
  278. * 函数功能                   : 向LCD写入一个字节的数据
  279. * 输    入         : dat
  280. * 输    出         : 无
  281. *******************************************************************************/                  
  282. #ifndef         LCD1602_4PINS                  
  283. void LcdWriteData(uchar dat)                        //写入数据
  284. {
  285.         LCD1602_E = 0;        //使能清零
  286.         LCD1602_RS = 1;        //选择输入数据
  287.         LCD1602_RW = 0;        //选择写入

  288.         LCD1602_DATAPINS = dat; //写入数据
  289.         Lcd1602_Delay1ms(1);

  290.         LCD1602_E = 1;   //写入时序
  291.         Lcd1602_Delay1ms(5);   //保持时间
  292.         LCD1602_E = 0;
  293. }
  294. #else
  295. void LcdWriteData(uchar dat)                        //写入数据
  296. {
  297.         LCD1602_E = 0;          //使能清零
  298.         LCD1602_RS = 1;          //选择写入数据
  299.         LCD1602_RW = 0;          //选择写入

  300.         LCD1602_DATAPINS = dat;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
  301.         Lcd1602_Delay1ms(1);

  302.         LCD1602_E = 1;          //写入时序
  303.         Lcd1602_Delay1ms(5);
  304.         LCD1602_E = 0;

  305.         LCD1602_DATAPINS = dat << 4; //写入低四位
  306.         Lcd1602_Delay1ms(1);

  307.         LCD1602_E = 1;          //写入时序
  308.         Lcd1602_Delay1ms(5);
  309.         LCD1602_E = 0;
  310. }
  311. #endif
  312. /*******************************************************************************
  313. * 函 数 名       : LcdInit()
  314. * 函数功能                 : 初始化LCD屏
  315. * 输    入       : 无
  316. * 输    出       : 无
  317. *******************************************************************************/                  
  318. #ifndef                LCD1602_4PINS
  319. void LcdInit()                                                  //LCD初始化子程序
  320. {
  321.          LcdWriteCom(0x38);  //开显示
  322.         LcdWriteCom(0x0c);  //开显示不显示光标
  323.         LcdWriteCom(0x06);  //写一个指针加1
  324.         LcdWriteCom(0x01);  //清屏
  325.         LcdWriteCom(0x80);  //设置数据指针起点
  326. }
  327. #else
  328. void LcdInit()                                                  //LCD初始化子程序
  329. {
  330.         LcdWriteCom(0x32);         //将8位总线转为4位总线
  331.         LcdWriteCom(0x28);         //在四位线下的初始化
  332.         LcdWriteCom(0x0c);  //开显示不显示光标
  333.         LcdWriteCom(0x06);  //写一个指针加1
  334.         LcdWriteCom(0x01);  //清屏
  335.         LcdWriteCom(0x80);  //设置数据指针起点

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

全部资料51hei下载地址:
多功能密码锁.rar (14.8 MB, 下载次数: 208)

评分

参与人数 3黑币 +108 收起 理由
waitc + 3 绝世好帖!
Amazing云山 + 5
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:87193 发表于 2017-12-18 14:59 | 显示全部楼层
设计挺好的,下载了看看,谢谢分享

评分

参与人数 1黑币 +1 收起 理由
10072805 + 1 赞一个!

查看全部评分

回复

使用道具 举报

ID:352858 发表于 2018-6-16 14:16 | 显示全部楼层
不错,下载学习!
回复

使用道具 举报

ID:350392 发表于 2018-6-16 15:13 | 显示全部楼层
挺好的,来自新手的膜拜
回复

使用道具 举报

ID:275175 发表于 2018-6-22 13:13 | 显示全部楼层
学习学习。谢谢。
回复

使用道具 举报

ID:356605 发表于 2018-6-22 14:16 | 显示全部楼层
新人一个,前来学习学习。
回复

使用道具 举报

ID:365788 发表于 2018-7-7 14:50 | 显示全部楼层
厉害厉害,学习了,
回复

使用道具 举报

ID:361206 发表于 2018-7-9 12:19 来自手机 | 显示全部楼层
可以改为六位密码吗
回复

使用道具 举报

ID:459850 发表于 2019-1-2 11:03 | 显示全部楼层
想问下楼主用的什么板子呢
回复

使用道具 举报

ID:459880 发表于 2019-1-2 11:25 | 显示全部楼层
看起来很厉害的样子。。膜拜一下
回复

使用道具 举报

ID:463109 发表于 2019-1-6 18:29 | 显示全部楼层
很好  非常感谢
回复

使用道具 举报

ID:467270 发表于 2019-3-14 19:51 | 显示全部楼层
强的一批
回复

使用道具 举报

ID:121195 发表于 2019-3-14 22:08 | 显示全部楼层
下载了看看,谢谢分享
回复

使用道具 举报

ID:542290 发表于 2019-5-19 19:41 | 显示全部楼层
下载看看谢谢
回复

使用道具 举报

ID:549713 发表于 2019-5-30 22:20 | 显示全部楼层
感觉不错呀
回复

使用道具 举报

ID:617814 发表于 2019-10-8 11:32 | 显示全部楼层
有没有门磁
回复

使用道具 举报

ID:617814 发表于 2019-10-8 11:33 | 显示全部楼层
如何加入生物识别模块
回复

使用道具 举报

ID:599674 发表于 2019-10-27 18:40 | 显示全部楼层
对不起 是我看错了 里面有视频的
回复

使用道具 举报

ID:649596 发表于 2019-11-26 08:39 | 显示全部楼层
感谢感谢,太优秀了
回复

使用道具 举报

ID:649596 发表于 2019-11-26 10:10 | 显示全部楼层
学习观察,发现好丰富啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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