单片机密码锁实验报告.docx
- 文档编号:28535622
- 上传时间:2023-07-18
- 格式:DOCX
- 页数:18
- 大小:155.76KB
单片机密码锁实验报告.docx
《单片机密码锁实验报告.docx》由会员分享,可在线阅读,更多相关《单片机密码锁实验报告.docx(18页珍藏版)》请在冰豆网上搜索。
单片机密码锁实验报告
内蒙古电子信息技术学院
单片机系统
设计实训报告
专业:
生产过程自动化
姓名:
李某
班级学号:
。
。
。
。
。
。
。
。
。
。
。
指导教师:
。
。
。
。
。
。
。
。
实训期间:
。
。
。
。
。
。
。
。
。
。
。
。
。
。
一.实验目的:
1.熟悉单片机定时器的编程方法。
2.灵活运用单片机C语言程序中的字符串、数组、指针。
3.熟悉数码显示、LCM1602液晶显示器、YJD12864液晶显示器的编程方法。
4.熟悉掌握4x4矩阵键盘的C语言编程。
二.实验要求:
1:
用4×4矩阵键盘组成0-f数字键及。
2:
可以自行设定或删除8位密码,
3:
用8位数码管组成显示电路提示信息,当输入密码时,只显示“8.”,当密码位数输入完毕按下确认键时,对输入的密码与设定的密码进行比较,若密码正确,则显示PASS,若密码显示错误时,显示ERR.
4:
自由发挥其他功能.
5:
要求有单片机硬件系统框图,电路原理图,软件流程图。
3.实验基本原理:
这个密码锁的功能是使用矩阵键盘中的十六个键输入密码0到F还有,输入的同时在八位数码管上显示用户所输入的密码,未输入的位置用横杆填补表述未输入。
当输入的密码超出设置的位数时,数据溢出,清零。
用8位数码管组成显示电路提示信息,当输入密码时,只显示“8.”,当密码位数输入完毕按下确认键时,对输入的密码与设定的密码进行比较,若密码正确,则显示pass,若密码不正确,则显示err;模拟密码锁,密码固化到ROM不能通过按键输入更改。
四.实验设计分析:
1.设计思想:
1.本系统采用单片机AT89S51作为核心元件的一款具有本机开锁,加锁,修改密码和错误2.报警的电子密码锁。
3.电子密码锁的原理是:
从键盘输入一组密码,CPU把该密码和设置密码比较,对则将锁打开,错则要求重新输入,并记录错误次数,如果三次错误,则被强制锁定并报警。
初步设计思路如下:
1.输入密码用矩形键盘,数字键,字母键。
2.LED数码管显示输入密码,但是只是输出显示符号8。
采用动态扫描输出。
3.输入密码错误时显示ERR,密码正确时显示PASS。
软件的设计主要包括矩形键盘键值的读取、LED动态扫描输出程序、密码判断程序。
电子密码锁工作的主要过程是LED数码管显示密码啊。
通过键盘输入密码,按下确认键后判断密码的正确性,正确显示PASS,错误显示ERR。
程序将分为主程序和中断服务子程序。
主程序负责键盘键值读取,密码判断和开锁,中断服务子程序主要是负责LED数码管显示。
根据程序功能,程序主要分为以下几部分:
1.键盘键值读取程序
键盘键值读取程序包括键盘扫描、消除抖动、键译码等内容。
按键的识别主要有两种方法:
行反转法和行扫描法。
因为键盘为机械开关,容易引入抖动。
为了消除抖动干扰,在程序中要加入消除抖动的部分。
2)LED数码显示程序
LED数码显示器是一种应用很普遍的显示器。
程序主要负责把要显示的数字或字母对应的显示码送到相应的LED显示管。
有多位需要同时显示时,可以采用动态刷新的方法,就可以得到稳定的输出。
循环显示8个数码管,可以实现稳定的数字显示。
中断服务程序只负责数据的输出显示,主程序根据所处的状态修正显示数据。
3)密码判断程序
密码判断程序放在主程序中,有按键时读取,当确定键按下时作出判断。
在程序中设置6字节的空间存放设定的密码和8字节存放键盘输入的数据。
根据读取的键盘数据和预先设定的密码逐位比较就可以判断输入密码的正确性。
2.密码显示与开锁
当密码输出时候,显示屏上逐步显示密码,逐一显示。
4.密码错误报警
当用户键入正确密码并按下“确认”键时,屏幕清零会显示PASS。
当用户键入错误密码按下“确认”时,屏幕清零会显示ERR。
5.实验要求实现:
1.电路设计:
2.主流程图:
3.4x4键盘行列式键盘原理电路图:
每一条水平(行线)与垂直线(列线)的交叉处不相通,而是通过一个按键来连通,利用这种行列式矩阵结构只需要N条行线和M条列线,即可组成具有N×M个按键的键盘。
本设计发射部分采用4x4键盘,接收部分采用4x4键盘。
键盘扫描时,首先由I/O口低四位输出高电平,高四位输出低电平,假若有键按下,那么在I/O口低四位即可读出低电平,接着延时消抖,再具体判断是何键按下。
4.显示模块
5.总电路设计如下
6.程序
#include
#defineDataPortP0//定义数据端口程序中遇到DataPort则用P0替换
#defineKeyPortP1
sbitLATCH1=P2^2;//定义锁存使能端口段锁存
sbitLATCH2=P2^3;//位锁存
unsignedcharcodedofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};//显示段码值0~F
unsignedcharcodedofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
unsignedcharTempData[8];//存储显示值的全局变量
unsignedcharcodepassword[8]={1,2,3,4,5,6,7,8};
//可以更改此密码做多组测试
voidDelayUs2x(unsignedchart);//us级延时函数声明
voidDelayMs(unsignedchart);//ms级延时
voidDisplay(unsignedcharFirstBit,unsignedcharNum);//数码管显示函数
unsignedcharKeyScan(void);//键盘扫描
unsignedcharKeyPro(void);
voidInit_Timer0(void);//定时器初始化
/*------------------------------------------------
主函数
------------------------------------------------*/
voidmain(void)
{
unsignedcharnum,i,j;
unsignedchartemp[8];
bitFlag;
Init_Timer0();
while
(1)//主循环
{
num=KeyPro();
if(num!
=0xff)
{
if(i==0)
{
for(j=0;j<8;j++)//清屏
TempData[j]=0;
}
if(i<8)
{
temp[i]=dofly_DuanMa[num];//把按键值输入到临时数组中
for(j=0;j<=i;j++)//通过一定顺序把临时数组中
//的值赋值到显示缓冲区,从右往左输入
TempData[7-i+j]=temp[j];
}
i++;//输入数值累加
if(i==9)//正常等于8即可,由于我们需要空一个用于清屏,
//清屏时的按键不做输入值
{
i=0;
Flag=1;//先把比较位置1
for(j=0;j<8;j++)//循环比较8个数值,
//如果有一个不等则最终Flag值为0
Flag=Flag&&(temp[j]==dofly_DuanMa[password[j]]);
//比较输入值和已有密码
for(j=0;j<8;j++)//清屏
TempData[j]=0;
if(Flag)//如果比较全部相同,标志位置1
{
TempData[0]=0x3f;//"o"
TempData[1]=0x73;//"p"
TempData[2]=0x79;//"E"
TempData[3]=0x54;//"n"
//说明密码正确,输入对应操作显示"open"
}
else
{
TempData[0]=0x79;//"E"
TempData[1]=0x50;//"r"
TempData[2]=0x50;//"r"
//否则显示"Err"
}
}
}
}
}
/*------------------------------------------------
uS延时函数,含有输入参数unsignedchart,无返回值
unsignedchar是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下T=tx2+5uS
------------------------------------------------*/
voidDelayUs2x(unsignedchart)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数unsignedchart,无返回值
unsignedchar是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
voidDelayMs(unsignedchart)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
显示函数,用于动态扫描数码管
输入参数FirstBit表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
如输入0表示从第一个显示。
Num表示需要显示的位数,如需要显示99两位数值则该值输入2
------------------------------------------------*/
voidDisplay(unsignedcharFirstBit,unsignedcharNum)
{
staticunsignedchari=0;
DataPort=0;//清空数据,防止有交替重影
LATCH1=1;//段锁存
LATCH1=0;
keyPort=dofly_WeiMa[i+FirstBit];//取位码
LATCH2=1;//位锁存
LATCH2=0;
DataPort=TempData[i];//取显示数据,段码
LATCH1=1;//段锁存
LATCH1=0;
i++;
if(i==Num)
i=0;
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
voidInit_Timer0(void)
{
TMOD|=0x01;//使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
//TH0=0x00;//给定初值
//TL0=0x00;
EA=1;//总中断打开
ET0=1;//定时器中断打开
TR0=1;//定时器开关打开
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
voidTimer0_isr(void)interrupt1
{
TH0=(65536-2000)/256;//重新赋值2ms
TL0=(65536-2000)%256;
Display(0,8);//调用数码管扫描
}
/*------------------------------------------------
按键扫描函数,返回扫描键值
------------------------------------------------*/
unsignedcharKeyScan(void)//键盘扫描函数,使用行列反转扫描法
{
unsignedcharcord_h,cord_l;//行列值中间变量
KeyPort=0x0f;//行线输出全为0
cord_h=KeyPort&0x0f;//读入列线值
if(cord_h!
=0x0f)//先检测有无按键按下
{
DelayMs(10);//去抖
if((KeyPort&0x0f)!
=0x0f)
{
cord_h=KeyPort&0x0f;//读入列线值
KeyPort=cord_h|0xf0;//输出当前列线值
cord_l=KeyPort&0xf0;//读入行线值
while((KeyPort&0xf0)!
=0xf0);//等待松开并输出
return(cord_h+cord_l);//键盘最后组合码值
}
}return(0xff);//返回该值
}
/*------------------------------------------------
按键值处理函数,返回扫键值
------------------------------------------------*/
unsignedcharKeyPro(void)
{
switch(KeyScan())
{
case0x7e:
return0;break;//0按下相应的键显示相对应的码值
case0x7d:
return1;break;//1
case0x7b:
return2;break;//2
case0x77:
return3;break;//3
case0xbe:
return4;break;//4
case0xbd:
return5;break;//5
case0xbb:
return6;break;//6
case0xb7:
return7;break;//7
case0xde:
return8;break;//8
case0xdd:
return9;break;//9
case0xdb:
return10;break;//a
case0xd7:
return11;break;//b
case0xee:
return12;break;//c
case0xed:
return13;break;//d
case0xeb:
return14;break;//e
case0xe7:
return15;break;//f
default:
return0xff;break;
}
}
七.实验心得
在科技高度发展的今天,计算机在人们之中的作用越来越突出。
而c语言作为一种计算机的语言,我们学习它,有助于我们更好的了解计算机,与计算机进行交流,因此,c语言的学习对我们尤其重要。
上机实验是学习程序设计语言必不可少的实践环节,特别是c语言灵活、简洁,更需要通过编程的实践来真正掌握它。
对于程序设计语言的学习目的,可以概括为学习语法规定、掌握程序设计方法、提高程序开发能力,这些都必须通过充分的实际上机操作才能完成。
学习c程序设计语言除了课堂讲授以外,必须保证有不少于课堂讲授学时的上机时间。
因为学时所限,课程不能安排过多的统一上机实验,所以希望学生有效地利用课程上机实验的机会,尽快掌握用c语言开发程序的能力,为今后的继续学习打下一个良好的基础。
课程上机实验的目的,不仅仅是验证教材和讲课的内容、检查自己所编的程序是否正确,课程安排的上机实验的目的可以概括为如下几个方面:
1.加深对课堂讲授内容的理解
课堂上要讲授许多关于c语言的语法规则,听起来十分枯燥无味,也不容易记住,死记硬背是不可取的。
然而要使用c语言这个工具解决实际问题,又必须掌握它。
通过多次上机练习,对于语法知识有了感性的认识,加深对它的理解,在理解的基础上就会自然而然地掌握c语言的语法规定。
对于一些内容自己认为在课堂上听懂了,但上机实践中会发现原来理解的偏差,这是由于大部分学生是初次接触程序设计,缺乏程序设计的实践所致。
学习c语言不能停留在学习它的语法规则,而是利用学到的知识编写c语言程序,解决实际问题。
即把c语言作为工具,描述解决实际问题的步骤,由计算机帮助我们解题。
只有通过上机才能检验自己是否掌握c语言、自己编写的程序是否能够正确地解题。
通过上机实验来验证自己编制的程序是否正确,恐怕是大多数同学在完成老师作业时的心态。
但是在程序设计领域里这是一定要克服的传统的、错误的想法。
因为在这种思想支配下,可能你会想办法去"掩盖"程序中的错误,而不是尽可能多地发现程序中存在的问题。
自己编好程序上机调试运行时,可能有很多你想不到的情况发生,通过解决这些问题,可以逐步提高自己对c语言的理解和程序开发能力。
2.熟悉程序开发环境、学习计算机系统的操作方法
一个c语言程序从编辑、编译、连接到运行,都要在一定的外部操作环境下才能进行。
所谓"环境"就是所用的计算机系统硬件、软件条件,只有学会使用这些环境,才能进行程序开发工作。
通过上机实验,熟练地掌握c语言开发环境,为以后真正编写计算机程序解决实际问题打下基础。
同时,在今后遇到其它开发环境时就会触类旁通,很快掌握新系统的使用。
3.学习上机调试程序
完成程序的编写,决不意味着万事大吉。
你认为万无一失的程序,实际上机运行时可能不断出现麻烦。
如编译程序检测出一大堆错误。
有时程序本身不存在语法错误,也能够顺利运行,但是运行结果显然是错误的。
开发环境所提供的编译系统无法发现这种程序逻辑错误,只能靠自己的上机经验分析判断错误所在。
程序的调试是一个技巧性很强的工作,对于初学者来说,尽快掌握程序调试方法是非常重要的。
有时候一个消耗你几个小时时间的小小错误,调试高手一眼就看出错误所在。
通过这次为数不多的计算机实践学习,了解一些关于c语言的知识,理解巩固c语言的理论知识,对我们将来到社会工作将会有莫大的帮助。
同时它让我知道,只要你努力,任何东西都不会太难。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 密码锁 实验 报告