简易计算器设计报告.pdf

上传人:l*** 文档编号:83459191 上传时间:2023-03-31 格式:PDF 页数:45 大小:1.75MB
返回 下载 相关 举报
简易计算器设计报告.pdf_第1页
第1页 / 共45页
简易计算器设计报告.pdf_第2页
第2页 / 共45页
点击查看更多>>
资源描述

《简易计算器设计报告.pdf》由会员分享,可在线阅读,更多相关《简易计算器设计报告.pdf(45页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、精品文档 1602 液晶显示计算器 设计报告 2016 年 10 月 精品文档 一、摘要 计算器是人们的日常生活最常见的电子产品之一,应用广泛,功能强大。本次我们小组设计制作了一个简易计算器,能够在-99999999999999 的范围内进行整数、小数的四则运算运算,并求解 ax+ex=b 类型方程。该计算器以 AT89C51单片机芯片作为核心,采 4*4 矩阵键盘作为输入,将数据输入单片机内部处理,用 LCD1602 工业字符液晶显示出运算和结果。进行显示。经过检验能够实现预设功能,具有很高的实用价值。关键词:单片机;简易计算器;AT89C51;LCD1602。本设计具有以下功能:1、能够实

2、现-99999999999999 范围内整数,小数的基本运算(超出范围后报错)。2、储存运算结果,掉电不丢失。3、实现 6 位及以上有效数字。4、解 ax+ex=b 方程。5、能够连续运算,即上次运算结果作为下次的输入。6、能够在一次操作中连续运算。二、方案论证 方案描述:方案一:以 51 单片机为核心,4*4 矩阵键盘输入,数码管显示输入数字和运算结果。方案二:以 51 单片机为核心,4*4 矩阵键盘输入,LCD1602 显示输入数字和运算结果。精品文档 方案比较与选择:LCD1602 作为一个成熟的产品,使用简单,模式固定,便于移植到各种类型的程序,又有微功耗、体积小、显示内容丰富超薄轻巧

3、等优点,而数码管虽然亮度高,但是操作复杂、能耗高、且不能显示符号,本设计对亮度要求不是特别高,故采用方案二。三、解方程算法 ax+ex=b 为非线性方程,采用牛顿法迭代求解。原理是利用泰勒公式在 X0处展开,且展开到一阶,即 f(X)=f(X0)+(X-X0)f(X0),求解 X=X1=X0-f(X0)/f(X0),进而推出 Xn+1=Xn-f(Xn)/f(Xn)。通过迭代,这个式子必然在 f(x)=0 的时候收敛,进而得到方程的解。四、电路与程序 系统组成:电源系统,复位电路,晶振电路,4*4 矩阵键盘,独立按键,STC80C52,LCD1602。具体设计如下:精品文档 1、复位电路 2、键

4、盘电路 3、晶振电路 S17 1K 精品文档 4、1602 显示屏 精品文档 1602 精品文档 5、STC89C52 电路 6、电源电路 精品文档 系统软件与流程图:1)、总流程图 开始 初始化 读 取 Function 存入 eeprom 扫描4*4矩阵键盘生成Function 计算 扫描显示选择界面(短按),显示上次计算结果 解方程 否 是 是否按下 Fuction value 精品文档 2)、计算部分流程图 09为数字 运算符 等号 1015 为符号 09 1014 生成 num2 扫描 4*4 矩阵键盘 1602 显示 显示 num2 扫描 4*4 矩阵键盘 记录符号 生成 num1

5、 1602 显示 计算生成 num2 015?keyvalue 015?精品文档 3)、解方程部分流程图 计算生成 num2 初值 x0=0 09为数字 09为数字 是 否 15 为确认 15 为确认 生成参数 a 生成参数 b 扫描 4*4 矩阵键盘 扫描 4*4 矩阵键盘 1602 显示 1602 显示 显示结果 Xn Xn+1=Xn-f(Xn)/f(Xn)015?015?f(Xn)0.0005?精品文档 使用说明:1、接入电源,按下电源开关后进入上次关闭时的界面(计算或解方程界面)。2、计算时,输入数字和符号,按等号键输出结果,超出运算范围则报错,按 AC键退出;3、解方程时,先输入参数

6、 a,b,按等号键确认,后输出 ax+ex=b 的解。按任意键继续解方程。4、在任意时刻短按 mode 键进入菜单界面,按 1 进入计算界面,按 2 进入解方程界面。5、长按 mode 键为记忆功能,即显示上次的计算结果。测试方案及结果:1、菜单界面 2、加法运算 精品文档 3、减法运算 4、乘法运算 5、除法运算 6、连续运算 精品文档 7、上次运算结果作为下次输入 8、报错 9、解方程 10、记忆功能 参考书目 精品文档 新概念 51 单片机 C 语言教程电子工业出版社 精品文档 附录 源代码:/键盘接 P3,1602 接 P0,STC89C58RC/by-FCY 2016-10#incl

