基于AT89S52单片机的44矩阵键盘设计.doc
《基于AT89S52单片机的44矩阵键盘设计.doc》由会员分享,可在线阅读,更多相关《基于AT89S52单片机的44矩阵键盘设计.doc(19页珍藏版)》请在冰豆网上搜索。
单片机系统开发与应用工程实习报告
选题名称:
基于AT89S52单片机的4*4矩阵键盘设计
系(院):
专业:
计算机科学与技术(嵌入式方向)
班级:
姓名:
学号:
指导教师:
学年学期:
2009 ~2010学年第2学期
2010 年5 月30 日
1
1
摘要:
嵌入式系统已经在现代生活中伴演着越来越重要的角色,单片机就是一个最典型的嵌入式系统,单片机的应用也越来越广泛。
目前单片机功能正日渐完善:
单片机集成越来越多资源,内部存储资源日益丰富,用户不需要扩充资源就可以完成项目开发,不仅是开发简单,产品小巧美观,同时抗干扰能力加强,系统也更加稳定,使得它更加适合工业控制领域,具有更加广阔的市场前景;提供在线编程能力,加速了产品的开发进程,为企业产品上市赢得宝贵时间。
此外单片机具有性能高、速度快、体积小、价格低、稳定可靠、应用广泛、通用性强等突出优点。
单片机的设计目标主要是增强“控制”能力,满足实时控制(就是快速反应)的需要。
因此,掌握单片机的基础和实际应用来说意义重大。
键盘作为一种最为普通的输入工具在单片机项目应用上显得尤为重要。
关键词:
键盘;单片机;数码管;扫描
目录
1设计目的 1
2设计原理 1
2.1设计电路图 1
2.2程序流程图 1
2.3硬件说明 2
3程序设计 6
3.1按键过程分析 6
3.2源程序(C语言) 7
4程序调试 12
5仿真测试 12
6实物实现 13
总 结 14
参考文献 15
单片机系统开发与应用工程实习计报告
1设计目的
在数码管上显示每个按键的0—F.对应按键的序号如图1-1,要实现按哪个键就在数码管上显示哪个数字或字母。
图1-1键盘正面图
2设计原理
2.1设计电路图
图2-1电路原理图
如图2-1所示,把系统中单片机的p3.0-p3.7端口连接到4*4行列式键盘端口上;具体为:
P3.0-p3.3接行线,p3.4-p3.7接列线;把系统中单片机的p0.0/AD0-p0.6/AD6端口连接到共阳数码管的a-g端口,并一一对映。
p0.0/AD对应a,依次对应。
整个电路由复位电路,晶振电路,主控制块,键盘扫描模块,LED显示模块,电源电路组成。
2.2程序流程图
图2-2程序流程图
如图2-2所示,每个按键都有他的行值和列值,行值和列值的组合就是识别这个按键的编码。
矩阵的行线和列线通过两个并行接口和单片机通信。
每个案件的状态同样需要变成数字量0和1,开关的一端(列线)通过电阻接+5V,而接地时通过程序输出数字0实现的。
键盘处理程序的任务是:
确定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断开时的抖动。
在两个并行口中,一个输出扫描码,使按键逐行动态接地;另一个并行口输入按键状态,由行扫描值和回馈信号共同行成键编码而识别按键,通过软件查表,查出该键的功能。
2.3硬件说明
图2-3共阳数码管
共阳数码管就是把每个LED灯的阳极接在共同接点com,而每个LED灯的阴极分别为a,b,c,d,e,f,g,dp;通过控制LED灯的亮灭来显示数字。
数码管跟据接收到的字形码显示数字。
图2-474ls245芯片
74LS245是我们常用的芯片,用来驱动led或者其他的设备,它是8路同相三态双向总线收发器,可双向传输数据。
74LS245还具有双向三态功能,既可以输出,也可以输入数据。
当8051单片机的P0口总线负载达到或超过P0最大负载能力时,必须接入74LS245等总线驱动器。
图2-5AT89S52单片机实物图
At89s52是一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器。
使用Atmel公司高密度非易失性存储器技术制造,与工业80C51产品指令和引脚完全兼容。
片上Flash允许程序存储器在系统可编程,亦适于常规编程器。
在单芯片上,拥有灵巧的8位CPU和在系统可编程Flash,使得AT89S52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
AT89S52具有以下标准功能:
8k字节Flash,256字节RAM,32位I/O口线,看门狗定时器,2个数据指针,三个16位定时器/计数器,一个6向量2级中断结构,全双工串行口,片内晶振及时钟电路。
另外,AT89S52可降至0Hz静态逻辑操作,支持2种软件可选择节电模式。
空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。
掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。
8位微控制器8K字节在系统可编程FlashAT89S52
图2-6AT89S52单片机引脚图
P0口:
P0口是一个8位漏极开路的双向I/O口。
作为输出口,每位能驱动8个TTL逻
辑电平。
对P0端口写“1”时,引脚用作高阻抗输入。
当访问外部程序和数据存储器时,P0口也被作为低8位地址/数据复用。
在这种模式下,
P0具有内部上拉电阻。
在flash编程时,P0口也用来接收指令字节;在程序校验时,输出指令字节。
程序校验
时,需要外部上拉电阻。
P1口:
P1口是一个具有内部上拉电阻的8位双向I/O口,p1输出缓冲器能驱动4个
TTL逻辑电平。
对P1端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入
口使用。
作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。
此外,P1.0和P1.2分别作定时器/计数器2的外部计数输入(P1.0/T2)和时器/计数器2
的触发输入(P1.1/T2EX),具体如下表所示。
在flash编程和校验时,P1口接收低8位地址字节。
引脚号第二功能
P1.0T2(定时器/计数器T2的外部计数输入),时钟输出
P1.1T2EX(定时器/计数器T2的捕捉/重载触发信号和方向控制)
P1.5MOSI(在系统编程用)
P1.6MISO(在系统编程用)
P1.7SCK(在系统编程用)
P2口:
P2口是一个具有内部上拉电阻的8位双向I/O口,P2输出缓冲器能驱动4个
TTL逻辑电平。
对P2端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入
口使用。
作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。
在访问外部程序存储器或用16位地址读取外部数据存储器(例如执行MOVX@DPTR)
时,P2口送出高八位地址。
在这种应用中,P2口使用很强的内部上拉发送1。
在使用
8位地址(如MOVX@RI)访问外部数据存储器时,P2口输出P2锁存器的内容。
在flash编程和校验时,P2口也接收高8位地址字节和一些控制信号。
P3口:
P3口是一个具有内部上拉电阻的8位双向I/O口,p3输出缓冲器能驱动4个
TTL逻辑电平。
对P3端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入
口使用。
作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。
P3口亦作为AT89S52特殊功能(第二功能)使用,如下表所示。
在flash编程和校验时,P3口也接收一些控制信号。
端口引脚第二功能
P3.0RXD(串行输入口)
P3.1TXD(串行输出口)
P3.2INTO(外中断0)
P3.3INT1(外中断1)
P3.4TO(定时/计数器0)
P3.5T1(定时/计数器1)
P3.6WR(外部数据存储器写选通)
P3.7RD(外部数据存储器读选通)
此外,P3口还接收一些用于FLASH闪存编程和程序校验的控制信号。
RST——复位输入。
当振荡器工作时,RST引脚出现两个机器周期以上高电平将是单片机复位。
ALE/PROG——当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。
一般情况下,ALE仍以时钟振荡频率的1/6输出固定的脉冲信号,因此它可对外输出时钟或用于定时目的。
要注意的是:
每当访问外部数据存储器时将跳过一个ALE脉冲。
对FLASH存储器编程期间,该引脚还用于输入编程脉冲(PROG)。
如有必要,可通过对特殊功能寄存器(SFR)区中的8EH单元的D0位置位,可禁止ALE操作。
该位置位后,只有一条MOVX和MOVC指令才能将ALE激活。
此外,该引脚会被微弱拉高,单片机执行外部程序时,应设置ALE禁止位无效。
PSEN——程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当AT89C52由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲,在此期间,当访问外部数据存储器,将跳过两次PSEN信号。
EA/VPP——外部访问允许,欲使CPU仅访问外部程序存储器(地址为0000H-FFFFH),EA端必须保持低电平(接地)。
需注意的是:
如果加密位LB1被编程,复位时内部会锁存EA端状态。
如EA端为高电平(接Vcc端),CPU则执行内部程序存储器的指令。
FLASH存储器编程时,该引脚加上+12V的编程允许电源Vpp,当然这必须是该器件是使用12V编程电压Vpp。
3程序设计
3.1按键过程分析
行信号(KEY)接到高电平,当没有键按时,行线与列线(KEYSCAN)是断开的,且行线都是高电平(1111),行信号作为FPGA的输入端、列信号作为FPGA的输出端。
可以设置列线初始状态为低电平(0000)。
信号为从上到下的顺序
当有键按下时,假如是K1按下,行信号与列信号接通,这时相应的行线(KEY0)变为低电平(01111),可以肯定第一行(K1,5,9,13)有键按下。
运用扫描的原理:
1、因为只知道第一行有键按下,不知道是那个,可以设置列信号为0111,这时行信号变为(1111)(注:
假设时钟周期很短,手还没松开,即键还在按下的状态)
2、设置列信号为1011,行信号也变成(1111)
3、设置列信号为1101,行信号也变成(1111)
4、设置列信号为1110,行信号也变成(0111),这时就可以肯定是第一个键按下。
3.2源程序(C语言)
#include
unsignedcharcodetable[]={0xC0,0xF9,0xA4,0xB0,
0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,
0xC6,0xA1,0x86,0x8E};
unsignedchartemp;
unsignedcharkey;
unsignedchari,j;
voidmain(void)
{
while
(1)
{
P3=0xff;//给P3口置1
P3_4=0;//给P3.4这条线送入0
temp=P3;
temp=temp&0x0f;//屏蔽低四位
if(temp!
=0x0f)//看是否有按键按下
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);//延时,消除抖动
temp=P3;
temp=temp&0x0f;
if(temp!
=0x0f)//再次判断按键是否按下
{
temp=P3;
temp=temp&0x0f;
switch(temp)//判断与P3.4相连的哪个键按下了
{
case0x0e:
key=7;
break;
case0x0d:
key=8;
break;
case0x0b:
key=9;
break;
case0x07:
key=10;
break;
}
temp=P3;
P0=table[key];//送数到P0口显示
temp=temp&0x0f;
while(temp!
=0x0f)//松手检测,否则跳不出循环{
temp=P3;
temp=temp&0x0f;
}
}
}
P3=0xff;
P3_5=0;//读P3.5这条线
temp=P3;
temp=temp&0x0f;//屏蔽低四位
if(temp!
=0x0f)//判断P3.5这条线上是否有按键按下
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);//延时,消除抖动
temp=P3;
temp=temp&0x0f;
if(temp!
=0x0f)//判断是否真有按键
{
temp=P3;
temp=temp&0x0f;
switch(temp)//判断与P3.5相连的哪个键按下了
{
case0x0e:
key=4;
break;
case0x0d:
key=5;
break;
case0x0b:
key=6;
break;
case0x07:
key=11;
break;
}
temp=P3;
P0=table[key];//送入P0口显示
temp=temp&0x0f;
while(temp!
=0x0f)//松手检测,否则跳不出循环
{
temp=P3;
temp=temp&0x0f;
}
}
}
P3=0xff;
P3_6=0;//读P3.6这条线
temp=P3;
temp=temp&0x0f;//屏蔽的低四位
if(temp!
=0x0f)//判断是否有按键按下
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);//延时,消除抖动
temp=P3;
temp=temp&0x0f;
if(temp!
=0x0f)//判断是否真有按键按下
{
temp=P3;
temp=temp&0x0f;
switch(temp)/判断与P3.6相连的哪个键按下了
{
case0x0e:
key=1;
break;
case0x0d:
key=2;
break;
case0x0b:
key=3;
break;
case0x07:
key=12;
break;
}
temp=P3;
P0=table[key];//送入P0口显示
temp=temp&0x0f;
while(temp!
=0x0f)//松手检测,否则跳不出循环
{
temp=P3;
temp=temp&0x0f;
}
}
}
P3=0xff;
P3_7=0;//读P3.7这条线
temp=P3;
temp=temp&0x0f;//屏蔽的低四位
if(temp!
=0x0f)//判断是否有键按下
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);//延时,消除抖动
temp=P3;
temp=temp&0x0f;
if(temp!
=0x0f)//判断是否真有键按下
{
temp=P3;
temp=temp&0x0f;
switch(temp)/判断与P3.7相连的哪个键按下了
{
case0x0e:
key=0;
break;
case0x0d:
key=13;
break;
case0x0b:
key=14;
break;
case0x07:
key=15;
break;
}
temp=P3;
P0=table[key];//送入P0口显示
temp=temp&0x0f;
while(temp!
=0x0f)//松手检测,否则跳不出循环
{
temp=P3;
temp=temp&0x0f;
}
}
}
}
}
4程序调试
程序刚完成调试后发现并不能在数码管上正常显示数字和字母。
经排查发现是程序当中的字型码表不对,经上网查资料后改正,最终能正常显示数字和字母。
5仿真测试
本次课程设计在PROTEUS,keils上仿真测试通过。
仿真结果如图4-1,达到设计要求,能在数码管上正常显示0-9,a-f。
图5-1仿真结果图
6实物实现
本次课程设计做出了4*4矩阵键盘实物,并实现了预期功能,答辩完后已交给答老师
总结
本次课程