您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > c51的简易计算器(已通过实测)初学者参考
1实验报告设计课题:基于单片机的简易计算器指导老师:班级:学号:姓名:2一设计内容和目的本次实验的任务就是要以51系列单片机为核心实现一个简易计算器计算器,它的结构非常简单,外部主要由4*4矩阵键盘和一个液晶显示屏构成,内部由一块AT89C51单片机构成,通过软件编程可实现简单加减乘除。目的:做自己喜欢的实验,提高自学能力。二方案论证经分析,计算器电路包括三个部分:显示电路、4*4键扫描电路、单片机微控制电路。具体如下:⒈)LCD显示电路LCD1602作为一个成熟的产品,使用简单,模式固定,便于移植到各种类型的程序,但是初学者往往要注意结合LCD本身的时序图来完善初始化程序。又以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,故采用LCD.⒉)4*4键盘扫描电路(中断式,扫描式,反转式)用户设计行列键盘接口,一般常采用3种方法读取键值。一种是中断式,外两种是扫描法和反转法。中断式:在键盘按下时产生一个外部中断通知CPU,并由中断处理程序通过不同的地址读取数据线上的状态,判断哪个案件被按下。本实验采用中断式实现用户键盘接口。扫描法:对键盘上的某一行送低电平,其他行为高电平,然后读取列值。若列值中有一位是低,则表明该行与低电平对应列的键被按下;否则,扫描下一行。反转法:先将所有行扫描线输出低电平,读列值。若列值有一位是低,则表明有键按下,读列值;然后所有列扫描线输出低电平,再读行值。根据读到的值组合就可以查表1得到的键码。这个就仁者见仁智者见智了,不过如果熟悉了扫描式,建议果断升级自己的硬件(很简单加个74LS08与门),故采用节省CPU的中断式扫描电路。⒊)单片机微控制电路微控制电路就是以AT89C51为核心的控制核心,主要注意晶振电路的接法和复3位电路的接法。三硬件电路的设计2.1硬件设计电路框图2.2硬件设计电路的元件清单器件名称数量AT89C511按键1774LS08110K电阻9电容22uF1LCD16021晶振12MHz1电容30pF25K电位器151系列单片机系统4*4键盘LCD显示晶振电路复位电路线路原理框图42.3硬件设计电路图将4*4的键盘直接接在P1口上,用P0口作为LCD的显示输出,P3.2口的INT0作为外部中断位。XTAL218XTAL119ALE30EA31PSEN29RST9P0.0/AD039P0.1/AD138P0.2/AD237P0.3/AD336P0.4/AD435P0.5/AD534P0.6/AD633P0.7/AD732P2.7/A1528P2.0/A821P2.1/A922P2.2/A1023P2.3/A1124P2.4/A1225P2.5/A1326P2.6/A1427P1.01P1.12P1.23P1.34P1.45P1.56P1.67P1.78P3.0/RXD10P3.1/TXD11P3.2/INT012P3.3/INT113P3.4/T014P3.7/RD17P3.6/WR16P3.5/T115U180C51X1CRYSTALC122pC222pC322pR11k+5VD714D613D512D411D310D29D18D07E6RW5RS4VSS1VDD2VEE3LCD1LM016LRV1k+5V+5V234567891RP1RESPACK-8+5V123U2:A74LS08456U2:B74LS089108U2:C74LS082.4硬件设计的补充说明5四软件设计程序及描述本程序组成可分为3个模块:矩阵键盘模块,LCD显示模块,和运算模块(源程序见底页)6开始初始化参数初始化LCD显示有键输入?读取键码LCD显示数字键清零键功能键状态清零输入数值数值送显示缓冲YN等待数值输入结果送显示缓冲根据上次功能键和输入的数据计算结果本次功能键?等待数值输入结果送显示缓冲等待数值输入结果送显示缓冲7五硬软件的调试及方法我个人遇到的主要问题出现在LCD1602上,要不是我自己买了块新的LCD恐怕我的结论,就只能在软件仿真实现了。硬件上:在不加芯片调试时,LCD1602只显示一排全黑,一般说明该元件是好的。(但也不一定,我那时就一直认为我的元件没坏);给15,16管脚分别接上+5v和0v,测试背光是否完好;给VEE接上电位器,检查对比度是否可调;一般LCD易出现的现象,我再做实验的时候遇到过以下几种情况:状态1上电之后,1602的第一行全黑,即16个5x7黑块产生原因:液晶根本就没有进行初始化操作,需要检查连线或者程序。运气不好的情况下就是整块LCD是坏的。状态2屏上显示两排灰格产生原因:程序中对液晶初始化不正常,应是部分初始化指令没有正常接收,建议按照标准初始化步骤调整程序,或者调整指令之间的延时(加大一些试试)----补充:也有可能是对比度太大,建议优先调整对比度电阻状态3显示乱码这是我在实验室组合版上做的,原因是接线问题状态3正确显示8六实验结果与性能达标我的计算器只能准确进行得数为0~9的四则运算。1.加法计算D714D613D512D411D310D29D18D07E6RW5RS4VSS1VDD2VEE3LCD1LM016L2.减法计算D714D613D512D411D310D29D18D07E6RW5RS4VSS1VDD2VEE3LCD1LM016L3.乘法计算D714D613D512D411D310D29D18D07E6RW5RS4VSS1VDD2VEE3LCD1LM016L4.除法计算D714D613D512D411D310D29D18D07E6RW5RS4VSS1VDD2VEE3LCD1LM016L5.字符显示A0A7A6A5A4A3A2A1D714D613D512D411D310D29D18D07E6RW5RS4VSS1VDD2VEE3LCD2LM016L实物与仿真不一致。这就是传说中的BUG了。我不明白。9七实验改进与心得体会很明显我的计算器处理数据及显示存在太大的局限性,我觉得主要还是我对程序中的运算模块理解不深,这点仍需大大加强。这个实验给我的感觉,硬件和软件上都不是很难。我的焊工也不马虎,即使难看了点,但只要软件能行,就能完美运行。可惜,我就败在LCD1602,从学校拿了两块,幸好最后实在没办法,自己买了一块。最终证实我之前的实验就是LCD的损坏。没知识真可怕,我不懂真正排查LCD的好坏。不过也因祸得福,我在磕磕碰碰中,固执的认为LCD是好的,反而使我对LCD初始化,LCD字符显示,3种不同的矩阵键盘扫描的方法,及软件上的巧妙技巧有了更好的了解。我在这次实验上,感觉收获的更多.下面是源代码:#includereg51.h#defineCLEARSCREENLCD_write_command(0x01)10#defineuintunsignedint#defineucharunsignedchar/**************定义接口************************/#defineLCDIOP0#defineKEYBOARDP1//保留sbitLCD1602_RS=P2^0;sbitLCD1602_RW=P2^1;sbitLCD1602_EN=P2^2;/************************************************/codeucharmayuan[16]={'0','1','2','3','4','5','6','7','8','9','0','/','*','-','+','='};//不错,这个比较明了unsignedcharcodekeycode[]={0x11,0x21,0x41,0x81,0x12,0x22,0x42,0x82,0x14,0x24,0x44,0x84,0x18,0x28,0x48,0x88};//键盘编码值()inti,j,k=1,s;//intt,t1,t2,a[];//voiddelay(uchar);//延时/**************定义函数************************/voidLCD_init(void);//初始化函数voiddelay_nms(unsignedintn);//延时函数voidLCD_write_command(unsignedcharcommand);//写入指令函数voidLCD_write_dat(unsignedchardat);//写入数据函数voiddelay_10ms();initial();ucharkeyscan();//键盘扫描函数calc(uchar);//计算函数ucharnum,temp,key,keynum;voidmain()//主函数{LCD_init();delay_nms(100);while(1){initial();//有中断KEYBOARD=0xf0;//键盘的列值全置高电平}}/**********************************开中断***************************************/initial(){EA=1;//总开关EX0=1;//中断方式0开启11IT0=0;}/*******************************************************************************//*********************************中断函数************************************/voidinter0()interrupt0{unsignedcharn;delay_10ms();//延时if(INT0==0)//没键按下{EX0=0;//关中断n=keyscan();calc(n);EX0=1;//开中断KEYBOARD=0xf0;//键盘的列值全置高电平}}/************************************************************************/calc(ucharn){if(n10)//键值小于10{t1=t1*10+n;LCD_write_command(0x00);//写命令语句LCD_write_dat(mayuan[n]);//写数据函数}else{if(n==10){LCD_init();t1=0;t2=0,t=0;k=1;}else{if(n15){t2=t1;t1=0;j=n;LCD_write_command(0x00);LCD_write_dat(mayuan[n]);}else{LCD_write_command(0x00);LCD_write_dat(mayuan[n]);switch(j){case11:t=t2/t1;12break;case12:t=t2*t1;break;case13:t=t2-t1;break;case14:t=t2+t1;break;}if(t=9){LCD_write_command(0x00);LCD_write_dat(t+48);}if(t9){while(t9){s=t%10;t=t/10;a[k]=s;k++;}if(t=9){LCD_write_command(0x00);LCD_write_dat(t+48);}for(i=k-1;i=1;i--){LCD_write_command(0x00);LCD_write_dat(a[i]+48);}}}}}}/*****************************************键盘扫描函数************************************/ucharkeyscan()//键盘扫描{KEYBOARD=0xf0;//键盘的列值全置高电平delay_10ms();//延时if(KEYBOARD!=0xf0)//有键按下{13temp=KEYBOARD;//保存键盘此刻的键植delay_10ms();//延时if(KE
本文标题:c51的简易计算器(已通过实测)初学者参考
链接地址:https://www.777doc.com/doc-4893861 .html