单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机密码门禁系统综合实验 proteus仿真+程序源码

[复制链接]
跳转到指定楼层
楼主
采用51单片机设计门禁系统,4X4键盘用户输入密码,错误蜂鸣器叫一声,正确LED闪烁,12864作为用户界面,初始显示“欢迎光临”,正确与错误时12864有相应的提示。

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


单片机源程序如下:
  1. #include <reg51.h>
  2. #define        uchar unsigned char
  3. #define uint unsigned int
  4. #define _nop {}                                                        //空操作
  5. #define PAGEADD 0xb8        //页地址起始
  6. #define TIERADD 0x40                //行地址起始          
  7. #define DIS_STARADD 0xc0          //开始命令

  8. uchar row,column,c;
  9.        
  10. sbit CS2 = P3 ^ 3;                                                       
  11. sbit CS1 = P3 ^ 4;                                                       
  12. sbit E   = P3 ^ 5;        //定义使能端                                               
  13. sbit RW  = P3 ^ 6;                                                       
  14. sbit DI  = P3 ^ 7;                               
  15.        
  16. sbit INT = P3 ^ 2;        //外部中断0引脚
  17. sbit buzzer = P3 ^ 0;
  18. sbit P3_1 = P3 ^ 1;
  19. sbit LED = P3 ^ 1;
  20.        
  21. uchar flog = 0;
  22. uchar flog1 = 0;
  23. //键值数组
  24. uchar cc[] = {0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};
  25. /****************************
  26. 汉字显示
  27. *****************************/
  28. uchar code table2[] = {                     //加code在ROM
  29.                 //-- 密 --
  30.      0x10,0x4C,0x24,0x04,0xF4,0x84,0x4D,0x56,0x24,0x24,0x14,0x84,0x24,0x54,0x0C,0x00,//16字节
  31.      0x00,0x01,0xFD,0x41,0x40,0x41,0x41,0x7F,0x41,0x41,0x41,0x41,0xFC,0x00,0x00,0x00,
  32.                 //-- 码 --
  33.      0x02,0x82,0xF2,0x4E,0x43,0xE2,0x42,0xFA,0x02,0x02,0x02,0xFF,0x02,0x80,0x00,0x00,
  34.      0x01,0x00,0x7F,0x20,0x20,0x7F,0x08,0x09,0x09,0x09,0x0D,0x49,0x81,0x7F,0x01,0x00,
  35.                 //-- 正 --
  36.      0x00,0x02,0x02,0xC2,0x02,0x02,0x02,0xFE,0x82,0x82,0x82,0xC2,0x83,0x02,0x00,0x00,
  37.      0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x60,0x40,0x00,
  38.                 //-- 确 --
  39.      0x04,0x84,0xE4,0x9C,0x84,0xC6,0x24,0xF0,0x28,0x27,0xF4,0x2C,0x24,0xF0,0x20,0x00,
  40.      0x01,0x00,0x7F,0x20,0x20,0xBF,0x40,0x3F,0x09,0x09,0x7F,0x09,0x89,0xFF,0x00,0x00,        //半个屏
  41.     //-- 欢 --
  42.                 0x04, 0x34, 0xC4, 0x04, 0xC4, 0x3C, 0x20, 0x10, 0x0F, 0xE8, 0x08, 0x08, 0x28, 0x18, 0x00, 0x00,
  43.     0x10, 0x08, 0x06, 0x01, 0x82, 0x8C, 0x40, 0x30, 0x0C, 0x03, 0x0C, 0x10, 0x60, 0xC0, 0x40, 0x00,
  44.     //-- 迎 --
  45.                 0x40, 0x42, 0x44, 0xC8, 0x00, 0xFC, 0x04, 0x02, 0x82, 0xFC, 0x04, 0x04, 0x04, 0xFE, 0x04, 0x00,
  46.     0x00, 0x40, 0x20, 0x1F, 0x20, 0x47, 0x42, 0x41, 0x40, 0x7F, 0x40, 0x42, 0x44, 0x63, 0x20, 0x00,
  47.     //-- 光 --
  48.                 0x40, 0x40, 0x42, 0x44, 0x58, 0xC0, 0x40, 0x7F, 0x40, 0xC0, 0x50, 0x48, 0x46, 0x64, 0x40, 0x00,
  49.     0x00, 0x80, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, 0x40, 0x40, 0x70, 0x00,
  50.     //-- 临 --
  51.                 0x00, 0xFC, 0x00, 0xFF, 0x40, 0x20, 0x10, 0x0C, 0x2B, 0x48, 0xC8, 0x08, 0x08, 0x8C, 0x08, 0x00,
  52.     0x00, 0x1F, 0x00, 0xFF, 0x00, 0xFF, 0x41, 0x41, 0x41, 0x7F, 0x41, 0x41, 0x41, 0xFF, 0x01, 0x00,
  53.     //-- 密 --
  54.     0x10, 0x4C, 0x24, 0x04, 0xF4, 0x84, 0x4D, 0x56, 0x24, 0x24, 0x14, 0x84, 0x24, 0x54, 0x0C, 0x00,
  55.     0x00, 0x01, 0xFD, 0x41, 0x40, 0x41, 0x41, 0x7F, 0x41, 0x41, 0x41, 0x41, 0xFC, 0x00, 0x00, 0x00,
  56.     //-- 码 --
  57.     0x02, 0x82, 0xF2, 0x4E, 0x43, 0xE2, 0x42, 0xFA, 0x02, 0x02, 0x02, 0xFF, 0x02, 0x80, 0x00, 0x00,
  58.     0x01, 0x00, 0x7F, 0x20, 0x20, 0x7F, 0x08, 0x09, 0x09, 0x09, 0x0D, 0x49, 0x81, 0x7F, 0x01, 0x00,
  59.     //-- 错 --
  60.     0x80, 0x40, 0x70, 0xCF, 0x48, 0x48, 0x48, 0x48, 0x7F, 0x48, 0x48, 0x7F, 0xC8, 0x68, 0x40, 0x00,
  61.     0x00, 0x02, 0x02, 0x7F, 0x22, 0x12, 0x00, 0xFF, 0x49, 0x49, 0x49, 0x49, 0xFF, 0x01, 0x00, 0x00,
  62.     //-- 误 --
  63.     0x40, 0x42, 0xC4, 0x0C, 0x00, 0x40, 0x5E, 0x52, 0x52, 0xD2, 0x52, 0x52, 0x5F, 0x42, 0x00, 0x00,
  64.     0x00, 0x00, 0x7F, 0x20, 0x12, 0x82, 0x42, 0x22, 0x1A, 0x07, 0x1A, 0x22, 0x42, 0xC3, 0x42, 0x00,

  65. };
  66. //延迟函数
  67. void Delay_nms(uchar n)
  68. {
  69.         uchar a;
  70.         for (; n>0; n--)
  71.                 for (a = 0; a<100; a++);
  72. }
  73. //检查状态
  74. void LCD_Busy()
  75. {
  76.         uchar busy;
  77.         E = 0;           //RW=1,E信号下降沿锁存DB7~DB0;RW=1,E=1,DDRAM数据读到DB7~DB0
  78.         DI = 0;          //DB7~DB0为指令数据
  79.         RW = 1;
  80.         while (1)
  81.         {
  82.                 E = 1;         //DDRAM数据读到DB7~DB0
  83.                 _nop;
  84.                 _nop;
  85.                 busy = P2;//读状态标志寄存器
  86.                 _nop;
  87.                 E = 0;        //        下降沿锁存DB7~DB0
  88.                 if ((busy & 0x90) == 0)//检测BF和RST(复位重启)位,两者都为零时表示可以进行写入
  89.                         break;
  90.         }
  91. }
  92. //左屏输入指令
  93. void WRCommand_L(uchar command)
  94. {
  95.         CS1 = 1;
  96.         CS2 = 0;
  97.         LCD_Busy();        //检查状态
  98.         DI = 0;           //DB7~DB0为指令数据
  99.         _nop;
  100.         RW = 0;
  101.         _nop;
  102.         E = 1;
  103.         _nop;
  104.         P2 = command;
  105.         _nop;
  106.         E = 0;        //RW=0,E下降沿数据写到DB7~DB0
  107.         _nop;
  108. }
  109. //右屏输入指令
  110. void WRCommand_R(uchar command)
  111. {
  112.         CS1 = 0;
  113.         CS2 = 1;
  114.         LCD_Busy();
  115.         DI = 0;//指令
  116.         _nop;
  117.         RW = 0;          //写
  118.         _nop;
  119.         E = 1;
  120.         _nop;
  121.         P2 = command;
  122.         _nop;
  123.         E = 0;
  124.         _nop;
  125. }
  126. //左屏输入数据 (写一个字节的显示数据)
  127. void WRdata_L(uchar ucdata)
  128. {
  129.         CS1 = 1;
  130.         CS2 =0;
  131.         LCD_Busy();
  132.         DI = 1;           //DB7~DB0为显示数据
  133.         _nop;               
  134.         RW = 0;
  135.         _nop;
  136.         E = 1;
  137.         _nop;
  138.         P2 = ucdata;
  139.         _nop;
  140.         E = 0;
  141.         _nop;
  142. }
  143. //右屏输入数据
  144. void WRdata_R(uchar ucdata)
  145. {
  146.         CS1 =0;
  147.         CS2 = 1;
  148.         LCD_Busy();
  149.         DI =1;
  150.         _nop;
  151.         RW = 0;
  152.         _nop;
  153.         E = 1;
  154.         _nop;
  155.         P2 = ucdata;
  156.         _nop;
  157.         E = 0;
  158.         _nop;
  159. }
  160. //左屏显示
  161. //字符为16*16显示,分为两部分写入32字节。前16个字节写入第一页(16*8) 后16个字节写入第二页(16*8)
  162. void C_display_L(uchar C_Pagenum, uchar C_Tiernum, uchar C_Temp)                                //C_Pagenum:页,C_Tiernum:行char C_Temp:第几个字符
  163. {
  164.         uchar k;
  165.         C_Pagenum = PAGEADD | C_Pagenum;        //首页地址为 0xb8                       
  166.         C_Tiernum = TIERADD | C_Tiernum;          //首行地址为 0x40
  167.         WRCommand_L(C_Pagenum);          //左屏输入
  168.         WRCommand_L(C_Tiernum);
  169.         for (k = 0; k<16; k++)
  170.         {
  171.                 WRdata_L(table2[C_Temp * 32 + k]);           //左屏输入数据
  172.         };
  173.         C_Pagenum = C_Pagenum + 1;                                                        //下页
  174.         WRCommand_L(C_Pagenum);
  175.         WRCommand_L(C_Tiernum);
  176.         for (k = 0; k<16; k++)
  177.         {
  178.                 WRdata_L(table2[C_Temp * 32 + k + 16]);
  179.         }
  180. }
  181. //右屏显示
  182. void C_display_R(uchar C_Pagenum, uchar C_Tiernum, uchar C_Temp)
  183. {
  184.         uchar k;
  185.         C_Pagenum = PAGEADD | C_Pagenum;
  186.         C_Tiernum = TIERADD | C_Tiernum;
  187.         WRCommand_R(C_Pagenum);
  188.         WRCommand_R(C_Tiernum);
  189.         for (k = 0; k<16; k++)
  190.         {
  191.                 WRdata_R(table2[C_Temp * 32 + k]);
  192.         }
  193.         C_Pagenum = C_Pagenum + 1;
  194.         WRCommand_R(C_Pagenum);
  195.         WRCommand_R(C_Tiernum);
  196.         for (k = 0; k<16; k++)
  197.         {
  198.                 WRdata_R(table2[C_Temp * 32 + k + 16]);
  199.         }
  200. }
  201. //清除所有显示寄存器
  202. void CLR_DisplayRAM()
  203. {
  204.         uchar C_page, i, k;
  205.         for (i = 0; i<8; i++)
  206.         {
  207.                 C_page = PAGEADD | i;//清除起始页为0       
  208.                 WRCommand_L(C_page);  //清除起始页写入
  209.                 WRCommand_L(TIERADD);        //清除起始行地址写入
  210.                 WRCommand_R(C_page);
  211.                 WRCommand_R(TIERADD);
  212.                 for (k = 0; k<64; k++)
  213.                 {
  214.                         WRdata_L(0x00);
  215.                         WRdata_R(0x00);   //lcm的ram自动加1,只允许循环64次
  216.                 }
  217.         }
  218. }
  219. //LCD初始化
  220. void Init_LCD(void)
  221. {
  222.         CLR_DisplayRAM();//          清除所有显示寄存器
  223.         WRCommand_L(DIS_STARADD);
  224.         WRCommand_R(DIS_STARADD);//           设置显示起始列地址0xc0
  225.         WRCommand_L(0x3f);
  226.         WRCommand_R(0x3f);
  227. }
  228. //延迟函数
  229. void delay()
  230. {
  231.         uchar i;
  232.         uchar j;
  233.         for(i = 0;i < 100;i++)
  234.         {
  235.                 for(j = 200;j>0;j--);
  236.         }
  237. }
  238. //键盘扫描
  239. char keyscan()
  240. {
  241.         uchar cord_h,cord_l;
  242.         uchar key=0;
  243.         P1=0xf0;
  244.         if(P1!=0xf0)
  245.         {
  246.                 delay();  //消抖动
  247.                 if(P1!=0xf0)
  248.                 {
  249.                         cord_l=P1;
  250.                         P1=0x0f;
  251.                         cord_h=P1;
  252.                         key=cord_l|cord_h; //键值
  253.                 }
  254.         }
  255.         P1=0xf0;
  256.         return key;
  257. }
  258. //密码输入成功
  259. void Pass()
  260. {
  261.                 uchar a = 0, pagenum = 0,i =0;
  262.                 LED = 1;
  263.                 Init_LCD();                //lcd初始化

  264.                         //中文显示“密码正确”
  265.                         pagenum = 0;//从第一排开始显示
  266.                         for (a = 0; a<4; a++)
  267.                         {
  268.                                 C_display_L(pagenum, a * 16, a);
  269.                         }
  270.                        
  271.                         //中文显示“欢迎光临”
  272.                                 pagenum = 2;//从第二排开始显示
  273.                         for (a = 0; a<4; a++)
  274.                         {
  275.                                 C_display_R(pagenum, a * 16, a + 4);
  276.                         }
  277.                         while(1);
  278.         }
  279.         //按键中断(int0)
  280. void IntoPro() interrupt 0
  281. {
  282.         uchar a = 0,pagenum = 0,i = 0,key;
  283.         flog1++;  //记录按键的次数
  284.         key=keyscan();        //扫描键盘是否按下
  285.        
  286.         CLR_DisplayRAM();  //清屏
  287.        
  288.         if(key == cc[0])  //判断第一位密码是否正确,正确flog++
  289.         {
  290.         flog=flog+1;}                                        //P3_1 = 0;
  291.         if(key == cc[1])
  292.         {if(flog % 3 == 1)                                                                
  293.                 flog=flog+1;}                                        //P3_1 = 1;
  294.         if(key== cc[2])
  295.         {if(flog % 3 == 2)                                                                
  296.                 flog=flog+1;}                                        //P3_1 = 0;                                       
  297.         if(key == cc[3])
  298.         {if(flog % 3 == 0)
  299.         {                                                                               
  300.                 P3_1 = 1;Pass();        //显示密码正确信  led灯亮
  301.                 }
  302.                 }                                                                       
  303.         if(flog1 % 4 == 0)           //密码错误
  304.         {
  305.                 buzzer = 1;           //蜂鸣器响
  306.                 delay();
  307.                 buzzer = 0;

  308.                 Init_LCD();                      //lcd初始化

  309.                 pagenum = 0;//从第一排开始显示
  310.                 //显示按键错误
  311.                 for (a = 0; a<4; a++)
  312.                         {
  313.                                 C_display_L(pagenum, a * 16, a + 8);
  314.                         }
  315.         }
  316. }

  317. void main()
  318. {
  319.         LED = 0;
  320.         buzzer = 0;//蜂鸣器关闭
  321.         P1 = 0xf0;
  322.        
  323.         EA = 1;           //中断总允许
  324.         EX0 = 1;  //外部中断0
  325.         IT0 = 1;   //下降沿触发
  326.        
  327.         while(1);
  328.        
  329. }
复制代码


所有资料51hei提供下载:
实验七.rar (99.17 KB, 下载次数: 32)


评分

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

查看全部评分

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

使用道具 举报

沙发
1138287461 发表于 2018-12-17 09:53 | 只看该作者
原理图能不能弄完整的
回复

使用道具 举报

无效楼层,该帖已经被删除
地板
Sunny丶炆 发表于 2019-1-9 18:46 | 只看该作者
对啊,求完整的图
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51黑电子论坛单片机.

Powered by 单片机教程网

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