基于单片机的键盘系统.docx
- 文档编号:29706109
- 上传时间:2023-07-26
- 格式:DOCX
- 页数:19
- 大小:155.79KB
基于单片机的键盘系统.docx
《基于单片机的键盘系统.docx》由会员分享,可在线阅读,更多相关《基于单片机的键盘系统.docx(19页珍藏版)》请在冰豆网上搜索。
基于单片机的键盘系统
一设计任务:
液晶显示控制系统
任务要求:
1.可显示键盘输入数字。
2.可实现编辑操作。
二总体方案设计
1.硬件设计
1.14*4行列式键盘
系统所用键盘为4x4行列式扫描键盘,由P1口实现,A1到A8分别接P1.0到P1.7。
如下图(具体接线由硬件电路图提供):
1.2LCD显示原理
字符型型液晶是一种用5×7点阵图形来显示字符的液晶显示器,根据显示的容量可以分为1行16个字、2行16个字、2行20个字等,最常用的为2行16个字。
LCD1602就是这样。
LCD1602的驱动控制器为HD44780及其兼容集成电路。
HD44780内置了DDRAM、CGRAM和CGRAM。
如下图:
LCD1602模块的各引脚功能如下图所示:
1.3单片机采用89C52。
2软件设计
本次课程设计实现了一个以AT89C52单片机为核心控制元件,与键盘、LCD显示器等模块组成核心主控制模块,通过按键,实现用户按键显示到LCD1602液晶显示器上的简易4*4键盘LCD显示器。
主程序流程图如图:
。
三硬件电路设计
键盘A1~A8接单片机p1.0~p1.7p1口全为输入端
p0口p0.0~p0.7接显示器D0~D7为输出口
p0作为输出口是,锁存器cp端一写入脉冲,与内部总线相连的D端数据取反后出现在/Q端,又经T2反相,在p0引脚上的数据正好是内部总线上的数据。
四程序设计
/*s1,s2,s3,s4分别是123+
s5,s6,s7,s8分别是456-
s9,s10,s11,s12分别是789*
s13,s14,s15,s16分别是0,清除,=,/*/
/*实现两个数的运算,每个数的位数至少可以八位*/
#include
typedefunsignedcharuint8;
typedefunsignedintuint16;
sbitrw=P2^5;
sbitrs=P2^6;
sbite=P2^7;
sbitled=P3^7;
sbitbeep=P2^0;
uint8key,num;
uint8fuhao;//定义具体的那个符号,是加减还是乘除。
uint8flag;//定义有没有按下符号键,这个是统称
longa,b,c,d;//定义运算数据的第一个和第二个及等于的数变量
uint8k;//定义小数点后面显示的位数
uint8biao;
uint8dat1[]={1,2,3,0x2b-0x30,4,5,6,0x2d-0x30,7,8,9,0x2a-0x30,0,0x01-0x30,0x3d-0x30,0x2b-0x30};//保存显示的数据
voiddelay(uint16i)
{
while(i--);
}
voidlcdwrc(uint8c)
{
delay(1000);
rs=0;
rw=0;
e=0;
P0=c;
e=1;
delay(1000);
e=0;
}
voidlcdwrd(uint8dat)
{
delay(1000);
rs=1;
rw=0;
e=0;
P0=dat;
e=1;
delay(1000);
e=0;
rs=0;
}
voidlcdinit()
{
delay(1500);
lcdwrc(0x38);
delay(500);
lcdwrc(0x38);
delay(500);
lcdwrc(0x38);
delay(500);
lcdwrc(0x38);
lcdwrc(0x08);
lcdwrc(0x01);
lcdwrc(0x06);
lcdwrc(0x0c);
key=0;
num=0;
flag=0;
fuhao=0;
a=0;
b=0;
c=0;
d=0;
biao=0;
led=0;
}
voidkeyscan()
{
P1=0xfe;//令第一行为0,然后判断是哪一列按下
if(P1!
=0xfe)
{
delay(1000);
if(P1!
=0xfe)
{
key=P1&0xf0;
switch(key)
{
case0xe0:
num=0;break;//1
case0xd0:
num=1;break;//2
case0xb0:
num=2;break;//3
case0x70:
num=3;break;//加
}
}
while(P1!
=0xfe);
if(num==0||num==1||num==2)//确认第一行的数1,2,3
{
if(flag==0)//没有按下符号键
{
//led=1;
a=a*10+dat1[num];
}
else
{
//led=1;
b=b*10+dat1[num];
}
}
if(num==3)
{
//led=0;
flag=1;
fuhao=1;//加号+
}
lcdwrd(0x30+dat1[num]);
}
P1=0xfd;//令第二行为0,判断是哪一列按下
if(P1!
=0xfd)
{
delay(1000);
if(P1!
=0xfd)
{
key=P1&0xf0;
switch(key)
{
case0xe0:
num=4;break;//4
case0xd0:
num=5;break;//5
case0xb0:
num=6;break;//6
case0x70:
num=7;break;//减—
}
}
while(P1!
=0xfd);
if(num==4||num==5||num==6)
{
if(flag==0)//没有按下符号键
{
//led=1;
a=a*10+dat1[num];
}
else
{
//led=1;
b=b*10+dat1[num];
}
}
else
{
flag=1;
fuhao=2;//带表减号
}
lcdwrd(0x30+dat1[num]);
}
P1=0xfb;//令第三行为0,判断哪一列按下
if(P1!
=0xfb)
{
delay(1000);
if(P1!
=0xfb)
{
key=P1&0xf0;
switch(key)
{
case0xe0:
num=8;break;//7
case0xd0:
num=9;break;//8
case0xb0:
num=10;break;//9
case0x70:
num=11;break;//乘*
}
}
while(P1!
=0xfb);
if(num==8||num==9||num==10)
{
if(flag==0)//没有按下符号键
{
led=1;
a=a*10+dat1[num];
}
else
{
led=1;
b=b*10+dat1[num];
}
}
else
{
flag=1;
fuhao=3;//带表乘号*
}
lcdwrd(0x30+dat1[num]);
}
P1=0xf7;//令第四行为0,判断哪一列按下
if(P1!
=0xf7)
{
delay(1000);
if(P1!
=0xf7)
{
key=P1&0xf0;
switch(key)
{
case0xe0:
num=12;break;//0
case0xd0:
num=13;break;//清除rst
case0xb0:
num=14;break;//等号=
case0x70:
num=15;break;//除/
}
}
while(P1!
=0xf7);
switch(num)
{
case12:
if(flag==0)//没有按下符号键
{
led=1;
a=a*10+dat1[num];
lcdwrd(0x30);
}
else
{
led=1;
b=b*10+dat1[num];
lcdwrd(0x30);
}
break;
case13:
lcdwrc(0x01);//清屏指令
a=0;
b=0;
flag=0;
fuhao=0;
break;
case15:
flag=1;
fuhao=4;
lcdwrd(0x2f);//除号/
break;
case14:
if(fuhao==1)//加
{
lcdwrc(0x4f+0x80);
lcdwrc(0x04);//设置光标左移,屏幕不移动
c=a+b;
while(c!
=0)//一位一位显示
{
lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置
c=c/10;//取前面的结果数据
}
lcdwrd(0x3d);//显示等于号=
a=0;
b=0;
flag=0;
fuhao=0;//全部清除为0
}
if(fuhao==2)//减
{
lcdwrc(0x4f+0x80);
lcdwrc(0x04);//设置光标左移,屏幕不移动
if(a>b)
c=a-b;
else
c=b-a;
while(c!
=0)//一位一位显示
{
lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置
c=c/10;//取前面的结果数据
}
if(a
lcdwrd(0x3d);//显示等于号=
a=0;
b=0;
flag=0;
fuhao=0;//全部清除为0
}
if(fuhao==3)//乘法
{
lcdwrc(0x4f+0x80);
lcdwrc(0x04);//设置光标左移,屏幕不移动
c=a*b;
while(c!
=0)//一位一位显示
{
lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置
c=c/10;//取前面的结果数据
}
lcdwrd(0x3d);//显示等于号=
a=0;
b=0;
flag=0;
fuhao=0;//全部清除为0
}
if(fuhao==3)//乘法
{
lcdwrc(0x4f+0x80);
lcdwrc(0x04);//设置光标左移,屏幕不移动
c=a*b;
while(c!
=0)//一位一位显示
{
lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置
c=c/10;//取前面的结果数据
}
lcdwrd(0x3d);//显示等于号=
a=0;
b=0;
flag=0;
fuhao=0;//全部清除为0
}
if(fuhao==4)
{
k=0;
lcdwrc(0x4f+0x80);
lcdwrc(0x04);//设置光标左移,屏幕不移动
c=(long)(((float)a/b)*1000);//强制转换为long。
while(c!
=0)//一位一位显示
{
k++;
lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置
c=c/10;//取前面的结果数据
if(k==3)
{
lcdwrd(0x2e);
k=0;
}
}
if(a/b<0)//如果a比b小的话那么除的结果最高位是0
{
lcdwrd(0x30);
}
lcdwrd(0x3d);//显示等号
a=0;
b=0;
flag=0;
fuhao=0;//全部清除为0
}
break;
}
}
}
voidmain()
{
lcdinit();
while
(1)
{
keyscan();
}
}
五调试
5.1仿真
根据4*4键盘LCD1602显示设计原理,可以按照以下步骤来完成仿真:
(1)根据要求在Proteus中选取元器件,设计电路图。
(2)编写代码,实现软件设计。
(3)使用Kiel编译程序,产生相应的Hex文件。
(4)将Hex文件装入Proteus仿真软件中,实现仿真。
5.2测试
(1)根据要求选取元器件。
(2)根据所设计电路图连接电路:
(3)编写代码,实现软件设计。
(4)使用Kiel编译程序,产生相应的Hex文件。
(5)将Hex文件装入DICE中,下载到AT89C51中,运行系统。
5.3结果分析
通过按照设计的电路图连接电路,装载、编译并运行程序,可以实现通过键盘按键对LCD1602显示器进行操作,使数字显示到LCD1602显示屏上。
六总结
这次课程设计主要通过对AT89C51的基本认识,利用4*4矩阵键盘扫描进行LCD显示,从而设计成一个与键盘、LCD等模块组成核心主控制模块,在主控模块上设有16个按键的简易4*4键盘LCD1602显示器。
由于本次设计的4*4键盘LCD1602显示键盘设计比较简单,所以没有增设键盘的消除抖动功能。
在这次课程设计过程中,不仅将以前学习到的微机原理和单片机相关知识得到了巩固和进一步的提高,而且对单片机C语言有了更好的理解和掌握,虽然过程中碰到了很多的问题,但是通过查阅相关书籍、资料,特别是老师的细心教导,不仅给了我思路上的开阔,而且使我认识到自己的不足之处,最终完成了本次课程设计。
通过这次课程设计,我也发现了自身的很多不足之处,在以后的学习过程中,我会不断的完善自我,勤动手,多思考,不断进取,为自己在专业上的深入发展构筑一个好的平台。
参考文献
[1]李群芳.单片微型计算机与接口技术.电子工业出版社,2005.1
[2]何立民.MCS-51单片机应用系统设计.北京航空航天大学出版社,2000.3
[3]戴梅鄂.微型计算机技术及应用.清华大学出版社,2008.2
[4]李建忠.单片机原理及应用.西安电子科技出版社,2008.2
[5]王守中.51单片机开发入门与典型实例.人民邮电出版社,2007.8
[6]张义和.例说8051.人民邮电出版社,2006.1
[7]刘坤.51单片机C语言应用开发技术大全.人民邮电出版社,2008.9
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 单片机 键盘 系统