基于单片机的多功能计算器设计.docx

上传人:b****1 文档编号:15137149 上传时间:2023-07-01 格式:DOCX 页数:23 大小:821.01KB
下载 相关 举报
基于单片机的多功能计算器设计.docx_第1页
第1页 / 共23页
基于单片机的多功能计算器设计.docx_第2页
第2页 / 共23页
基于单片机的多功能计算器设计.docx_第3页
第3页 / 共23页
基于单片机的多功能计算器设计.docx_第4页
第4页 / 共23页
基于单片机的多功能计算器设计.docx_第5页
第5页 / 共23页
基于单片机的多功能计算器设计.docx_第6页
第6页 / 共23页
基于单片机的多功能计算器设计.docx_第7页
第7页 / 共23页
基于单片机的多功能计算器设计.docx_第8页
第8页 / 共23页
基于单片机的多功能计算器设计.docx_第9页
第9页 / 共23页
基于单片机的多功能计算器设计.docx_第10页
第10页 / 共23页
基于单片机的多功能计算器设计.docx_第11页
第11页 / 共23页
基于单片机的多功能计算器设计.docx_第12页
第12页 / 共23页
基于单片机的多功能计算器设计.docx_第13页
第13页 / 共23页
基于单片机的多功能计算器设计.docx_第14页
第14页 / 共23页
基于单片机的多功能计算器设计.docx_第15页
第15页 / 共23页
基于单片机的多功能计算器设计.docx_第16页
第16页 / 共23页
基于单片机的多功能计算器设计.docx_第17页
第17页 / 共23页
基于单片机的多功能计算器设计.docx_第18页
第18页 / 共23页
基于单片机的多功能计算器设计.docx_第19页
第19页 / 共23页
基于单片机的多功能计算器设计.docx_第20页
第20页 / 共23页
亲,该文档总共23页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

基于单片机的多功能计算器设计.docx

《基于单片机的多功能计算器设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的多功能计算器设计.docx(23页珍藏版)》请在冰点文库上搜索。

基于单片机的多功能计算器设计.docx

基于单片机的多功能计算器设计

 

工程设计训练

设计报告

 

课题名称基于单片机的多功能计算器设计

院系物理与电子工程学院

年级专业电子信息工程

班级学号

学生姓名任课教师

设计时间

目录

第一章概述

第二章硬件设计方案

第三章程序设计

第四章软件仿真调试

心得体会

参考文献

附录

 

工程设计训练—基于单片机的多功能计算器设计任务书

一、设计课题:

基于单片机的多功能计算器设计

二、设计目的:

运用已学课程的基本知识,在设计中加以应用,进而得到理解、巩固和提高发展,通过实践的过程学习掌握分析与解决实际问题的方法与手段,提高设计、编程与调试的实际动手能力,作为工程技术工作的一次基本训练。

三、设计任务:

使用AT89C51单片机设计一个多功能计算器,主要用到矩阵键盘,LCD液晶显示器。

要求进行硬件、软件系统设计。

四、主要任务:

1、在多功能计算器上能够显示所输入的表达式,例如:

(20+10)/10

2、在设计中,能进行加减乘除及优先级运算,例如:

2+6*2,并且有清除功能用C表示。

3、能够计算的最大数字位数是两位。

4、程序设计完过后,进行电路设计。

用protues软件进行仿真。

 

二,具体内容

I-硬件设计

单片机用AT89C51,4*4矩阵键盘,显示用LCD1602,上拉电阻,74HC21与门和一些外设设备(晶振,电容)

设置

1—AT89C51单片机

2--计算器的键盘布局:

计算器有16个键(0,1,2,3,4,5,6,7,8,9,/,*,+,-,=,ON/AC)组成,在单片机中正好有一个端口实现16个按键功能,这种形式在单片机系统中最常用是矩阵键盘。

矩阵式结构的键盘识别要复杂一些,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。

这样,当按键没有按下时,所有的输入端都是高电平,代表无键按下。

行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。

  

  在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。

这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。

