计算器按键键盘报告书全.docx
《计算器按键键盘报告书全.docx》由会员分享,可在线阅读,更多相关《计算器按键键盘报告书全.docx(18页珍藏版)》请在冰豆网上搜索。
![计算器按键键盘报告书全.docx](https://file1.bdocx.com/fileroot1/2022-12/13/8688b404-c5e6-44b7-95d2-79d68430f97b/8688b404-c5e6-44b7-95d2-79d68430f97b1.gif)
计算器按键键盘报告书全
计算器键盘按键显示
设计者:
——————
设计日期:
2013年——月——日
摘要:
为了满足利用AT89C51单片机结合12864LCD显示器设计计算器4*4键盘按键的要求,我设计了利用AT89C51控制整个电路显示12864LCD显示器设计计算器键盘按键的系统。
系统主要包括硬件和软件两部分。
其中包括各模块的器件选择和电路设计。
将计算器按键上的信息传送至AT89C51主芯片之中,利用P2端口使之显示于12864LCD液晶显示屏上,包含复位、定时电路。
通过在proteus和keil仿真软件联合仿真环境下,系统达到了通过按键显示计算器键盘按键的需求,12864LCD精准的显示了按键信息,达到了目的。
关键字:
计算器键盘、液晶显示屏、按键、复位、定时
Abstract:
inordertomeettheneedsofusingAT89C51MCUwith12864LCDdisplaydesigncalculator4*4keyboardkeyrequirements,IdesigntheAT89C51controltheentirecircuitdisplaysystemof12864LCDdisplaydesigncalculatorkeypad.Thesystemmainlyincludestwoparts:
hardwareandsoftware.Includingdeviceselectionandcircuitdesignofeachmodule.TotransmittheinformationtotheAT89C51mainchipcalculatoronthebutton,thedisplayonthe12864LCDLCDscreenwithP2port,comprisingareset,thetimingcircuit.ThroughtheProteusandkeilsimulationsoftwaresimulationenvironment,thesystemachievedthroughthekeydisplaycalculatorkeyboardkeydemand,12864LCDprecisionshowsthekeyinformation,toachievetheobjective.
Keywords:
computerkeyboard,LCDdisplay,button,reset,timing
目录
一、系统方案论证与选择-1-
1.1系统基本方案比较-1-
1.2系统各模块的最终方案-2-
二、系统的硬件设计与实现-3-
2.1系统硬件的基本组成部分-3-
2.2主要单元电路的设计-3-
2.2.1时钟电路-3-
2.2.2复位电路-4-
2.2.3按键电路-5-
三、系统软件设计-5-
3.1主程序流程图-5-
3.2按键操作子函数流程图-6-
四、系统测试-7-
4.1测试仪器-7-
4.2指标测试-7-
五、总结-8-
参考文献-9-
一、系统方案论证与选择
根据题目要求,系统可以分为定时电路模块、复位电路模块、液晶显示电路模块、键盘模块、控制电路模块,控制电路是以AT89C51为主控芯片,其他电路模块都是由控制电路模块AT89C51芯片进行控制。
如图1,为系统总电路模块框图。
图1系统总框图
1.1系统基本方案论证
为实现各模块的功能,分别论证了几种不同的设计方案并进行了讨论,并且就各方案的优缺点进行了方案选择。
1.1.1液晶显示电路的选择
方案一:
选用LCD1602液晶显示器,LCD1602是字符型的模组,为16字乘2行字符型。
但只能显示数字与字符,不可以显示汉字。
不能显示出题目目的的汉字字符。
方案二:
选用LCD12864液晶显示器,12864屏幕为64行,每行显示128个字符,是点阵型显示器。
可根据需求任意显示字符、数字、汉字、图形,LCD12864是图形型的模组。
显示器控制器接口信号说明如表1所示。
表1控制器借口信号说明
RS
R/W
功能说明
L
L
MPU写指令到IR
L
H
读出BF及AC状态
H
L
MPU写数据到DR
H
H
MPU从DR读出数据
综上所述,配合我的AT89C51控制系统和液晶显示系统,我选择方案二,达到了我需要显示汉字、符号、数字的要求。
1.1.2控制电路的选择
方案一:
选用PIC、或AVR、或凌阳SPCE061A等作为控制核心;这些单片机资源丰富,可以实现复杂的逻辑功能,功能强大,完全可以实现对小车的控制。
但对于本题目而言,其优势资源无法得以体现,且成本稍高。
方案二:
采用AT89C5高速单片机来作为整机的控制单元。
AT89C51与MCS-51兼容;4K字节可编程闪烁存储器;寿命:
1000写/擦循环;数据保留时间:
10年;全静态工作:
0Hz-24MHz;三级程序存储器锁定;128×8位内部RAM;32可编程I/O线;两个16位定时器/计数器;5个中断源;可编程串行通道;低功耗的闲置和掉电模式;片内振荡器和时钟电路。
此系统比较灵活,采用软件方法来解决复杂的硬件电路部分,使系统硬件简洁化,各类功能易于实现,能很好地满足实际的需要。
综上所述,配合循迹探测系统,我们选择采用方案二,达到了用软件方法解决硬件电路系统的目的。
1.2系统各模块的最终方案
经过仔细分析和论证,决定了系统各模块的最终方案如下:
(1)液晶显示模块:
采用LCD12864为系统显示器
(2)控制模块:
采用AT89C51单片机
二、系统的硬件设计与实现
2.1系统硬件的基本组成部分
通过AT89C51芯片PO口与键盘相接,键盘中的键就是一个行列开关,该开关位于行列的交点处,通过按下某个键,该交点的行线和列线联通,相应的行列电平发生变化,从而可以确定按下的功能键。
读取P0的值就可以确定按键,再由AT89C51芯片读取按键的值通过P1口和P2口显示在LCD12864上,每显示一个按键值LS1发出声音。
接P3.7口,判断键盘是否按下,一旦键盘某个键按下,此元件会发出声音。
如图2,为系统总体电路图。
图2系统总电路图
2.2主要单元电路的设计
2.2.1时钟电路
时钟电路由AT89S51得18、19引脚的时钟端(XTL1及ATAL2)以及12MHZ晶振、47pF的电容C1、C2组成,采用片内振荡方式。
其时间周期为1/12us,机器周期为1s。
单片机的外部晶振电路如图3所示。
AT89C51中有一个用于构成内部振荡器的高增益反相放大器,引脚XTAL1和XTAL2分别是该放大器的输入端和输出端。
这个放大器与作为反馈元件的片外石英晶体或陶瓷谐振器一起构成振荡器。
振荡器特性:
XTAL1和XTAL2分别为反向放大器的输入和输出。
该反向放大器可以配置为片内振荡器。
石晶振荡和陶瓷振荡均可采用。
如采用外部时钟源驱动器件,XTAL2应不接。
有余输入至内部时钟信号要通过一个二分频触发器,因此对外部时钟信号的脉宽无任何要求,但必须保证脉冲的高低电平。
图3时钟电路图
2.2.2复位电路
复位电路采用简单的上位电路,由1K电阻及22uF电容接至AT89S52的RST复位端电阻给电容充电,电容的电压缓慢上升直到vcc,没到vcc时芯片复位脚近似低电平,于是芯片复位,接近vcc时芯片复位脚近高电平,于是芯片停止复位,复位完成。
按键后电容器被短路放电、RST直接和VCC相连,就是高电平,此时进入“复位状态”。
松手后电源开始对电容器充电,此时,充电电流在电阻上,形成高电平送到RST,仍然是“复位状态”,稍后,充电结束,电流降为0,电阻上的电压也将为0,RST降为低电平,开始正常工作。
如图4,为复位电路截图。
图4复位电路图
2.2.3按键电路
键盘电路的设计原理首先行列式键盘中的键实际上就是一个机械开关,该开关位于行线和列线的交点处,通过按键加以连接。
当按下某个键时,该交点的行线和列线接通,相应行线或列线上的的电平发生变化,从而可以确定被按下的功能键其次运用线翻转法判断有无键按下:
键盘的高4位用于列控制,低4位用于行控制,并将全部行线Y0~Y3置低电平,然后再检查列线电平的状态。
只要其中有一列电平为低,则表示右键按下,并且被按下的键位于低电平和4根行线交叉的某一个按键中。
如图5,为4*4按键电路图。
图54*4按键电路图
三、系统软件设计
3.1主程序流程图
如图6,为系统主流程图,程序开始启动显示器,单片机判断是否有按键按下,如果有进行按键扫描,否则一直进行检测直到按键按下。
图6系统主流程图
3.2按键操作子函数流程图
当按键程序启动的时候,通过扫描按键,判断有误按键按下,如果有按键按下,则进行数据处理、显示处理,否则一直判断是否有按键按下。
如图7,为按键操作流程图。
图7按键操作流程图
四、系统测试
4.1测试仪器
表2测试使用的仪器设备
序号
名称、型号、规格
数量
备注
1
UNI-T数字万用表
1
2
秒表精度0.01s
1
4.2指标测试
4.2.1硬件调试
硬件调试分为静态调试和动态调试,对于硬件调试而言,只要认真焊接,硬件一般不会出现什么问题的。
静态调试一般采用的工具是万用表,它是在用户系统未工作时的一种硬件检测。
动态调试是在用户系统工作的情况下发现和排查错误的一种硬件检测。
调试步骤是:
首先把电路分为若干模块,调试过程中与该模块无关的元件可以不加考虑,这样可把故障限定在一定的范围内;故障清除后,把各个模块合在一起进行联调,即可完成整个硬件调试工作。
4.2.2软件调试
软件调试是通过对程序的汇编、连接、执行来发现程序中存在的语法错误与逻辑错误并加以排除纠正的过程。
调试过程:
1、代码录入完成进行调试。
2、在KeiluVision3中检测查找错误。
3、检测过程中总是有一处错误无法解决。
4、最后把原程序分开逐个调试,检查每段程序的错误,修正每个代码错误。
5、这种分开调试方法的效率还是很不错的,经过几次修改就完成了程序的调试,运行结果没有错误,电路显示也完全正确。
4.2.3软硬件调试
软硬件联调是指把调试无误的软件程序烧制进单片机芯片内部,通上电源后,检查硬件工作是否有预期的效果,如果没有则需要检测软件是否在实现功能上有欠缺。
若有错误,通过改写软件来调试,直至达到预期效果,则设计圆满成功。
五、总结
有付出就会有收获。
在本次设计的过程中,遇到了许多事先未曾预料的事情和各种困难,设计制作曾几度中断,但通过查找资料、仔细分析和自我调整讨论后解决了问题。
在设计的过程中,提高了自己发现问题,分析问题,解决问题的能力。
学会了通过寻找芯片资料,弄懂、研究芯片本身来找到解决问题的最优解。
要多请教他人,不能有个人主义,有些问题在经过长时间思考后,如果还未解决的话我们就要不耻下问,攻取他人的帮助。
经过此次课程设计,简单带有LCD显示的数字的,系统基本功能基本实现,测试运行也基本正常,该系统基本上完成了日期的显示与计数的功能。
参考文献
[1]范立南,谢子殿等.单片机原理及应用教程[M].
北京大学出版社
[2]马忠梅,籍顺心,张凯等.单片机的C语言应用程序设计[M].
北京航空航天大学出版社,2006.
[3]张毅刚,彭喜元,董继成.《单片机原理及应用》
高等教育出版社,2003.
[4]谭浩强《C语言程序设计(第二版)》
清华大学出版社 1999年12月第二版 2005年1月第58次印刷
[5]王丽娟,徐军,戴宝华,荣政 《C程序设计》
西安电子科技大学出版社 2003年6月第五版 2000年8月出版
[6]彭伟《单片机C语言程序设计实训100例》
电子工业出版社2012年6月第六次印刷
附录1:
程序代码
//12864LCD显示计算器键盘按键实验源代码
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
//定义DotMatri.c中的点阵,数字,符号等编码
externucharcodeWord_String[][32];
externucharcodeKeyboard_Chars[][16];
externucharcodeKeyPosTable[];
externucharKeyScan();//keypad.c中的键盘扫描函数
//定义在LCP_12864.c中的相关液晶显示函数
externLCD_Initialize();
voidDisplay_A_Char(uchar,uchar,uchar*);
voidDisplay_A_WORD(uchar,uchar,uchar*);
voidDisplay_A_WORD_String(uchar,uchar,uchar,uchar*);
//键盘扫描开启标志,其值由外部中断0控制
bitKeyPressDown=0;
ucharT_Count=0;
sbitSPK=P3^7;
//Keybord_Chars中数字与符号编码与键盘按键对照表
ucharcodeKeyPosTable[]=
{
7,8,9,10,
4,5,6,11,
1,2,3,12,
15,0,14,13
};
//蜂鸣器发声
voidBeep()
{
uchari,x=20;
while(x--)
{
for(i=0;i<120;i++);SPK=~SPK;
}
}
//主程序
voidmain()
{
uchari;
LCD_Initialize();//初始化LCD
for(i=0;i<7;i++)//从第一页开始,左边距16点,显示7个16*16点阵的中文提示信息
Display_A_WORD_String(1,16*(i+1),1,Word_String[i]);
P1=0x0f;
IE=0x83;//允许外部0和定时器0中断
IT0=1;//设为下降沿中断方式,外部中断0用于启停键盘扫描处理
TH0=(65536-5000)/256;//50ms定时
TL0=(65536-5000)%256;
while
(1)
{
//如果有按键按下则处理按键
if(KeyPressDown==1)
{
Beep();
KeyPressDown=0;
Display_A_Char(4,55,Keyboard_Chars[KeyPosTable[KeyScan()]]);
TR0=0;
}
}
}
//外部中断0控制消抖延时
voidEX0_INT()interrupt0
{
TR0=1;//开启定时器0,延时300ms消抖
}
//定时器用于消抖并确认有键按下,启动主程序中的按键扫描
voidT0_INT()interrupt1
{
if(++T_Count==6)//50*6=300ms延时抖动
{
T_Count=0;
KeyPressDown=1;//确定有键按下
}
TH0=(65526-50000)/256;//50ms定时
TL0=(65526-50000)%256;
}
//---------------------------------------------LCD_12864.C----------------------------------------------
//名称:
12864LCD显示驱动程序(不带字库)
//---------------------------------------------------------------------------------------------------------
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineLCD_DB_PORTP0//液晶DB0~DB7
#defineLCD_START_ROW0xC0//起始行
#defineLCD_PAGE0xB8//页指令
#defineLCD_COL0x40//列指令
//液晶引脚定义
sbitDI=P2^0;
sbitRW=P2^1;
sbitE=P2^2;
sbitCS1=P2^3;
sbitCS2=P2^4;
sbitRST=P2^5;
//检查LCD是否忙
bitLCD_Check_Busy()
{
LCD_DB_PORT=0xFF;
RW=1;_nop_();DI=0;
E=1;_nop_();E=0;
return(bit)(P0&0X80);
}
//向LCD发送命令
voidLCD_Write_Command(ucharc)
{
while(LCD_Check_Busy());
LCD_DB_PORT=0xFF;RW=0;_nop_();DI=0;
LCD_DB_PORT=c;E=1;_nop_();E=0;
}
//向LCD发送数据
voidLCD_Write_Data(uchard)
{
while(LCD_Check_Busy());
LCD_DB_PORT=0xFF;RW=0;_nop_();DI=1;
LCD_DB_PORT=d;E=1;_nop_();E=0;
}
//初始化LCD
voidLCD_Initialize()
{
CS1=1;CS2=1;
LCD_Write_Command(0x38);//8位形式,2行字符
LCD_Write_Command(0x0F);//开显示
LCD_Write_Command(0x01);//清屏
LCD_Write_Command(0x06);//画面不动光标右移
LCD_Write_Command(LCD_START_ROW);//设置起始行
}
//通用显示函数
//从第P页第L列开始显示W字节数据,数据在r所指向的缓冲
//每字节8位是垂直显示的,高位在下,低位在上
//每个8*128的矩形区域为一页(每页分左半页与右半页)
//整个LCD又由64*64的左半习工和64*64的右半屏构成
voidCommon_Show(ucharP,ucharL,ucharW,uchar*r)
{
uchari;
if(L<64)//显示在左半屏或右半屏
{
CS1=1;CS2=0;
LCD_Write_Command(LCD_PAGE+P);
LCD_Write_Command(LCD_COL+L);
if(L+W<64)//全部显示在左半屏
{
for(i=0;i}
else//如果越界则跨越左右半屏显示
{
for(i=0;i<64-L;i++)LCD_Write_Data(r[i]);//左半屏显示
CS1=0;CS2=1;//右半屏显示
LCD_Write_Command(LCD_PAGE+P);
LCD_Write_Command(LCD_COL);
for(i=64-L;i}
}
else//全部显示在右半屏
{
CS1=0;CS2=1;
LCD_Write_Command(LCD_PAGE+P);
LCD_Write_Command(LCD_COL+L-64);
for(i=0;i}
}
//显示一个8*16点阵字符(字符上半部分与下半部分分别处在相邻两页中)
voidDisplay_A_Uchar(ucharP,ucharL,uchar*M)
{
Common_Show(P,L,8,M);
Common_Show(P+1,L,8,M+8);
}
//显示一个16*16点阵汉字(汉字上半部分与下半部分分别处在相邻两页中)
voidDisplay_A_WORD(ucharP,ucharL,uchar*M)
{
Common_Show(P,L,16,M);//显示汉字上半部分
Common_Show(P+1,L,16,M+16);//显示汉字下半部分
}
//显示一串16*16点阵汉字
voidDisplay_A_WORD_String(ucharP,ucharL,ucharC,uchar*M)
{
uchari;
for(i=0;iDisplay_A_WORD(P,L+i*16,M+i*32);
}
//-------------------------------DotMatrix.c--------------------------
//本例中相关汉字与数字的点阵编码
//--------------------------------------------------------------------#defineucharunsignedchar
#defineuintunsignedint
//中文提示(16*16点阵)
ucharcodeWord_String[][32]=
{
{0x10,0x28,0xE7,0x24,0x24,0xC2,0xB2,0x8E,0x10,0x54,0x54,0xFF,0x54,0x7C,0x10,0x00,0x01,0x01,0x7F,0x21,0x51,0x24,0x18,0x27,0x48,0x89,0x89,0xFF,0x89,0xCD,0x48,0x00
},
{0x20,0x20,0x20,0xFE,0x22,0x22,0xAB,0x32,0x22,0x22,0x22,0xFF,0x22,0x30,0x20,0x00,0x40,0x42,0x7D,0x44,0x44,0x7C,0x44,0x45,0x44,0x7D,0x46,0x45,0x7C,0x40,0x40,0x00
}
};
//键盘数字与符号点阵(8*16点阵)
ucharcodeKeyboard_Char[][16]=
{
{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,