7、ude /单片机头文件#include#include#include#include#define uchar unsigned char#define uint unsigned int#define RdCommand 0 x01/定义 ISP 的操作命令#define PrgCommand 0 x02#define EraseCommand 0 x03#define Error 1#define Ok 0#define WaitTime 0 x01 /定义 CPU 的等待时间 sfr ISP_DATA=0 xe2;/寄存器申明 sfr ISP_ADDRH=0 xe3;sfr ISP_A

8、DDRL=0 xe4;sfr ISP_CMD=0 xe5;sfr ISP_TRIG=0 xe6;精品文档 sfr ISP_CONTR=0 xe7;sbit lcden=P11;/定义 1602 能使端和数据命令选择端 sbit lcdrs=P10;/*sbit lcden=P34;/TX 开发板调试 sbit lcdrs=P35;sbit dula=P26;sbit wela=P27;*/sbit mode=P12;/定义功能键 sbit led=P15;/定义 1602 背光 K uchar time;/定义中断计时时间 char cnumf14;char csign5=.,+,-,*,/;

9、/定义整数,小数,符号数组 float num1,num2;/定义运算数字 uchar key_value,sign_value=11,fun_value=1;/定义键值,符号值,功能值 void delay(uint z);/函数声明 uchar keyscan();void function_choose();void write_com(uchar com);void write_data(uchar date);void memoryread();精品文档 float num_input();float num_input0();void num_output(float num);v

10、oid display(int s,char str16,uchar l);/*=延时函数=*/void delay(uint z)/延时 z 毫秒 uint x,y;for(x=z;x0;x-)for(y=110;y0;y-);/*=键盘扫描函数=*/uchar keyscan()uchar num=100,temp;TR0=1;/计时开始 while(num=100)/只有有键按下的时候才跳出 P3=0 xfe;temp=P3;temp=temp&0 xf0;/扫描 mode 键 精品文档 if(mode=0)delay(10);if(mode=0)delay(500);/按下 500 毫

11、秒 if(mode=0)while (!mode);/等待释放 memoryread();/读取记忆 else/短按 while (!mode);function_choose();/功能选择 ISP_CONTR=0X20;/系统复位 /扫描矩阵键盘 while(temp!=0 xf0)delay(5);temp=P3;精品文档 temp=temp&0 xf0;while(temp!=0 xf0)temp=P3;switch(temp)case 0 xee:num=7;break;case 0 xde:num=8;break;case 0 xbe:num=9;break;case 0 x7e:

12、num=11;break;while(temp!=0 xf0)temp=P3;temp=temp&0 xf0;精品文档 P3=0 xfd;temp=P3;temp=temp&0 xf0;while(temp!=0 xf0)delay(5);temp=P3;temp=temp&0 xf0;while(temp!=0 xf0)temp=P3;switch(temp)case 0 xed:num=4;break;case 0 xdd:num=5;break;case 0 xbd:num=6;break;case 0 x7d:num=12;break;精品文档 while(temp!=0 xf0)te

13、mp=P3;temp=temp&0 xf0;P3=0 xfb;temp=P3;temp=temp&0 xf0;while(temp!=0 xf0)delay(5);temp=P3;temp=temp&0 xf0;while(temp!=0 xf0)temp=P3;switch(temp)case 0 xeb:num=1;break;精品文档 case 0 xdb:num=2;break;case 0 xbb:num=3;break;case 0 x7b:num=13;break;while(temp!=0 xf0)temp=P3;temp=temp&0 xf0;P3=0 xf7;temp=P3

14、;temp=temp&0 xf0;while(temp!=0 xf0)delay(5);temp=P3;temp=temp&0 xf0;精品文档 while(temp!=0 xf0)temp=P3;switch(temp)case 0 xe7:num=0;break;case 0 xd7:num=10;break;case 0 xb7:num=15;break;case 0 x77:num=14;break;while(temp!=0 xf0)temp=P3;temp=temp&0 xf0;精品文档 led=0;/亮屏 time=0;/有键按下时清零计时 return num;/*=数据储存部

15、分=*/打开 ISP,IAP 功能 void ISP_IAP_enable(void)EA=0;/关中断 ISP_CONTR =ISP_CONTR&0 x18;/0001,1000 ISP_CONTR =ISP_CONTR|WaitTime;/写入硬件延时 ISP_CONTR =ISP_CONTR|0 x80;/ISPEN=1 /关闭 ISP,IAP 功能 void ISP_IAP_disable(void)ISP_CONTR=ISP_CONTR&0 x7f;/ISPEN =0 ISP_TRIG=0 x00;EA =1;/开中断 /公用的触发代码 精品文档 void ISPgoon(void)

