基于STC89C52的电子密码锁Word格式.docx
《基于STC89C52的电子密码锁Word格式.docx》由会员分享,可在线阅读,更多相关《基于STC89C52的电子密码锁Word格式.docx(12页珍藏版)》请在冰豆网上搜索。
三、所用芯片
STC89C52RC
在本实验中用到的是STC89C52RC单片机。
STC89C52是一种低功耗、高性能CMOS8位微控制器,具有系统可编程8K字节闪烁可编程可檫除只读存储器(FPEROM-FlashProgramableandErasableReadOnlyMemory)。
在单芯片上,拥有灵巧的8位CPU和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
STC89C52具有以下标准功能:
8K字节Flash,512字节RAM,32位I/O口线,看门狗定时器,MAX810复位电路,置4KBEEPROM,3个16位定时器/计数器,1个6向量2级中断结构,全双工串行口。
另外STC89X52可降至0Hz静态逻辑操作,支持2种软件可选择节电模式。
空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。
掉电保护方式下,RAM容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。
最高运作频率35Mhz,6T/12T可选。
四、对应的管脚
LED灯端口对应在STC89C52芯片上上是P1口;
矩阵键盘与STC89C52芯片的P3_0~P3_3直接相连;
如下图所示:
芯片STC89C52
LED电路
4*4键盘矩阵
五、键盘矩阵扫描
确定矩阵式键盘上何键被按下的方法有高低电平翻转法和线反转法(或者称为行列翻转法)。
高低电平翻转法:
首先让P1口高四位为1,低四位为0,。
若有按键按下,则高四位中会有一个1翻转为0,低四位不会变,此时即可确定被按下的键的行位置。
然后让P1口高四位为0,低四位为1,。
若有按键按下,则低四位中会有一个1翻转为0,高四位不会变,此时即可确定被按下的键的列位置。
线反转法(或者称为行列翻转法):
首先,让单片机的行全部输出0,列全部输出1,读取列的值(假设行接P3口的高四位,列接低四位)。
即P3=0x0f;
此时读列的值,如果有键按下,则相应的列读回来的值应该为低。
譬如此时读回来的值为0x0e;
即按键列的位置已经确定。
这时反过来,把行作为输入,列作为输出,即P0=0xf0;
知道了一个按键被按下的行和列的位置,那么就可以肯定确定它的位置了。
我们把读回来的行值和列值进行或运算。
即0xe0|0x0e即0xee。
那么0xee就是我们按下的按键的键值了。
本试验中应用的是行列反转法。
六、电路原理图
密码锁开锁电路原理图
七、流程图
八、下载图
九、程序代码
#include<
reg52.h>
#defineSCANPORTP3
UnsignedcharKey[4][4]=
{0x00,0x01,0x02,0x03,0x10,0x11,0x12,0x13,0x20,0x21,0x22,0x23,0x30,0x31,0x32,0x33};
//所用键盘位置
unsignedintlock_num=456;
//初始密码
unsignedintinput_num=0;
//输入数字
unsignedcharsig_num=0;
//支持的输入次数
unsignedcharlock=0;
//密码输入错误次数
sbitP1_0=P1^0;
sbitP1_1=P1^1;
sbitP1_2=P1^2;
sbitP1_5=P1^5;
sbitP1_6=P1^6;
sbitP1_7=P1^7;
//各个灯所对应的管脚
voiddelay(unsignedintz)
{
unsignedintx,y;
for(x=z;
x>
0;
x--)
for(y=110;
y>
y--);
//延时子程序
}
voidmain()
unsignedcharrow=0;
unsignedcharline=0;
unsignedcharstate=0;
unsignedcharWhichKey=0x44;
//(放在程序中间是错误的)
P1=0xff;
//灯全灭
while
(1)
{
SCANPORT=0x0F;
state=SCANPORT&
0x0F;
if(state!
=0x0F)
{
delay(5);
state=SCANPORT&
}
switch(sig_num)
{
case0:
sig_num=1;
P1_0=0;
break;
//按下第一个数字,第一个灯亮
case1:
sig_num=2;
P1_1=0;
//按下第二个数字,第二个灯亮
case2:
sig_num=0;
P1_2=0;
//按下第三个数字,第三个灯亮
}
switch(state)
case0x0E:
line=0;
case0x0D:
line=1;
case0x0B:
line=2;
case0x07:
line=3;
default:
line=5;
//行扫描
SCANPORT=0xFF;
SCANPORT=0xF0;
0xF0;
case0xE0:
row=0;
case0xD0:
row=1;
case0xB0:
row=2;
case0x70:
row=3;
row=5;
//列扫描
WhichKey=Key[line][row];
if(WhichKey==0x33)
if(lock_num==input_num)
{
P1_7=0;
input_num=0;
//输入密码和原始密码
匹配时,第八个灯亮
}
else
lock+=1;
P1=0xff;
P1_6=0;
不匹配时,第七个灯亮
if(lock==3)
P1_5=0;
//当三次输入密码错误时,
第六个灯亮
if(WhichKey==0x23)
input_num=0;
switch(WhichKey)
case0x31:
input_num=
input_num*10+0;
//键盘的'
0'
case0x00:
input_num*10+1;
1'
case0x01:
input_num*10+2;
2'
case0x02:
input_num*10+3;
3'
case0x10:
input_num*10+4;
4'
case0x11:
input_num*10+5;
5'
case0x12:
input_num*10+6;
6'
case0x20:
input_num*10+7;
7'
case0x21:
input_num*10+8;
8'
case0x22:
input_num*10+9;
9'
delay(200);
//延时
}
while(lock==3);
//连续三次输入错误时键盘锁闭
十、心得体会
通过本次单片机的课程设计我对所学知识有了更加深刻的认识,对单片机及C语言有了更加深入的理解,在课程设计过程中,我遇到了很多困难,无论是程序设计方面的,还是调试下载方面的问题,但通过不断的尝试和老师的指导,这些问题终于一一得到解决。
同时也了解了在程序编写的时候容易出现的问题。
在程序编写开始时分不清那个管脚与那个管脚相连,但通过学习单片机原理图,渐渐明白了各个管脚并不是独立存在的,而是各个模块与单片机管脚相连。
通过一些简单程序的试验,使我明白了各个模块的使用方法及程序的编写。
虽然困难重重,但结果是喜人的,当我看到自己的设计结果时,心的喜悦和成就感是无以名状的。
通过课程设计全方位的培养和考察我们解决问题和处理是基于理论关系的能力,在设计编程到最后实现功能的过程中,我们必须经过思考。
我们必须在短期锻炼迅速掌握一门语言的能力,并学会利用其他的资料与书籍。
这次课程设计让我学到的不只是更多相关的知识,还让我了解到了努力、坚持的重要性。
也许在坚持一点点成功就是属于你的。
同时也让我了解到同学间团结协作,互帮互助的作用,或许是一个不经意的提点就会让你收益匪浅。
由此可见,课程设计的意义是十分重大和深远的。
不仅丰富了我们的知识锻炼了我们的动手能力,还给以我们生活的提点,展示自己的平台。
今后,我会更加努力学习更多专业知识,不断提高自己的专业素质,把自己的综合水平提升一个高度,争取不断做出新而实用的设计。