1、1目 录一、目 的2二、描述和要求2三、硬件选择2四、硬件电路图5五、程序设计5六、总 结7七、参考书目8附录:程序代码92一、目的随着社会物质财富的日益增长和人们生活水平的提高,安全成为现代居民最关心的问题之一。而创自古以来就是把守门户的铁将军,人们对它要求甚高。即要安全可靠地防盗,又要使用方便,这也是制锁者长期以来研制的主题。传统的门既要备有大量的钥匙。又要担心钥匙丢失后的麻烦。另外,如:宾馆、办公大楼、仓库、保险柜等由于人员的变动,开锁的钥匙也不再是只有一人拥有。购得新居的家庭。由于装修施工等人住时也要把原有的锁胆更换,况且钥匙随身携带也诸多不便。随着单片机的问世,出现了带微处理器的电子
2、密码锁,它的出现解决了传统锁的许多缺点,使密码锁具有很高的安全性、可靠性。目前已经大量地应用于日常生活之中。希望通过本课设完成具有一定实用性的电子密码锁,从而培养对单片机学习的兴趣,巩固 PIC 单片机的知识内容,提高实践动手能力。二、描述和要求1、密码正确则电机转动。2、密码错误则需重新输入,若连续三次输入错误则报警声响起,键盘被锁。3、按错键时可按“删除”键删除输入键值。4、按下一个键时响一声,说明按键按下。三、硬件选择1、单片机 PIC16F887本系统设计的核心控制芯片为 PIC16F887。它是一款采用纳瓦技术的 40引脚 8 位 CMOS 增强型闪存单片机。PIC16F887 具有
3、 8K 字程序存储器,368 字节用户可用数据存储器和 256字节 EEPROM。具有 36 个 I/0 口,14 个 A/D 通道,1 个 CCP,1 个增强型CCP,1 个增强型通用同步/异步收发器,1 个主控同步串行端口,2 个比较器,2 个 8 位计数器/定时器,1 个 16 位计数器/定时器。PIC16F887 引脚图如下:3本系统用到的引脚主要有:引脚 1:RE3/MCLR/Vpp,系统复位端。接操作按键 K1。引脚 11、32:Vdd,系统电源端。引脚 12、31:Vss,系统接地端。引脚 13、14:RA7/OSC1/CLKIN、RA6/OSC2/CLKOUT,接 4MHz 的
4、晶振,为系统的时钟源。引脚 33:RB0/AN12/INT,为外部中断输入端。接操作按键 K2。引脚 34:RB1/AN10/C12IN3,设为输入口,接操作按键 K3。引脚 35:RB2/AN8,设为输入口,接操作按键 K4。引脚 1923:RD0RD3,设为输出口,接 LCD1602 的数据输入端高四位。引脚 27:RD4,设为输出口,接 LCD1602 的 RS 数据/命令选择端。引脚 28:RD5/P1B,设为输出口,接 LCD1602 的 RW 读写选择端。引脚 29:RD6/P1C,设为输出口,接 LCD1602 的 E 使能端。引脚 16:RC1/T1OSI/CCP2,设为输出口
5、,接微型直流电机。引脚 17:RC2/P1A/CCP1,设为输出口,接蜂鸣器。2、 点阵型 LCD YB1602A4采用 4 位数据线接线方式,是为节省单片机的 I/O 口用到的引脚有:引脚 1:GND,接地引脚 2;VCCB,电源正极引脚 3:VO,液晶显示偏压信号口 引脚 4:RS,命令/数据选择,接单片机 RD4 口引脚 5:R/W,读/写选择,接单片机 RD5 口引脚 6:E,数据使能,接单片机 RD6 口引脚 1114:DB4DB7,数据输入口,接单片机 RD0RD3 口3、 4x4 按键4 行(RB0RB3)作为输入状态,低 4 位有弱上拉使能并允许电平变化中断54 列(RB4RB
6、7)作为输入状态,输出低电平4、 微型直流电机(5V 供电) 5、 蜂鸣器四、硬件电路图五、程序设计1模块介绍该电子密码锁系统的软件设计分为以下几个模块:(1)主程序模块主程序主要完成初始化、设置中断向量、检查有无按键按下、以及调用显示等等。主程序的流程图如下所示。(2)键盘扫描及识别子程序键盘采用查询的方式,放在主程序中,当没有按键按下的时候,单片机循环主程序,一旦有按键按下,便转向相应的子程序处理,处理结束再返回。(3)显示子程序由于是分屏显示数据,所以就要用到 4 个显示子程序,分别是:LCD 初始化设定 void lcdcsh(void);写入指令数据到 LCD void xie_ml
7、(unsigned char ml);6写入字符显示数据到 LCD void xie_sj(unsigned char sj);写入字符串到 LCD void xie_zfc(unsigned char *pp,unsigned int n);LCD 字符清除子程序 void qingchu(void)/;(4)密码比较子程序输入密码与正确密码的比较 int bijiao(void);(5)声响子程序通过改变蜂鸣器接口电平高低发声,包括 2 个声响子程序警报声 void jingbao (void);按键声 void anjiansheng (void);(6)延时子程序通过软件程序进行延时
8、void delay(unsigned int);2、程序流程图:7开 始初始化按键扫描有键按下?防抖动延时识别按键按下“ E”键则确认电机转动按下“C”键则清除比较密码 再次提示输入密码警报响起键盘锁定3 次输入错误密码错误正确YN3、程序代码:详见附录六、总结1、LCD YB1602A 的编程,主要要点为:(1)数据使能端 E 的控制,高电平变为低电平时写入;(2)4 位数据线的写入方式,要分别将高 4 位和低 4 位写入;(3)体现删除效果时,可在原数据位写入“空格” 。2、键盘扫描及识别子程序的编程,主要要点为:(1)将 RB 低 4 位设置为输入状态,注意弱上拉和电平变化中断设置。(
9、2)将 RB 高 4 位设置为输出状态,通过判断按下键时的 PORTB 值判断键值(3)要有防抖动措施,防止按键错误。83、其他程序要点:(1)注意 switch 语句的运用,包括 break 别漏。(2)标志位的设置有助于程序的判断。(3)字符串的运用中用 for 语句进行各位的比较和写入。(4)延时子程序的多处运用,如防抖、显示等。经过将近三周的 PIC 单片机课程设计,终于完成了我的电子密码锁的设计,虽然功能不算强大,譬如说无法从硬件上修改密码,电路的密码不能遗忘,一旦遗忘,就很难打开,这可以通过增加电路解决,但过于复杂,本次设计未其中;虽然如此但从心底里说,还是高兴的,毕竟这次设计把实
10、物都做了出来。通过这三周的学习,我感觉有很大的收获:首先,通过学习使自己对课本上的知识可以应用于实际,使的理论与实际相结合,加深自己对课本知识的更好理解,同时实习也段练了我个人的动手能力:能够充分利用网络去查阅资料,增加了许多课本以外的知识。能对 proteus、和 mplab-ide 等软件操作,能达到学以致用。对我们学生来说,理论与实际同样重要,这是我们以后在工作中说明自己能力的一个重要标准。在课设实践过程中,我感受到了老师对学生的负责态度,无论是在课堂还是在网咯上老师都来给我们指导,使我们少走弯路,顺利完成课设任务,感谢你们,老师!七、参考书目1李荣正、刘启中、陈学军,PIC 单片机原理
11、及应用,北京航空航天大学出版社,2006年 10 月2江和、鲍光海,PIC 单片机课程设计指导书,2010 年 6 月3 谭浩强. C 程序设计(第二版) ,清华大学出版社,19994Microchip Technology Inc. PIC16F87XA Data Sheet. DS39582B,20035长沙太阳人电子有限公司.LCD1602 使用说明书9附录:程序代码#include _CONFIG(0x20f1);#define RS RD4#define RW RD5#define E RD6#define LCD PORTDvoid lcdcsh(void);void xie_sj
12、(unsigned char sj);void xie_ml(unsigned char ml);void xie_zfc(unsigned char *pp,unsigned int n);void delay(unsigned int);void anjian(void);void qingchu(void);void jingbao (void);void anjiansheng (void);10int bijiao(void);unsigned char k,j=0,errorflag=0;unsigned char str1=“password:“,str2=“lock“,pass
13、word=“123456“,pw6;void main(void) TRISB=0x0F;/B 口高 4 位设置为输出,低 4 位设置为输入TRISC=0x00;/C 口设置为输出TRISD=0X00;/C 口设置为输出PORTB=0X0F;/B 口高 4 位设置为低电平,低 4 位设置为高电平PORTC=0x00;/C 口设置为低电平WPUB=0x0F;/B 口低 4 位设置为使能弱上拉IOCB=0x0F;/B 口低 4 位设置为允许电平变化中断ANSEL=0X00;/数字 I/O 设置ANSELH=0X00;OPTION=0X00;/选项寄存器设置xie_zfc(str1,9);/LCD
14、写入“password:“while(1)while(PORTB=0x0f)/等待键按下while(RBIF=0);delay(2);RBIF=0;/RB 中断标志位清零delay(2);anjiansheng();/按下一个键响一声anjian();/判断哪个键按下switch(k)caseC:qingchu();j-;break;/清除 LCD 前一个字符caseE:if(bijiao()=0)/如果密码比较错误errorflag+;/密码错误标志位加 1if(errorflag=3)/当密码输入错误三次xie_zfc(str2,4);/LCE 写入“lock”jingbao();/警报声
15、响起TRISB=0X00;/B 口设置为输出,键盘被锁else/当密码输入错误不足三次,允许再次输入11xie_zfc(str1,9);/LCD 写入“password:“j=0;else/如果密码比较正确PORTC=0x02;/RC2 口输出高电平,电机转动errorflag=0;/密码错误标志位清 0;break;default:pwj=k;/按键值依次输入字符串 PW 中j+;xie_sj(*);/每按一个键,LCE 写入一个“*”void xie_ml(unsigned char ml)/写入指令数据到 LCDRW=0;/选择写入E=1;/数据使能:下降沿送入有效RS=0;/选择命令d
16、elay(1);LCD=ml;/命令送入 D 口delay(1);E=0;/数据使能:写入命令void qingchu(void)/清除命令xie_ml(0x00);/写入命令:完成一个字符码传送后,光标左移,AC 自动减 1xie_ml(0x04);delay(2);xie_sj( );/在光标目前所在的位置写入空格delay(2);xie_sj( );/在需删除的字符位写入空格xie_ml(0x01);/写入命令:没有读写显示数据的情况下光标右移,AC 自动加 1xie_ml(0x04);xie_ml(0x00);/写入命令:完成一个字符码传送后,光标左右移,AC 自动加 112xie_m
17、l(0x06);void xie_sj(unsigned char sj)/写入字符显示数据到 LCDchar sj_h,sj_l;sj_h=(sj/获得数据高 4 位写入 sj_h 低 4 位sj_l=sj/获得数据低 4 位写入 sj_l 低 4 位E=1;NOP();/数据使能:下降沿送入有效RW=0;NOP();/选择写入RS=1;NOP();/选择数据delay(1);LCD/B 口低 4 位清 0,高 4 位保留LCD|=sj_h;/B 口低 4 位为 sj_h 低 4 位值,高 4 位值不变E=0;/数据使能:写入命令delay(1);E=1;/数据使能:下降沿送入有效LCD/B
18、 口低 4 位清 0,高 4 位保留LCD|=sj_l;/B 口低 4 位为 sj_l 低 4 位值,高 4 位值不变delay(1);E=0;/数据使能:写入命令void lcdcsh(void)/LCD 初始化设定char i;delay(50);for(i=0;i3;i+)/写控制命令“0b0011”3 次xie_ml(0x03);delay(10);xie_ml(0x02);/写数据格式命令“0b0010”delay(5);xie_ml(0x02);/写功能设置命令“0b00101000” ,4 位数据格式,2 行,5*7 点阵xie_ml(0x08);xie_ml(0x00);/写显
19、示控制命令“0b00001111” ,打开显示,光标闪烁xie_ml(0x0f);xie_ml(0x00);/写清除命令“0b00000001”xie_ml(0x01);13delay(10);xie_ml(0x00);/写模式命令“0b00000110” ,每显示一个字符后地址自动加 1xie_ml(0x06);void xie_zfc(unsigned char *pp,unsigned int n) /写入字符串int i;lcdcsh();/LCD 初始化xie_ml(0x08);/光标移至 LCD 第一行第一位xie_ml(0x00);for(i=0;in;i+)/逐个写入字符串xi
20、e_sj(ppi);xie_ml(0x0C);/光标移至 LCD 第二行第一位xie_ml(0x00);void anjian(void)/判断按键值unsigned int y;y=PORTB;switch(y)case(0x0e):/如果 B 口值为 0x0e,即 RB0=0 第一行按下TRISB=0xF0;/B 口高 4 位设置为输入,低 4 位设置为输出PORTB=0XF0;/B 口高 4 位设置为高电平,低 4 位设置为低电平WPUB=0xF0;/B 口高 4 位设置为使能弱上拉IOCB=0xF0;/B 口高 4 位设置为允许电平变化中断if(RB4=0)k=0;/如果 RB4 口为
21、低电平,则0键按下if(RB5=0)k=1;if(RB6=0)k=2;if(RB7=0)k=3;break;case(0x0d): TRISB=0xF0;PORTB=0XF0;WPUB=0xF0;IOCB=0xF0;14if(RB4=0)k=4;if(RB5=0)k=5;if(RB6=0)k=6;if(RB7=0)k=7;break;case(0x0b): TRISB=0xF0;PORTB=0XF0;WPUB=0xF0;IOCB=0xF0;if(RB4=0)k=8;if(RB5=0)k=9;if(RB6=0)k=A;if(RB7=0)k=B;break;case(0x07):TRISB=0xF
22、0;PORTB=0XF0;WPUB=0xF0;IOCB=0xF0;if(RB4=0)k=C;if(RB5=0)k=D;if(RB6=0)k=E;if(RB7=0)k=F;break;default:break;TRISB=0x0F;PORTB=0X0F;WPUB=0x0F;IOCB=0x0F;while(PORTB!=0x0F);/如果有按键按下则保持循环扫描int bijiao(void)/密码比较int flag=1;unsigned char h;for (h=0;h6;h+)15if (pwh!=passwordh)/如果输入值与原密码有一位不相等则密码错误flag=0;/标志位为 0 return(flag);/标志位值返回void jingbao (void)/警报声while(1)RC2=1;delay(500);RC2=0;delay(300);void anjiansheng (void)/按键声RC2=1;delay(100);RC2=0;void delay(unsigned int n) / 延时unsigned int i;char j;for(i=0;in;i+) for(j=0;j99;j+)NOP();NOP();NOP();NOP();