16、ISP_IAP_enable();/打开 ISP,IAP 功能 ISP_TRIG=0 x46;/触发 ISP_IAP命令字节 1 ISP_TRIG=0 xb9;/触发 ISP_IAP命令字节 2 _nop_();/读取数据 unsigned char byte_read(unsigned int byte_addr)ISP_ADDRH =(unsigned char)(byte_addr 8);/地址赋值 ISP_ADDRL =(unsigned char)(byte_addr&0 x00ff);ISP_CMD =ISP_CMD&0 xf8;/清除低 3 位 ISP_CMD =ISP_CMD|

17、RdCommand;/写入读命令 ISPgoon();/触发执行 ISP_IAP_disable();/关闭 ISP,IAP 功能 return (ISP_DATA);/返回读到的数据 /扇区擦除 void SectorErase(unsigned int sector_addr)unsigned int iSectorAddr;精品文档 iSectorAddr =(sector_addr&0 xfe00);/取扇区地址 ISP_ADDRH =(unsigned char)(iSectorAddr 8);ISP_ADDRL =0 x00;ISP_CMD=ISP_CMD&0 xf8;/清空低 3

18、 位 ISP_CMD=ISP_CMD|EraseCommand;/擦除命令 3 ISPgoon();/触发执行 ISP_IAP_disable();/关闭 ISP,IAP 功能 /写入数据 void byte_write(unsigned int byte_addr,unsigned char original_data)ISP_ADDRH =(unsigned char)(byte_addr 8);/取地址 ISP_ADDRL =(unsigned char)(byte_addr&0 x00ff);ISP_CMD =ISP_CMD&0 xf8;/清低 3 位 ISP_CMD =ISP_CMD

19、|PrgCommand;/写命令 2 ISP_DATA =original_data;/写入数据准备 ISPgoon();/触发执行 ISP_IAP_disable();/关闭 IAP 功能 /储存浮点数函数 void memory(float num)精品文档 char i=13;float a;a=num;sprintf(cnumf,%14.6f,a);while (cnumfi=48|cnumfi=46)i=i-1;if(cnumfi+1=46)break;/将浮点数拆分成数组并去除尾数的 0(或小数点)SectorErase(0 x2200);/擦除扇区 byte_write(0 x2

20、200,i);/储存位数 for(;i=0;i-)byte_write(0 x2201+i,cnumfi);/储存数组 /读取浮点数函数 void memoryread()char i;i=byte_read(0 x2200);/读取位数 write_com(0 x01);/清屏 display(0 x80,memory number ,16);精品文档 write_com(0 x80+0 x4f);/定位指针为第二行第 16 位(最后一位)write_com(0 x0c);/不显示光标 write_com(0 x04);/写一个字符指针减一 for(;i=0;i-)/读取数组 cnumfi=

21、byte_read(0 x2201+i);write_data(cnumfi);write_com(0 x06);/还原 1602 设置:写一个字符指针加一 /*=1602 相关函数=*/写指令 void write_com(uchar com)lcdrs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;/写数据 精品文档 void write_data(uchar date)lcdrs=1;P0=date;delay(5);lcden=1;delay(5);lcden=0;delay(5);/清除某行函数 void clear(int s)/光标起始位(

22、第一行 0 x80,第二行 0 x80+0 x40)uchar i=0;write_com(s);/定位指针位置 write_com(0 x06);write_com(0 x0c);/不显示光标 while(i=16)write_data(32);i+;/输入 16 个空格 精品文档 write_com(s);/指针归位 write_com(0 x0e);/显示光标 /显示字符函数 void display(int s,char str16,uchar l)/定义显示起点,显示的数组,显示字符的个数 int j=0;write_com(s);write_com(0 x06);for(j=0;j

23、l;j+)write_data(strj);/*=初始化函数=*/void init()lcden=0;/写命令模式 num1=0;num2=0;/数据清零 led=0;/亮屏 write_com(0 x38);/设置 16*2 显示,5*7 点阵,8 位数字据接口 write_com(0 x0e);/光标不闪烁 write_com(0 x06);/写字符后指针自动加一 精品文档 write_com(0 x01);/显示清零,指针清零 write_com(0 x80);/指针定位为第一行首位 TMOD=0 x01;/开定时器 T0,并设置为 16 位定时模式,且启动仅受 TR0 控制 TH0=

