这样如果按键时间超过1s将会认为同一个键事件多次触发。
比如定义一个“+”键,如果一直按下不释放,那么每隔0.5s就会响应一次加动作。
键盘扫描采用128Hz时基中断,每1/128ms扫描一次键盘。
先判断是否有键按下,如果没有键按下,则认为是键抬起状态,把键抬起标志置1后返回;如果有键按下,按行扫描,先扫描第一行,如果键码为0;再扫描第二行,如果键码为0,再扫描第三行,依次扫描到第四行,如果键码为0,则认为是键抬起状态,置贱抬起标志;如果键码不为0,比较键码和上次扫描到的键码是否相同,如果不同,保存新的键值,扫描计数器置1;如果相同,扫描计数器加一,返回。
上面介绍的是键扫描程序和取键值程序流程,去扫描计算器值;根据前面的定义,如果按键小于30ms,即判断扫描计算值是否小于4,如果小于4,键值为0;如果大于4,根据前面的定义,判断按键时间是否大于0.5s,即判断扫描计算器值是否大于64,如果小于64,判断键是否抬起,没有抬起,则键值为0;抬起时保存键值,把计数器全部清零;返回键值。
图2-2设计原理图
4.菜单的选择
菜单的选择主要是通过键盘控制光标来进行选择
5.数据的采集
键盘/液晶显示器与单片机的接口电路设计。
人机对话功能,在绝大多数的单片机应用系统中是必不可少的,它起着沟通操作者与系统之间的联系的重要作用。
包括人对应用系统的状态干预与数据输入以及应用系统向人报告运行状态与运行结果。
而人机对话功能模块的最基本组成就是键盘、显示器两部分。
因此,设计一种将键盘、显示两部分融为一体的相对独立的人机对话功能模块很有必要。
对它的设计,在一定程度上影响着系统的智能化程度和操作的直观性。
本次设计采用了4×4键盘,与单片机的P0口相连,利用键盘实现对液晶屏幕显示的控制。
这16个键分别实现的功能表示为:
0-9十个数字键、返回、确认、向上、向下、左移、右移等键盘主要功能有:
1、通过方向键(向上/向下)来控制光标进行菜单选择
2、在本次设计中,方向键(左移/右移)实现的功能为调节采集速度
3、1-8这八个数据键用来确定显示八路采集波形曲线中的一路
4、返回、确定键就是实现返回与确定功能
2.3基本方案
本次设计用到的硬件有:
装有Windows系统和装有Proteus仿真环境的PC机一台,十六位单片机实验箱一个。
本设计用到的实验箱硬件模块为:
SPCE061A核心及周边电路模块,LCD1602模块,4×4键盘。
硬件电路图如下图:
图2-44*4键盘LCD1602显示硬件电路图
第三章程序设计
3.1主程序流程图
主程序流程图如图3-1,初始化LCD,调用键盘程序取键值,根据键值进入相应的程序:
如果按下的是数字键并且之前确认键没有按下进入显示BMP位图循环:
点亮整个屏幕,延时;设置为取反并覆盖的图形显示方式,即LCD501_SetPaintMode的参数ModeCode为4;显示BMP位图,BMP位图显示在(50,15)的坐标位置,延时。
循环里加延时同样是为了看清实验现象。
如果按下的是保留键或者没有按键按下,直接返回取键值;如果是确认键按下,确认键按下标志置1,之后按任何键都不起作用。
图3-1主程序流程图
数据采集流程图如图3-2所示:
图3-2数据采集
3.2程序代码
程序代码见附录
第四章调试结果及分析
按照以下步骤进行调试运行:
1.新键工程ex2_Led_Show_Key,在工程里C语言文件main.c,新键文件key.asm或者key.c。
2.拷贝头文件SPCE061A.h、MCS-51.inc到ex2_Led_Show_Key工程文件夹。
3.添加头文件SPCE061A.h、MCS-51.inc到ex2_Led_Show_Key工程。
4.根据程序流程图编写程序。
5.RebuildAll。
6.按照硬件连接图连接硬件,注意J27和JP7连接时排线的顺序,J27的0号引脚和JP7的C4连接,不要接反。
7.下载程序到实验箱,调试运行。
通过按照设计的电路图连接电路,装载、编译并运行程序,可以实现通过键盘按键对LCD1602显示器进行操作,经过对程序的调试和修改,每当按下一个数字键时,数字键对应的图片在LCD显示屏上显示。
第五章结论与体会
在这次课程设计中,我选的题目是“4×4键盘在LCD显示屏上的应用”。
在这个设计过程中,我通过对‘4×4键盘工作原理’和‘Proteus工具’的深入学习,以及对程序的反复修改和调试才使设计结果能够符合题意,成功完成了此次设计要求。
当硬件连接正确,程序调试无错误时,每按下一个键就会在LCD显示屏上显示出相应的不同的图片。
课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程.随着科学技术发展的日新日异,单片机已经成为当今计算机应用中空前活跃的领域,在生活中可以说得是无处不在。
因此作为二十一世纪的大学来说掌握单片机的开发技术是十分重要的。
回顾起此次单片机课程设计,我仍感慨颇多,的确,从选题到定稿,从理论到实践,在接近一个星期的日子里,可以说得是苦多于甜,但是可以学到很多很多的的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
通过这次的课程设计作品的制作让我对单片机的理论有了更加深入的了解,同时在具体的制作过程中我们发现现在书本上的知识与实际的应用存在着不小的差距,书本上的知识很多都是理想化后的结论,忽略了很多实际的因素,或者涉及的不全面,可在实际的应用时这些是不能被忽略的,我们不得不考虑这方的问题,这让我们无法根据书上的理论就轻易得到预想中的结果,有时结果甚至很差别很大。
通过这次实践使我更深刻的体会到了理论联系实际的重要性,我们在今后的学习工作中会更加的注重实际,避免称为只会纸上谈兵的赵括。
参考文献
[1]周润景.Proteus入门实用教程.机械工业出版社,2011
[2]王达峰.基于C51的汉字/数字混合液晶显示及更新[J],2002.12
[3]李宏.液晶显示器件应用技术[M].北京:
机械工业出版社,2004
[4]张毅刚.MCS-51单片机应用设计[M].哈尔滨工业大学出版社,2002
[5]林雪明.点阵式液晶显示系统图文界面的设计[J],2000.12
[6]参考网址
附录
程序代码:
#include"SPCE061A.h"
#include"Dig.h"
#include"Key.h"
#include"SPLC501User.h"//包含SPLC501液晶模组驱动程序的用户接口API函数声明的头文件
#include"sunplus.h"//包含凌阳标识字模数据的头文件
#defineP_Watchdog_Clear(volatileunsignedint*)0x7012
intmain(void)
{intEnt_Flag=0;
unsignedintuiKey;
unsignedintuiData[6]={1,0,0,0,0,1};
uiData[0]=0;
uiData[5]=0;
Key_Init();
DIG_Init();
inti,j;//用于延时
LCD501_Init(0xFF);//初始化LCD端口以及LCD初始化所需要的设置,在SPLC501User.c中定义
while
(1)
{uiKey=Key_Get();
switch(uiKey)
{caseKEY_0:
//数字“7”键按下
if(Ent_Flag==0)//判断“ENT”键是否按下,即确认键是否按下?
{LCD501_ClrScreen
(1);//整屏填充,即全部点亮
for(j=0;j<=3;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
LCD501_SetPaintMode(PAINT_RECO);//设置图片与背景的叠加模式为:
取反覆盖
LCD501_Bitmap(50,15,(unsignedint*)encoding_07);//显示图片
for(j=0;j<=7;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
}
break;
caseKEY_1:
//数字“8”键按下
if(Ent_Flag==0)//判断“ENT”键是否按下,即确认键是否按下?
{LCD501_ClrScreen
(1);//整屏填充,即全部点亮
for(j=0;j<=3;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
LCD501_SetPaintMode(PAINT_RECO);//设置图片与背景的叠加模式为:
取反覆盖
LCD501_Bitmap(50,15,(unsignedint*)encoding_08);//显示图片
for(j=0;j<=7;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
}
break;
caseKEY_2:
//数字“9”键按下
if(Ent_Flag==0)//判断“ENT”键是否按下,即确认键是否按下?
{LCD501_ClrScreen
(1);//整屏填充,即全部点亮
for(j=0;j<=3;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
LCD501_SetPaintMode(PAINT_RECO);//设置图片与背景的叠加模式为:
取反覆盖
LCD501_Bitmap(50,15,(unsignedint*)encoding_09);//显示图片
for(j=0;j<=7;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
}
break;
caseKEY_3:
//保留“F1”键
break;
caseKEY_4:
//数字“4”键按下
if(Ent_Flag==0)//判断“ENT”键是否按下,即确认键是否按下?
{LCD501_ClrScreen
(1);//整屏填充,即全部点亮
for(j=0;j<=3;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
LCD501_SetPaintMode(PAINT_RECO);//设置图片与背景的叠加模式为:
取反覆盖
LCD501_Bitmap(50,15,(unsignedint*)encoding_04);//显示图片
for(j=0;j<=7;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
}
break;
caseKEY_5:
//数字“5”键按下
if(Ent_Flag==0)//判断“ENT”键是否按下,即确认键是否按下?
{LCD501_ClrScreen
(1);//整屏填充,即全部点亮
for(j=0;j<=3;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗LCD501_SetPaintMode(PAINT_RECO);//设置图片与背景的叠加模式为:
取反覆盖
LCD501_Bitmap(50,15,(unsignedint*)encoding_05);//显示图片
for(j=0;j<=7;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
}break;
caseKEY_6:
//数字“6”键按下
if(Ent_Flag==0)//判断“ENT”键是否按下,即确认键是否按下?
{LCD501_ClrScreen
(1);//整屏填充,即全部点亮
for(j=0;j<=3;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
LCD501_SetPaintMode(PAINT_RECO);//设置图片与背景的叠加模式为:
取反覆盖
LCD501_Bitmap(50,15,(unsignedint*)encoding_06);//显示图片
for(j=0;j<=7;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
}
break;
caseKEY_7:
//保留“F2”键按下
break;
caseKEY_8:
//数字“1”键按下
if(Ent_Flag==0)//判断“ENT”键是否按下,即确认键是否按下?
{LCD501_ClrScreen
(1);//整屏填充,即全部点亮
for(j=0;j<=3;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
LCD501_SetPaintMode(PAINT_RECO);//设置图片与背景的叠加模式为:
取反覆盖
LCD501_Bitmap(50,15,(unsignedint*)encoding_01);//显示图片
for(j=0;j<=7;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
}
break;
caseKEY_9:
//数字“2”键按下
if(Ent_Flag==0)//判断“ENT”键是否按下,即确认键是否按下?
{LCD501_ClrScreen
(1);//整屏填充,即全部点亮
for(j=0;j<=3;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdog_Clear=0x0001;//清看门狗
LCD501_SetPaintMode(PAINT_RECO);//设置图片与背景的叠加模式为:
取反覆盖
LCD501_Bitmap(50,15,(unsignedint*)encoding_02);//显示图片
for(j=0;j<=7;j++)//延时保持当前显示
for(i=0;i<0x2fff;i++)
*P_Watchdo