由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。

  <1>确定矩阵式键盘上何键被按下介绍一种“行扫描法”。

  行扫描法行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,如上图所示键盘,介绍过程如下。

  1、判断键盘中有无键按下将全部行线Y0-Y3置低电平,然后检测列线的状态。

只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。

若所有列线均为高电平,则键盘中无键按下。

  2、判断闭合键所在的位置在确认有键按下后,即可进入确定具体闭合键的过程。

其方法是:

依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。

在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。

若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。

  <2>确定矩阵式键盘上何键被按下介绍一种“高低电平翻转法”。

  首先让P1口高四位为1,低四位为0,。

若有按键按下,则高四位中会有一个1翻转为0,低四位不会变,此时即可确定被按下的键的行位置。

  然后让P1口高四位为0,低四位为1,。

若有按键按下,则低四位中会有一个1翻转为0,高四位不会变,此时即可确定被按下的键的列位置。

最后将上述两者进行或运算即可确定被按下的键的位置。

本设计用第一种“行扫描法”。

键盘与单片机接口是P1^0=R1,P1^1=R2,P1^2=R3,P1^3=R4.P1^4=L1,

P1^5=L2,P1^6=L3,P1^7=L4

3--74HC21与门接线图

4--上拉电阻

作用是驱动LCD1602

5—LCD1602显示模块

本设计采用LCD液晶显示器来显示输出数据。

LCD的特性有:

1、+5V电压,对比可调度;2、内含复位电路;3、提供各种控制命令,如:

清屏、字符闪烁、光标闪烁、显示移位等多种功能;4、有80字节显示数据存储器DDRAM;5、内建有160个5X7点阵的字型的字符发生器CGROM;6、8个可由用户自定义的5X7的字符发生器CGRAM。

本设计通过D0-D7引脚向LCD写指令字或写数据以使LCD实现不同的功能或显示相应的数据。

接口电路如下:

II--软件设计

输入数据和表达式并显示表达式。

判断输入是否正确,如果输入错误显示”ERROR”,如果输入正确就进行分辨符号“*”,“/”,“+”,“-”然后按这样顺序(乘,除,加,减)进行运算

仿真用KeilUvision2软件和Proteus7软件

仿真结果

#include

//#include

#defineuintsignedint

#defineucharunsignedchar

#definefuhao_1-1//'/"除符号

#definefuhao_2-2//乘符号

#definefuhao_3-3//减符号

#definefuhao_4-4//加符号

sbitlcden=P3^5;//定义引脚E使能

sbitrs=P3^7;

sbitrw=P3^6;

sbitbusy=P0^7;

sbitp33=P3^3;

floatarry[20];

intarry_1[]={0x52,0x4f,0x52,0x52,0x45};//"ERROR'

longc;//结果

longq;//结果的绝对数

ucharerror;//错误标志

ucharm;//输入新表达式的标志

ucharok_flag;//输入完毕的标志

ucharfuhao;//符号标志

voiddelay(ucharz)//延迟函数

{uchary;

for(z;z>0;z--)

for(y=0;y<110;y++);

}

//*********************判断忙或空闲******************//

voidcheck()

{

do{

P0=0xFF;

rs=0;

rw=1;//读rsrw值为01时,忙标志和地址计数器读出

lcden=0;//E=0,禁止读写

delay

(1);//等待,液晶显示器处理数据

lcden=1;//E=1,允许读写

}while(busy==1);//判断是否为空闲,1为忙,0为空闲

}

//*********************写指令函数*****************//

voidwrite_com(ucharcom)

{

P0=com;//com指令付给P0口

rs=0;

rw=0;

lcden=0;

check();

lcden=1;

}

//**********************写数据函数*********************//

voidwrite_date(uchardate)

{

P0=date;

rs=1;

rw=0;

lcden=0;

check();

lcden=1;

}

voidinit()//初始化

{uchari;

lcden=1;//使能信号为高电平

write_com(0x38);//功能设置命令:

8位,2行DDRAM的地址

write_com(0x0e);//显示开,光标开,不闪烁

write_com(0x06);//地址计数器加1模式,显示屏不移位

write_com(0x80);//设置访问地址

for(i=0;i<20;i++)

{arry[i]=0;}

error=0;

ok_flag=0;

c=0;

q=0;//结果

fuhao=0;//fuhao表征按下的是哪个符号

}