24、0 x4c;TL0=0 x00;/装入初值 65536-46080,初值=216-计数个数 N,N=(计数时长*晶振频率/12)(50ms)EA=1;ET0=1;/打开 T0 中断允许 /*=数字输入函数=*/数字输入函数 float num_input()float num=0;char key,i=1;char sign=1;key=keyscan();if(key=12)sign=-1;write_data();write_data(-);精品文档 key=keyscan();/解决负数运算 if(key10)num=0;while(key10)num=num*10+key;write_

25、data(key+0 x30);key=keyscan();if (key=10)write_data(csign0);for(key=keyscan();key10;key=keyscan()num=num+key/pow(10,i);write_data(key+0 x30);i+;if(sign=11&key=14)/如果按下运算符 write_data(csignkey-10);/显示运算符 key_value=key;/记录运算符 num=sign*num;return num;/数字输入函数 0 float num_input0()float num=num2;/无操作返回 num

26、2 char key,i=1;key=keyscan();clear(0 x80);/清除第一行 if(key10)num=0;while(key10)num=num*10+key;write_data(key+0 x30);key=keyscan();精品文档 if (key=10)write_data(csign0);for(key=keyscan();key=11&key=9999999|num=0;j-)/显示数字 num,不显示尾数的零(如 12.00000 显示为 12)write_data(cnumfj);write_com(0 x06);/还原 1602 设置:写一个字符指针加

27、一 /*=功能选择函数=*/void function_choose()精品文档 uchar j=0;while(1)switch(j%2)/页面选择 case 0:display(0 x80,1 calculate +,16);/显示菜单 display(0 x80+0 x40,2 advance +,16);/显示菜单 display(0 x80+0 x40,4 information=200)/1min 灭屏 led=1;/*=计算函数=*/void calculate()num2=num_input0();/获取 num2,记录运算符,并判断是否为连续运算 while(key_valu

28、e=11)/如果没有输入等号 sign_value=key_value;/转移运算符的符号值 num1=num_input();/获取 num1,记录下一个运算符 switch(sign_value)case 11:num2=num2+num1;break;精品文档 case 12:num2=num2-num1;break;case 13:num2=num2*num1;break;case 14:num2=num2/num1;break;/计算,将结果赋给 num2 if(key_value=15)/如果符号为等号 num_output(num2);/显示运算结果 write_com(0 x8

29、0+0 x40);write_data(=);/显示等号 /*=高级计算=*/void advanced()uchar k=0;float x=0,y=0;float z=0;while(1)精品文档 display(0 x80,1xy 3cos 5ln +,16);/显示菜单 display(0 x80+0 x40,2sin 4tan 6ra 0&ky)init();display(0 x80+0 x40,Error ,16);while(1);do z=rand()%(int)x-(int)y-1)+(int)x;num_output(z);k=keyscan();while(k=15);

30、continue;case 2:display(0 x80,sin ,4);x=num_input();/获取 x z=sin(x);break;case 3:精品文档 display(0 x80,cos ,4);x=num_input();/获取 x z=cos(x);break;case 4:display(0 x80,tan ,4);x=num_input();/获取 x z=tan(x);break;case 5:display(0 x80,ln ,3);x=num_input();/获取 x z=log(x);break;write_data(=);/显示等号 num_output(

31、z);keyscan();/等待任意键 精品文档 /*=解方程函数=*/void equation()long i=0;float a=0,b=0;float x=20;/定义方程中的变量 a b x init();write_data(a);write_data(=);a=num_input();/显示并获取 a write_com(0 x80+0 x40);write_data(b);write_data(=);b=num_input();/显示并获取 b if(floor(a)+floor(b)=fabs(a)+fabs(b)&a*b!=0)/如果 a,b 均为正整数 if(a=1&b=

32、1)x=0;for(;fabs(a*x+exp(x)-b)1e-5;i+)/设置精度为 10(5)x=x-(a*x+exp(x)-b)/(a+exp(x);/牛顿法主要循环 x1=x0-f(x)/f(x)if(i=1000)/1000 次迭代没有达到精度就跳出 break;精品文档 write_com(0 x01);/清屏 num_output(x);/第二行显示方程的解 display(0 x80+0 x40,x=,2);/显示x=else write_com(0 x01);/清屏 display(0 x80+0 x40,Error ,16);/报错 while(1);/程序停止 displ

33、ay(0 x80,any key continue,16);/第一行显示any key continue keyscan();/等待任意键 /*=主函数=*/void main()init();while(1)fun_value=byte_read(0 x2000);/读取功能值 switch(fun_value)精品文档 case 1:calculate();break;case 2:advanced();break;case 3:equation();break;case 4:display(0 x80,made by fcy ,16);display(0 x80+0 x40,2016-10-26 ,16);keyscan();break;default:SectorErase(0 x2000);/擦除扇区 byte_write(0 x2000,1);/储存功能值

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 应用文书 > 工作报告

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