基于单片机实现的四则运算计算器.docx
- 文档编号:25617175
- 上传时间:2023-06-10
- 格式:DOCX
- 页数:22
- 大小:138.25KB
基于单片机实现的四则运算计算器.docx
《基于单片机实现的四则运算计算器.docx》由会员分享,可在线阅读,更多相关《基于单片机实现的四则运算计算器.docx(22页珍藏版)》请在冰豆网上搜索。
基于单片机实现的四则运算计算器
基于单片机实现的四则运算计算器
姓名
学号:
班级:
专业名称:
测控技术与仪器
指导教师:
东北大学
2016年1月
课程设计(论文)任务书
课程设计(论文)题目:
基于单片机实现的四则运算计算器
基本内容和设计要求:
1、主机的矩阵键盘输入数和运算符号,从机显示运算结果。
2、主从单片机串行通信系统,并在LCD上显示运算内容及结果。
3、计算结果超过十位数字则显示错误。
4、运算除法时,结果只取整数,不是四舍五入。
5、有清零功能。
摘要
单片机的出现是计算机制造技术高速发展的产物,它是嵌入式控制系统的核心,如今,它已广泛的应用到我们生活的各个领域,电子、科技、通信、汽车、工业等。
本设计是基于89C52RC单片机来进行的四则运算计算器系统设计,可以完成计算器的键盘输入,进行加、减、乘、除的基本四则运算,并在LCD1602液晶显示屏上显示相应的结果。
本电路采用89C52RC单片机为主要控制电路,利用4*4矩阵键盘作为计算器以及运算符的输入。
显示采用字符LCD静态显示。
软件用C语言编程,并用开发板进行演示。
关键词:
计算器,89C52RC单片机,LCD,矩阵键盘
第1章绪论
1.1计算器简介
计算器是现代人们发明的可以进行数字运算的电子机器。
现代的电子计算器能进行数学运算的手持电子机器,除显示计算结果外,还常有溢出指示、错误指示等,拥有集成电路芯片,但结构比电脑简单得多,可以说是第一代的电子计算机(电脑),且功能也较弱,但较为方便与廉价,可广泛运用于商业交易和学习计算中,是必备的学习和办公用品之一[1]。
1.2设计主要内容
本系统使用89C52RC单片机作为主控芯片,通过矩阵键盘输入,进行运算,并在LCD上显示相应的数字和结果,主要功能如下:
(1)LCD第一行显示运算符号之前的数字,第二行显示运算符号和运算符号之后的数字,按下等号键得到结果。
(2)在任何时候按下清零键则清零。
(3)当运算完第一次完整的计算之后,可以在不按任何键的情况下,进行新的一轮计算。
本系统采用MCS-52系列单片机作为主控机,通过拓展必要的外围电路,实现对计算器的设计,具体设计如下:
(1)因为想显示运算符号,用数码管不能很好的显示出来,所以采用LCD1602液晶显示器作为显示模块。
(2)计算器一般包含数字键(0~9),符号键(+,—,*,/),等号键,清零键。
故采用4*4矩阵键盘结合键盘扫描技术来达到要求。
(3)开机后1602显示‘0’,等待按键输入,当键入数字,在LCD上显示出来,计算器内部把数据储存起来,并等待下一按键输入,当键入运算符号时,计算器内部步数加1,然后等待再次输入数值,按等于号就在LCD上显示结果。
(4)清零功能:
在运算的任何时候键入清零键,则把数据清零,等待下一次运算。
根据给的开发板的原理图在protel中设计并连接电路图,分析电路图的正确性,输出PCB图。
利用C语言编程,分模块测试板子的好坏,然后编写程序,在keil中进行调试。
第2章系统硬件设计
2.1硬件组成
硬件以89C52单片机为核心,外部扩展用LCD实现显示功能,用4*4矩阵键盘实现输入功能。
基本硬件结构图如图2.1所示。
图2.1四则运算计算器基本硬件结构图
2.2输入模块
计算器输入数字和其他功能按键要用到很多按键,如果采用独立按键的方式,在这种情况下,编程会简单,但I/0口不够用,所以采用矩阵键盘形式,本次采用4*4矩阵键盘的形式,采用四条I/O线作为行线,四条I/O线作为列线组成键盘。
在行线和列线的每个交叉点上设置一个按键,这样键盘上按键的个数就为4×4个。
图2-2输入模块电路图
矩阵键盘功能:
预设16个键位,分别是0~9数字键,加减乘除,等于和清零功能。
单片机不停扫描键盘当发现有按键按下时,若为数字键则在lcd上显示,功能键则实现对应的功能。
例如,按下5时,lcd上显示数字5,按下加号,即实现加法功能也在lcd上显示加号。
2.3输出模块
采用LCD1602来显示字符和数字,1602能够同事显示16*02即32个字符。
1602液晶模块内部的字符发生储存器已经储存了160个不同的点阵字符图形,这些字符有:
阿拉伯数字,英文字母大小写,常用的符号等,每一个字符有一个固定的代码。
在对液晶模块的初始化中要先设置其显示模式,在液晶模块显示字符时光标是自动右移的。
每次输入指令前都要判断液晶模块是否处于忙的状态。
图2-3输出模块电路图
lcd1602能够同时显示16*2个字符,用它接收单片机送来的信号,然后在上边显示相应的数字或符号,实现显示功能。
2.4运算模块
单片机是靠程序运行的,并且可以修改。
通过不同的程序实现不同的功能,尤其是特殊的独特的一些功能,通过上网查找运算代码作参考,然后对单片机进行程序编写,从而实现运算功能。
第3章系统软件设计
3.1主程序
主程序框图如图3.1所示
图3.1主程序框图
主程序说明:
接通电源后,先让lcd显示屏初始化显示0,然后通过键盘扫描看是否有键按下,若有键按下,则分析按下键的性能,若为数字键或清零键则通过lcd显示,若为功能键,实现功能然后lcd显示。
图3.2LCD程序框图
Lcd初始化显示0,开始后判断是否有键按下,有键按下判断是否是数字键,若为数字键则显示键值,若不是,则为功能键,再判断功能键是否是等号,若为等号,则显示计算结果,若不是实现功能,等待输入。
图3.3键盘程序框图
开始后,扫描键盘,若没有键按下则继续扫描,有键按下,若为等号键则显示结果然后结束,若不是看是否是计算符,不是计算符则读入内存然后lcd显示,若是计算符读进内存,等待输入。
图3.4运算程序框图
运算程序:
先判断运算符,若为加或乘则要判断运算结果是否溢出,若溢出,则lcd显示-1表示运算错误,若为除号,判断除数是否为0,若为0,则lcd显示-1表示运算错误,其他情况则可直接送至lcd显示。
第4章调试测试与实验分析
4.1计算器调试
(1)问题:
将已编好的程序用烧录进开发板后,发现开发板上LCD显示屏只发光但是没有任何数字。
(2)分析:
这种现象可能存在两个问题:
1)LCD显示屏有问题
2)程序存在错误
(3)解决方案:
重新检查开发板元器件,将开发版资料已给的1602液晶显示程序烧录开发板中,发现LCD仍然只发光不显示任何东西,初步判定是LCD未调节好或者故障,经检测是LCD显示字符的亮度未调节合适,拿螺丝刀调节,LCD就能显示字符。
(4)再次检测:
再次将已编好的程序烧录进开发板,打开开发板电源,LCD上先显示‘0’字符。
矩阵键盘输入‘3*4’进行计算,发现显示屏上第一行显示‘3’,第二行显示‘4’和‘*’,然后在键盘上输入‘=’,显示屏上得出结果12。
参考文献
[1]李小坚郝晓丽.protelDXP电路设计与制版实用教程[J].人民邮电出版社,2015,10.
[2]张秋菊刘继超.单片机应用实训教程[J].化学工业出版社,2015,10.
心得体会
周二早上开始选课题的时候,感觉我们的能力不是很强,所以想选一个简单一点的题目,然后就选了一个四则运算计算器,这个题目硬件上的确不难,但是软件上却令我们很困扰,很头疼。
周二下午写计划的时候,看到被老师打回来这么多份计划,我们就想自己好好的写一写,可是还是改了两遍,也用了一晚上的时间,但是这个计划却对我们之后几天的工作有一个很好的指导。
第二天学习protel,老师没有怎么讲,我们一开始也不会用,只能是哪里不会哪里XX,但是有的元件还是没有找到,周四早上才知道原来资料里有单片机上的元件库,于是把那个元件库导入,画图便容易多了。
我们硬件没有什么东西,于是第三天下午便开始编程了,可是我们对着程序看了一下午也没有什么头绪,反而整得自己要发疯了一样,对课设也失去了信心。
后来老师来检查的时候告诉我们要一步一步的调试,不可能一口吃个大胖子,我们就把程序分开来调试,通过从图书馆借来的资料一步一步的来,程序中不懂的地方便查书或者通过网络解决。
这几天的确是蛮痛苦的,天天早晨起来到教室里,一坐一天,感觉比上课累多了,可也有了自己的收获,没有老师指导,需要的东西基本上要自己来查找,也锻炼了自己的能力。
实物的焊接也锻炼了我们的动手能力,课程设计对于我们的益处是很大的。
也希望自己通过知识与实际的结合不断的提高自己。
附录硬件原理图及PCB图
附录程序清单
LCD1602
#include
#defineLCD1602_DBP0
sbitLCD1602_RS=P1^0;
sbitLCD1602_RW=P1^1;
sbitLCD1602_E=P1^2;
/*等待液晶准备好*/
voidLcdWaitReady()
{
unsignedcharsta;
LCD1602_DB=0xFF;
LCD1602_RS=0;
LCD1602_RW=1;
do{
LCD1602_E=1;
sta=LCD1602_DB;//读取状态字
LCD1602_E=0;
}while(sta&0x80);//bit7等于1表示液晶正忙,重复检测直到其等于0为止
}
/*向LCD1602液晶写入一字节命令,cmd-待写入命令值*/
voidLcdWriteCmd(unsignedcharcmd)
{
LcdWaitReady();
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_DB=cmd;
LCD1602_E=1;
LCD1602_E=0;
}
/*向LCD1602液晶写入一字节数据,dat-待写入数据值*/
voidLcdWriteDat(unsignedchardat)
{
LcdWaitReady();
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_DB=dat;
LCD1602_E=1;
LCD1602_E=0;
}
/*设置显示RAM起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标*/
voidLcdSetCursor(unsignedcharx,unsignedchary)
{
unsignedcharaddr;
if(y==0)//由输入的屏幕坐标计算显示RAM的地址
addr=0x00+x;//第一行字符地址从0x00起始
else
addr=0x40+x;//第二行字符地址从0x40起始
LcdWriteCmd(addr|0x80);//设置RAM地址
}
/*在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,str-字符串指针*/
voidLcdShowStr(unsignedcharx,unsignedchary,unsignedchar*str)
{
LcdSetCursor(x,y);//设置起始地址
while(*str!
='\0')//连续写入字符串数据,直到检测到结束符
{
LcdWriteDat(*str++);
}
}
/*区域清除,清除从(x,y)坐标起始的len个字符位*/
voidLcdAreaClear(unsignedcharx,unsignedchary,unsignedcharlen)
{
LcdSetCursor(x,y);//设置起始地址
while(len--)//连续写入空格
{
LcdWriteDat('');
}
}
/*整屏清除*/
voidLcdFullClear()
{
LcdWriteCmd(0x01);
}
/*初始化1602液晶*/
voidInitLcd1602()
{
LcdWriteCmd(0x38);//16*2显示,5*7点阵,8位数据接口
LcdWriteCmd(0x0C);//显示器开,光标关闭
LcdWriteCmd(0x06);//文字不动,地址自动+1
LcdWriteCmd(0x01);//清屏
}
矩阵键盘
#include
sbitKEY_IN_1=P2^4;
sbitKEY_IN_2=P2^5;
sbitKEY_IN_3=P2^6;
sbitKEY_IN_4=P2^7;
sbitKEY_OUT_1=P2^3;
sbitKEY_OUT_2=P2^2;
sbitKEY_OUT_3=P2^1;
sbitKEY_OUT_4=P2^0;
unsignedcharcodeKeyCodeMap[4][4]={//矩阵按键编号到标准键盘键码的映射表
{'1','2','3',0x26},//数字键1、数字键2、数字键3、向上键
{'4','5','6',0x25},//数字键4、数字键5、数字键6、向左键
{'7','8','9',0x28},//数字键7、数字键8、数字键9、向下键
{'0',0x1B,0x0D,0x27}//数字键0、ESC键、回车键、向右键
};
unsignedcharpdataKeySta[4][4]={//全部矩阵按键的当前状态
{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
};
externvoidReset();
externvoidGetResult();
externvoidNumKeyAction(unsignedcharn);
externvoidOprtKeyAction(unsignedchartype);
externvoidLcdShowStr(unsignedcharx,unsignedchary,unsignedchar*str);
voidKeyAction(unsignedcharkeycode)
{
if((keycode>='0')&&(keycode<='9'))
{
NumKeyAction(keycode-'0');
}
elseif(keycode==0x26)
{
OprtKeyAction(0);
}
elseif(keycode==0x28)
{
OprtKeyAction
(1);
}
elseif(keycode==0x25)
{
OprtKeyAction
(2);
}
elseif(keycode==0x27)
{
OprtKeyAction(3);
}
elseif(keycode==0x0D)
{
GetResult();
}
elseif(keycode==0x1B)
{
Reset();
LcdShowStr(15,1,"0");
}
}
/*按键驱动函数,检测按键动作,调度相应动作函数,需在主循环中调用*/
voidKeyDriver()
{
unsignedchari,j;
staticunsignedcharpdatabackup[4][4]={//按键值备份,保存前一次的值
{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
};
for(i=0;i<4;i++)//循环检测4*4的矩阵按键
{
for(j=0;j<4;j++)
{
if(backup[i][j]!
=KeySta[i][j])//检测按键动作
{
if(backup[i][j]!
=0)//按键按下时执行动作
{
KeyAction(KeyCodeMap[i][j]);//调用按键动作函数
}
backup[i][j]=KeySta[i][j];//刷新前一次的备份值
}
}
}
}
/*按键扫描函数,需在定时中断中调用,推荐调用间隔1ms*/
voidKeyScan()
{
unsignedchari;
staticunsignedcharkeyout=0;//矩阵按键扫描输出索引
staticunsignedcharkeybuf[4][4]={//矩阵按键扫描缓冲区
{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},
{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF}
};
//将一行的4个按键值移入缓冲区
keybuf[keyout][0]=(keybuf[keyout][0]<<1)|KEY_IN_1;
keybuf[keyout][1]=(keybuf[keyout][1]<<1)|KEY_IN_2;
keybuf[keyout][2]=(keybuf[keyout][2]<<1)|KEY_IN_3;
keybuf[keyout][3]=(keybuf[keyout][3]<<1)|KEY_IN_4;
//消抖后更新按键状态
for(i=0;i<4;i++)//每行4个按键,所以循环4次
{
if((keybuf[keyout][i]&0x0F)==0x00)
{//连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下
KeySta[keyout][i]=0;
}
elseif((keybuf[keyout][i]&0x0F)==0x0F)
{//连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起
KeySta[keyout][i]=1;
}
}
//执行下一次的扫描输出
keyout++;//输出索引递增
keyout&=0x03;//索引值加到4即归零
switch(keyout)//根据索引,释放当前输出引脚,拉低下次的输出引脚
{
case0:
KEY_OUT_4=1;KEY_OUT_1=0;break;
case1:
KEY_OUT_1=1;KEY_OUT_2=0;break;
case2:
KEY_OUT_2=1;KEY_OUT_3=0;break;
case3:
KEY_OUT_3=1;KEY_OUT_4=0;break;
default:
break;
}
}
主函数
#include
unsignedcharstep=0;
unsignedcharoprt=0;
signedlongnum1=0;
signedlongnum2=0;
signedlongresult=0;
unsignedcharT0RH=0;
unsignedcharT0RL=0;
voidConfigTimer0(unsignedintms);
externvoidKeyScan();
externvoidKeyDriver();
externvoidInitLcd1602();
externvoidLcdShowStr(unsignedcharx,unsignedchary,unsignedchar*str);
externvoidLcdFullClear();
externvoidLcdAreaClear(unsignedcharx,unsignedchary,unsignedcharlen);
voidmain()
{
EA=1;//开总中断
ConfigTimer0
(1);//配置T0定时1ms
InitLcd1602();//初始化液晶
LcdShowStr(15,1,"0");//初始显示一个数字0
while
(1)
{
KeyDriver();//调用按键驱动
}
}
unsignedcharLongToString(unsignedchar*str,signedlongdat)
{
signedchari=0;
unsignedcharlen=0;
unsignedcharbuf[12];
if(dat<0)
{
dat=-dat;
*str++='-';
len++;
}
do{
buf[i++]=dat%10;
dat/=10;
}while(dat>0);
len+=i;
while(i-->0)
{
*str++=buf[i]+'0';
}
*str='\0';
returnlen;
}
voidShowOprt(unsignedchary,unsignedchartype)
{
switch(type)
{
case0:
LcdShowStr(0,y,"+");break;
case1:
LcdShowStr(0,y,"-");break;
case2:
LcdShowStr(0,y,"*");break;
case3:
LcdShowStr(0,y,"/");break;
default:
break;
}
}
voidReset()
{
num1=0;
num2=0;
step=0;
LcdFullClear();
}
voidNumKeyAction(unsignedcharn)
{
unsignedcharlen=0;
unsignedcharstr[12];
if(step>1)
{
Reset();
}
if(step==0)
{
num1=num1*10+n;
len=LongToString(str,num1);
LcdShowStr(16-len,1,str);
}
else
{
num2=num2*10+n;
len=LongToString(str,num2);
LcdShowStr(16-len,1,str);
}
}
voidOprtKeyAction(unsignedchartype)
{
unsignedcharlen;
unsignedcharstr[12];
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 单片机 实现 四则运算 计算器