//*****************键盘扫描程序**********************//

voidkeyscan(void)//键盘扫描程序

{uchartemp,i,num;

voidint0();

if(m==1)//输入新表达式

{

write_com(0x01);//清屏命令

for(i=0;i<20;i++)

{arry[i]=0;}

m=0;

ok_flag=0;

fuhao=0;

}

P1=0xfe;

if(P1!

=0xfe)//第1行有键按下

{

delay(20);//20ms

if(P1!

=0xfe)//第1行确实有键按下

{

temp=P1&0xf0;

switch(temp)

{

case0xe0:

num=0;//确定按键为第1行第1列,置标示符num

break;

case0xd0:

num=1;

break;

case0xb0:

num=2;

break;

case0x70:

num=3;

break;

}

}

while(P1!

=0xfe);

if(num==0)

{arry[2*fuhao]=10*(arry[2*fuhao])+7;write_date(0x30+7);}//第1行第1列键值7,存在数组arry[]

if(num==1)

{arry[2*fuhao]=10*(arry[2*fuhao])+8;write_date(0x30+8);}

if(num==2)

{arry[2*fuhao]=10*(arry[2*fuhao])+9;write_date(0x30+9);}

if(num==3)

{arry[2*fuhao+1]=fuhao_1;fuhao++;write_date(0x2f);}//第1行第4列键值"/",存在数组arry[]

}

P1=0xfd;

if(P1!

=0xfd)//第2行有键按下

{

delay(20);

if(P1!

=0xfd)//第2行确实有键按下

{

temp=P1&0xf0;

switch(temp)

{

case0xe0:

num=4;//确定按键为第2行第1列,置标示符num

break;

case0xd0:

num=5;

break;

case0xb0:

num=6;

break;

case0x70:

num=7;

break;

}

}

while(P1!

=0xfd);

if(num==4)

{arry[2*fuhao]=10*(arry[2*fuhao])+4;write_date(0x30+4);}//第2行第1列键值为4,存在数组arry[]

if(num==5)

{arry[2*fuhao]=10*(arry[2*fuhao])+5;write_date(0x30+5);}

if(num==6)

{arry[2*fuhao]=10*(arry[2*fuhao])+6;write_date(0x30+6);}

if(num==7)

{arry[2*fuhao+1]=fuhao_2;fuhao++;write_date(0x2a);}//第2行第4列键值为"*",存在数组arry[]

}

P1=0xfb;//第3行有键按下

if(P1!

=0xfb)

{

delay(20);

if(P1!

=0xfb)//第3行确实有键按下

{

temp=P1&0xf0;

switch(temp)

{

case0xe0:

num=8;//确定按键为第3行第1列,置标示符num

break;

case0xd0:

num=9;

break;

case0xb0:

num=10;

break;

case0x70:

num=11;

break;

}

}

while(P1!

=0xfb);

if(num==8)

{arry[2*fuhao]=10*(arry[2*fuhao])+1;write_date(0x30+1);}//第3行第1列键值为1,存在数组arry[]

if(num==9)

{arry[2*fuhao]=10*(arry[2*fuhao])+2;write_date(0x30+2);}

if(num==10)

{arry[2*fuhao]=10*(arry[2*fuhao])+3;write_date(0x30+3);}

if(num==11)

{arry[2*fuhao+1]=fuhao_3;fuhao++;write_date(0x2d);}//第3行第4列键值为"-",存在数组arry[]

}

P1=0xf7;

if(P1!

=0xf7)

{

delay(20);

if(P1!

=0xf7)

{

temp=P1&0xf0;

switch(temp)

{

case0xe0:

num=12;

break;

case0xd0:

num=13;

break;

case0xb0:

num=14;

break;

case0x70:

num=15;

break;

}

}

while(P1!

=0xf7);

if(num==12)//第4行第1列ON/C键,清屏

{

write_com(0x01);

for(i=0;i<20;i++)

{arry[i]=0;}

fuhao=0;

ok_flag=0;

}

if(num==13)

{arry[2*fuhao]=10*(arry[2*fuhao]);write_date(0x30);}//第4行第2列键值为0,存在数组arry[]

if(num==14)

{ok_flag=1;m=1;}//第4行第3列j键值"=",输入完毕,输入新表达式

if(num==15)

{arry[2*fuhao+1]=fuhao_4;fuhao++;write_date(0x2b);}////第2行第4列键值为"*",存在数组arry[]

}

P1=0xf0;//置第一行全部按下

}

//***********************条件运算条件*********************//

voidstop(void)

{uchark,h;

h=2*fuhao;

for(k=0;k<=h;k++)

{

if((arry[k])<0)

{if((arry[k+1])==0)

if(arry[k+2]<0)

error=1;}

if(arry[k]==fuhao_1)

{if(arry[k+1]==0)

error=1;}

}

}

//************************运算*********************//

voidprocess(void)

{ucharh,k,i,j;

for(k=0;k<=(2*fuhao);k++)

{

if(arry[k]==fuhao_2)//乘符号//

{

j=k-1;

h=2*fuhao-2;

arry[j]=arry[j]*arry[j+2];

for(i=(j+1);i<=h;i++)

{arry[i]=arry[i+2];}

fuhao=fuhao-1;

k=k-1;

}

}

for(k=0;k<=(2*fuhao);k++)

{

if(arry[k]==fuhao_1)//除符号//

{

j=k-1;

h=2*fuhao-2;

arry[j]=arry[j]/arry[j+2];

for(i=(j+1);i<=h;i++)

{arry[i]=arry[i+2];}

fuhao=fuhao-1;

k=k-1;

}

}

h=fuhao;

for(k=1;k<=h;k++)

{if(arry[1]==fuhao_3)//减符号//

{arry[0]=arry[0]-arry[2];

fuhao=fuhao-1;

for(i=1;i<=(2*fuhao);i++)

{arry[i]=arry[i+2];}

}

else

{if(arry[1]==fuhao_4)//加符号//

{arry[0]=arry[0]+arry[2];

fuhao=fuhao-1;

for(i=1;i<=(2*fuhao);i++)

{arry[i]=arry[i+2];}

}

//*******显示运算结果****************//

if(fuhao==0)

{c=arry[0];//小位数取三位//

write_com(0x80+0x4f);

//按下等于键,光标前进至第二行最后一个显示处//

write_com(0x04);

//设置从后住前写数据每写完一个数据,光标后退一格//

if(c<0)

{

q=0-c;

}

if(q>=1000)

{

i=0;

while(i<3)

{write_date(0x30+q%10);

q=q/10;

i++;

}

write_date(0x2e);//写小数符号"."

while(q!

=0)

{

write_date(0x30+q%10);

q=q/10;

}

}

if(c<0)

write_date(0x2d);//写"-"符号

write_date(0x3d);//再写"="符号

}

ok_flag=0;

}

//************************输入错误处理***************************//

voiderror_process(void)

{inti;

write_com(0x80+0x4f);

//按下等于键,光标前进至第二行最后一个显示处//

write_com(0x04);

//设置从后住前写数据,每写完一个数据,光标后退一格//

for(i=0;i<5;i++)

{write_date(arry_1[i]);

}

error=0;

for(i=0;i<20;i++)

{arry[i]=0;}

}

//**************************主函数************************//

voidmain(void)

{uchari;

init();

EX1=1;

EA=1;

IT1=1;

p33=1;

P1=0xf0;

while

(1)

{

if(p33==0)

{keyscan();}

if(ok_flag==1)

{

stop();

if(error==1)

{error_process();}

else

{process();

for(i=0;i<20;i++)

{arry[i]=0;}

}

ok_flag=0;

}

}

}

voidint0()interrupt2using1//中断

{

if(p33==1)

{

p33=0;

}

}

 

参考文献

教师评语:

 

工程设计成绩:

任课教师签名:

 

附录

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2