简易计算器设计报告样本

合集下载

简易计算器的设计报告

简易计算器的设计报告

1. 方案根据计算器的功能要求,选择AT89C51为主控机,通过扩展必要的外围接口电路,实现对计算器的设计。

外部主要由4*4矩阵键盘和一个液晶显示屏构成,内部由一块AT89C51单片机构成。

计算器电路包括四个部分:选用LCD作为显示部分,矩阵键盘作为输入部分,运算模块,单片机控制部分。

模块图如图1.2所示。

图1.2 方案二模块图1.1整体设计根据简易计算器的功能和指标要求,本设计系统选用MCS-51系列单片机AT89C51为主控机。

通过扩展必要的外围接口电路,实现对简易计算器的设计。

计算器电路包括三个部分:显示电路、4*4键扫描电路、单片机微控制电路。

具体设计如下:(1)由于要设计的是简单的计算器,可以进行四则运算,为了得到较好的显示效果,采用七段数码管显示数据和结果。

(2)另外键盘包括数字键(0~9)、符号键(+、-、×、÷)、清除键和等号键,故只需要16 个按键即可。

(3)执行过程:开机显示零,等待键入数值,当键入数字,通过LCD显示出来,当键入+、-、*、/运算符,计算器在内部执行数值转换和存储,并等待再次键入数值,当再键入数值后将显示键入的数值,按等号就会在LCD上输出运算结果。

(4)错误提示:当计算器执行过程中有错误时,会在LCD上显示相应的提示,如:当输入的数值或计算得到的结果大于计算器的表示范围时,计算器会在LCD上提示溢出;当除数为0时,计算器会在七段数码管上提示错误。

线路原理框图如图1.3所示。

图1.3 线路原理框图2电路设计原理2.1键盘接口电路计算器输入数字和其他功能按键要用到很多按键,如果采用独立按键的方式,在这种情况下,编程会很简单,但是会占用大量的I/O 口资源,因此在很多情况下都不采用这种方式,而是采用矩阵键盘的方案。

矩阵键盘采用四条I/O 线作为行线,四条I/O 线作为列线组成键盘,在行线和列线的每个交叉点上设置一个按键。

这样键盘上按键的个数就为4×4个。

vb 简易计算器实验报告

vb 简易计算器实验报告

简易计算器课程设计报告一、实验目的:模拟计算器的功能。

系统启动后, 先清屏, 再在显示屏右侧显示0字样, 系统仅接收数字键、加减乘除键、退格键、C键(复位)、=或回车键、ESC键(退出系统)作为有效按键, 其余按键不响应。

按键后屏幕显示效果要达到一般计算器显示屏的同样效果。

不要求设计一般计算器上都具有的M功能。

二、实验设计内容及思想:首先, 创建一个主体框架: 建立程序的主要界面后, 系统自动生成界面的主要窗口生成代码。

对于每个按钮的的代码段中, 分别添加事件触发的处理代码。

分别设立三个显示屏, 第一个显示屏作为“被加数”框, 第二个显示屏作为“加数”框, 第三个显示屏则作为输出框。

四则运算时直接采用计算表达式。

所以, 优先级和运算规则皆宜考虑在内。

在进行除法运算时, 若遇到除数为0, 则运用条件语句执行, 并在输出显示屏上输出“E”。

三角函数、指数、对数、整除、取余等运算, 也是运用类似手法。

考虑到计算器的操作简便性, 所以加入了复位和退出按钮。

三、源程序文件:Private Sub Command1_Click()Dim x As IntegerDim y As Integerx = Text1.Texty = Text2.TextText3.Text = x + yEnd SubPrivate Sub Command10_Click()Dim x As Integerx = Text1.TextText3.Text = Cos(x)End SubPrivate Sub Command11_Click()Dim x As Integerx = Text1.TextText3.Text = Tan(x)End SubPrivate Sub Command12_Click()Dim x As Integerx = Text1.TextText3.Text = Atn(x)End SubPrivate Sub Command13_Click() Dim x As IntegerDim y As Integerx = Text1.Texty = Text2.TextText3.Text = x ^ yEnd SubPrivate Sub Command14_Click() Dim x As Integerx = Text1.TextIf x <= 0 ThenText3.Text = "输入错误"ElseText3.Text = Log(x)End IfEnd SubPrivate Sub Command15_Click() Text3.Text = "此按钮仅作装饰用" End SubPrivate Sub Command2_Click() Dim x As IntegerDim y As Integerx = Text1.Texty = Text2.TextText3.Text = x - yEnd SubPrivate Sub Command3_Click() Dim x As IntegerDim y As Integerx = Text1.Texty = Text2.TextText3.Text = x * yEnd SubPrivate Sub Command4_Click() Dim x As IntegerDim y As Integerx = Text1.Texty = Text2.TextIf y = 0 ThenText3.Text = "E"ElseText3.Text = x / yEnd IfEnd SubPrivate Sub Command5_Click()Dim x As IntegerDim y As Integerx = Text1.Texty = Text2.TextText3.Text = x \ yEnd SubPrivate Sub Command6_Click()Dim x As IntegerDim y As Integerx = Text1.Texty = Text2.TextText3.Text = x Mod yEnd SubPrivate Sub Command7_Click()Text1.Text = ""Text2.Text = ""Text3.Text = " 0" End SubPrivate Sub Command8_Click()EndEnd SubPrivate Sub Command9_Click()Dim x As Integerx = Text1.TextText3.Text = Sin(x)End Sub源代码截图:四、运行结果演示: 加法演示:减法演示: 乘法演示:除法演示:能够整除: 不能够整除:除数为零:。

简单计算器实验报告

简单计算器实验报告

简单计算器实验报告简单计算器实验报告引言:在现代社会,计算器已经成为人们生活中不可或缺的工具之一。

无论是在学校、办公室还是家庭,计算器都扮演着重要的角色。

本实验旨在设计和构建一个简单的计算器,并通过实验验证其功能和准确性。

实验步骤:1. 设计计算器的外观和功能:我们首先对计算器进行了外观设计,选择了简洁、易于使用的界面。

然后确定了计算器的基本功能,包括加法、减法、乘法和除法。

2. 选择合适的硬件和软件:为了构建计算器,我们选择了合适的硬件和软件。

硬件方面,我们选用了一块Arduino开发板、液晶显示屏和按键。

软件方面,我们使用了Arduino编程语言。

3. 连接硬件和编写代码:我们将液晶显示屏和按键与Arduino开发板连接起来,并编写了相应的代码。

代码中包括了计算器的逻辑运算和界面显示。

4. 测试计算器的功能和准确性:在完成硬件连接和代码编写后,我们对计算器进行了测试。

我们输入了一系列的算术表达式,包括简单的加减乘除运算,以及复杂的多步运算。

通过与手动计算的结果进行对比,我们验证了计算器的功能和准确性。

实验结果:经过多次测试,我们的计算器表现出了良好的功能和准确性。

无论是简单的加法还是复杂的多步运算,计算器都能够正确地给出结果。

液晶显示屏清晰地显示了算术表达式和计算结果,而按键的响应速度也非常迅速。

讨论:虽然我们的计算器在功能和准确性方面表现出色,但仍有一些改进的空间。

首先,我们可以增加更多的功能,如开方、求余等。

其次,我们可以改进界面设计,使其更加美观和易于使用。

此外,我们还可以考虑加入更强大的处理器和更大的内存,以提高计算器的性能。

结论:通过本次实验,我们成功设计和构建了一个简单的计算器,并验证了其功能和准确性。

计算器在各种算术运算中表现出色,并且具有清晰的界面和快速的响应速度。

然而,我们也意识到计算器仍有改进的空间,包括增加更多功能和改进界面设计。

总的来说,本次实验为我们深入了解计算器的原理和构造提供了宝贵的经验。

简易计算器实验报告

简易计算器实验报告

简易计算器实验报告简易计算器实验报告引言:计算器是我们日常生活中常用的工具之一。

它可以帮助我们进行简单的数学运算,提高计算的效率。

在本次实验中,我们将设计并制作一台简易计算器,通过实践来掌握计算器的原理和工作原理。

实验目的:1. 了解计算器的基本原理和工作原理;2. 掌握计算器的设计和制作方法;3. 提高动手能力和创造力。

实验材料:1. 电路板;2. 按键;3. LED显示屏;4. 电容;5. 电阻;6. 电源。

实验步骤:1. 连接电路板和电源,确保电路板能够正常工作;2. 将按键连接到电路板上,用于输入数字和运算符;3. 连接LED显示屏,用于显示计算结果;4. 添加电容和电阻,用于控制电路的稳定性和电流;5. 调试电路,确保计算器能够正确运行。

实验结果:经过一番调试,我们成功制作出了一台简易计算器。

它可以进行基本的加减乘除运算,并且在LED显示屏上显示结果。

通过按键输入数字和运算符,我们可以进行各种运算,从而得到我们想要的结果。

这台计算器虽然简单,但是它的实用性和便携性都非常高。

实验分析:在本次实验中,我们主要学习了计算器的基本原理和工作原理。

计算器是通过按键输入数字和运算符,然后经过电路的计算和控制,最终在显示屏上显示结果。

在电路中,电容和电阻的作用是为了保证电路的稳定性和电流的控制。

通过这个实验,我们更加深入地了解了计算器的内部结构和工作原理。

实验总结:通过本次实验,我们成功制作了一台简易计算器,并且对计算器的原理和工作原理有了更深入的了解。

实验过程中,我们不仅提高了动手能力和创造力,还培养了解决问题的能力。

计算器作为一种常见的工具,它的设计和制作过程并不复杂,但是它的实用性和便携性却非常高,为我们的生活带来了很大的便利。

未来展望:通过这次实验,我们对计算器的原理和工作原理有了初步的了解。

在未来,我们可以进一步深入研究计算器的更高级功能和更复杂的电路设计。

同时,我们也可以将这种简易计算器的设计思想应用到其他领域,如电子设备、机器人等,从而提高我们的创造力和创新能力。

简易计算器报告

简易计算器报告

tong datain[35..0]
dataout[27..0]
inst9
XOR inst19
模块说明: 当乘法符号的上升沿的时候读入反馈的结果 (包括数据及正负号) 并输出到
data1 、data1_pn; 当乘法符号的下降沿的时候读入数据 (包括数据及正负号) 并输出到 data2 、
data2_pn 。并进行计算,结果的数据由乘法器计算得到;结果的正负号即为两个 相乘数据的正负号取异或。
data1_pn:outstd_logic; data2_pn:outstd_logic
); end entity mul; architecturebehaveof mul is signal temp1:std_logic; signal temp2:std_logic; begin process(reset,clk) begin if(reset='0')then
data2_pn 。并进行计算,结果的数据由除法器计算得到;结果的正负号即为两个 相除数据的正负号取异或。
数据为保留两位小数,输出的当成被除数的数乘上 100。
3.乘或除数据选择输出模块:
7
tt
reset pn1 pn2 res1[27..0] res2[27..0] clk1 clk2
inst6
6.加减运算模块:
add
clk reset data[27..0] data_pn
dout[27..0] dout_pn
inst11
模块说明:
由于上一级已考虑加减情况,此模块只需实现加法运算。 A+B 有四种情况:
1、A>0,B>0 输出数据 A+B,正负号为正

简单计算器设计报告

简单计算器设计报告

简单计算器设计报告045一、基本功能描述通过文本编辑框实现基本整数的加减乘除运算二、设计思路如下图是整个程序进行的流程图, 基本方法是在ItemText文本编辑框输入字符, 程序对字符进行判断, 若输入不是数字则提示错误。

输入正常时, 通过下拉框ComboBox_InsertString选择相应运算符。

点击等号IDC_OK, 即可得出运算结果。

操作简便, 算法简单。

三、软件设计1、设计步骤打开Microsoft Visual C++ 6.0,在文件中点击新建, 在弹出框内选择MFC AppWizard[exe]工程, 输入工程名zhoutong及其所在位置, 点击确定将弹出MFC AppWizard-step 1对话框, 选择基本对话框, 点击完成MFC AppWizard就建立了一个基于对话窗口的程序框架四、主要程序分析1.字符判定函数BOOL IsInt(TCHAR*str) {int i=atoi(str);TCHAR strtemp[256]; wsprintf(strtemp,"%i",i); if(strcmp(str,strtemp)!=0) {return FALSE;}Else{return TRUE;}}3、该函数通过atoi把文本编辑框读取的字符转换为数字, 再通过wsprintf把转换数字转换为字符, 通过strcmp比较原字符和转换得来的字符。

如相同返回true,不通则返回false.4、运算符选择程序BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam){HWND hwndComboOP=GetDlgItem(hwnd,IDC_COMBOOP);ComboBox_InsertString(hwndComboOP,-1,TEXT("+"));ComboBox_InsertString(hwndComboOP,-1,TEXT("-"));ComboBox_InsertString(hwndComboOP,-1,TEXT("*"));ComboBox_InsertString(hwndComboOP,-1,TEXT("/"));return TRUE;}通过ComboBox_InsertString插入要输入的运算符5、主程序字符获取TCHAR str1[256];TCHAR str2[256];GetDlgItemText(hwnd,IDC_EDIT1,str1,sizeof(str1));GetDlgItemText(hwnd,IDC_EDIT2,str2,sizeof(str2));调用子程序判断输入是否为数字if(IsInt(str1)==FALSE){MessageBox(hwnd,TEXT("第一个数不是合法整数"),TEXT("错误"),MB_OK|MB_ICONERROR); return;}if(IsInt(str2)==FALSE){MessageBox(hwnd,TEXT("第二个数不是合法整数"),TEXT("错误"),MB_OK|MB_ICONERROR); return;}将输入字符转换为数字int i1=atoi(str1);int i2=atoi(str2);int i3=0;获取运算符HWND hwndComboOp=GetDlgItem(hwnd,IDC_COMBOOP);int curIndex=ComboBox_GetCurSel(hwndComboOp);运算switch(curIndex){case 0:{i3=i1+i2;}break;case 1:{i3=i1-i2;}break;case 2:{i3=i1*i2;}break;case 3:{i3=i1/i2;}break;}运算结果转换为字符TCHAR str3[256];itoa(i3,str3,10);输出运算结果SetDlgItemText(hwnd,IDC_EDIT3,str3);}break;退出程序case IDC_EXIT:{exit(0);}break;五、结果分析六、该计算器只能实现简单的整数运算, 不能对小数分数进行运算。

51单片机简易计算器设计报告

51单片机简易计算器设计报告

51单片机简易计算器设计报告
本文将介绍51单片机简易计算器的设计报告。

该计算器通过
16位的LCD显示屏实现了基本计算功能,包括加、减、乘、除、取反、开方等。

1. 硬件设计
该计算器的核心部件是STC89C52单片机。

STC89C52是一种
高性能、低功耗的8位单片机,拥有8KB的Flash程序存储器和128字节的内部RAM,可提供多种功能和通讯接口。

通过
I/O口与LCD模块通讯,实现输出功能。

该计算器使用16位的LCD显示屏,显示范围为-99.99~99.99,共有6个数字位。

显示屏使用了ST7920控制器,可通过串行、并行等多种方式控制。

2. 软件设计
该计算器的软件设计主要包括三部分:键盘扫描,计算功能和LCD显示。

键盘扫描:该计算器采用4x5矩阵键盘,通过程序对键盘进行扫描,实现对不同按键的检测。

计算功能:该计算器可以实现基本的四则运算、取反、开方等功能。

对于四则运算,通过栈来实现计算,将运算符压入栈中,然后将操作数从栈中取出进行计算。

LCD显示:该计算器使用16位的LCD显示屏,通过程序控制数据和命令的传输,将计算结果显示在LCD屏幕上。

3. 总结
通过对51单片机简易计算器的设计报告,可以看出该计算器实现了基本的计算功能,通过硬件设计和软件设计相结合,将计算器的功能实现得十分完整。

该计算器的设计初步掌握了51单片机的应用,有助于后续项目的开展。

简易计算器设计报告

简易计算器设计报告

1602液晶显示计算器设计报告2016年10月一、摘要计算器是人们的日常生活最常见的电子产品之一,应用广泛,功能强大。

本次我们小组设计制作了一个简易计算器,能够在-9999999~9999999的范围内进行整数、小数的四则运算运算,并求解ax+e x=b类型方程。

该计算器以AT89C51单片机芯片作为核心,采4*4矩阵键盘作为输入,将数据输入单片机内部处理,用LCD1602工业字符液晶显示出运算和结果。

进行显示。

经过检验能够实现预设功能,具有很高的实用价值。

关键词:单片机;简易计算器;AT89C51;LCD1602。

本设计具有以下功能:1、能够实现-9999999~9999999范围内整数,小数的基本运算(超出范围后报错)。

2、储存运算结果,掉电不丢失。

3、实现6位及以上有效数字。

4、解ax+e x=b方程。

5、能够连续运算,即上次运算结果作为下次的输入。

6、能够在一次操作中连续运算。

二、方案论证方案描述:方案一:以51单片机为核心,4*4矩阵键盘输入,数码管显示输入数字和运算结果。

方案二:以51单片机为核心,4*4矩阵键盘输入,LCD1602显示输入数字和运算结果。

方案比较与选择:LCD1602作为一个成熟的产品,使用简单,模式固定,便于移植到各种类型的程序,又有微功耗、体积小、显示内容丰富超薄轻巧等优点,而数码管虽然亮度高,但是操作复杂、能耗高、且不能显示符号,本设计对亮度要求不是特别高,故采用方案二。

三、解方程算法ax+e x=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. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1602液晶显示计算器设计报告10月一、摘要计算器是人们寻常生活最常用电子产品之一,应用广泛,功能强大。

本次咱们小组设计制作了一种简易计算器,可以在-9999999~9999999范畴内进行整数、x=b类型方程。

该计算器以AT89C51单片机芯片小数四则运算运算,并求解ax+e作为核心,采4*4矩阵键盘作为输入,将数据输入单片机内部解决,用LCD1602工业字符液晶显示出运算和成果。

进行显示。

通过检查可以实现预设功能,具备很高实用价值。

核心词:单片机;简易计算器;AT89C51;LCD1602。

本设计具备如下功能:1、可以实现-9999999~9999999范畴内整数,小数基本运算(超过范畴后报错)。

2、储存运算成果,掉电不丢失。

3、实现6位及以上有效数字。

4、解ax+e x=b方程。

5、可以持续运算,即上次运算成果作为下次输入。

6、可以在一次操作中持续运算。

二、方案论证方案描述:方案一:以51单片机为核心,4*4矩阵键盘输入,数码管显示输入数字和运算成果。

方案二:以51单片机为核心,4*4矩阵键盘输入,LCD1602显示输入数字和运算成果。

方案比较与选取:LCD1602作为一种成熟产品,使用简朴,模式固定,便于移植到各种类型程序,又有微功耗、体积小、显示内容丰富超薄轻巧等长处,而数码管虽然亮度高,但是操作复杂、能耗高、且不能显示符号,本设计对亮度规定不是特别高,故采用方案二。

三、解方程算法ax+e x=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、复位电路S17 1K2、键盘电路3、晶振电路4、1602显示屏1602 5、STC89C52电路6、电源电路系统软件与流程图:1)、总流程图使用阐明:1、接入电源,按下电源开关后进入上次关闭时界面(计算或解方程界面)。

2、计算时,输入数字和符号,按等号键输出成果,超过运算范畴则报错,按AC 键退出;3、解方程时,先输入参数a,b,按等号键确认,后输出ax+e x=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 -10#include<reg52.h> //单片机头文献#include<math.h>#include<stdio.h>#include<stdlib.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define RdCommand 0x01 //定义ISP操作命令#define PrgCommand 0x02#define EraseCommand 0x03#define Error 1#define Ok 0#define WaitTime 0x01 //定义CPU等待时间sfr ISP_DATA=0xe2;//寄存器声明sfr ISP_ADDRH=0xe3;sfr ISP_ADDRL=0xe4;sfr ISP_CMD=0xe5;sfr ISP_TRIG=0xe6;sfr ISP_CONTR=0xe7;sbit lcden=P1^1;//定义1602能使端和数据命令选取端sbit lcdrs=P1^0;sbit lcden=P3^4; //TX开发板调试sbit lcdrs=P3^5;sbit dula=P2^6;sbit wela=P2^7;*/sbit mode=P1^2; //定义功能键sbit led=P1^5; //定义1602背光Kuchar time; //定义中断计时时间char cnumf[14];char csign[5]={'.','+','-','*','/'}; //定义整数,小数,符号数组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);void display(int s,char str[16],uchar l);/*===========延时函数===========*/void delay(uint z)//延时z毫秒uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/*===========键盘扫描函数=========*/ uchar keyscan(){uchar num=100,temp;TR0=1;//计时开始while(num==100)//只有有键按下时候才跳出{P3=0xfe;temp=P3;temp=temp&0xf0;//扫描mode键if(mode==0){delay(10);if(mode==0)delay(500);//按下500毫秒if(mode==0){while (!mode);//等待释放memoryread();//读取记忆}else//短按{while (!mode);function_choose();//功能选取ISP_CONTR=0X20;//系统复位}}//扫描矩阵键盘while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xee:num=7;break;case 0xde:num=8;break;case 0xbe:num=9;break;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfd;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xed:num=4;break;break;case 0xbd:num=6;break;case 0x7d:num=12;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfb;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xeb:num=1;break;case 0xdb:num=2;break;case 0xbb:num=3;break;case 0x7b:num=13;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xf7;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xe7:num=0;break;case 0xd7:num=10;break;case 0xb7:num=15;break;case 0x77:num=14;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}}led=0;//亮屏time=0;//有键按下时清零计时return num;}/*=====================数据储存某些=========================*/ //打开ISP,IAP 功能void ISP_IAP_enable(void){EA = 0; //关中断ISP_CONTR = ISP_CONTR & 0x18;// 0001,1000 ISP_CONTR = ISP_CONTR | WaitTime; //写入硬件延时ISP_CONTR = ISP_CONTR | 0x80;//ISPEN=1}//关闭ISP,IAP 功能void ISP_IAP_disable(void){ISP_CONTR = ISP_CONTR & 0x7f; //ISPEN = 0ISP_TRIG = 0x00;EA = 1; //开中断}//公用触发代码void ISPgoon(void){ISP_IAP_enable(); //打开ISP,IAP 功能ISP_TRIG = 0x46; // 触发ISP_IAP命令字节1ISP_TRIG = 0xb9; // 触发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 & 0x00ff);ISP_CMD = ISP_CMD & 0xf8; //清除低3位ISP_CMD = ISP_CMD | RdCommand; // 写入读命令ISPgoon(); //触发执行ISP_IAP_disable(); //关闭ISP,IAP功能return (ISP_DATA); // 返回读到数据}//扇区擦除void SectorErase(unsigned int sector_addr){unsigned int iSectorAddr;iSectorAddr = (sector_addr & 0xfe00);//取扇区地址ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);ISP_ADDRL = 0x00;ISP_CMD = ISP_CMD & 0xf8; //清空低3位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 & 0x00ff);ISP_CMD = ISP_CMD & 0xf8; //清低3位ISP_CMD = ISP_CMD | PrgCommand; //写命令2ISP_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 (cnumf[i]==48||cnumf[i]==46){i=i-1;if(cnumf[i+1]==46)break;}//将浮点数拆提成数组并去除尾数0(或小数点)SectorErase(0x2200);//擦除扇区byte_write(0x2200,i);//储存位数for(;i>=0;i--)byte_write(0x2201+i,cnumf[i]);//储存数组}//读取浮点数函数void memoryread(){char i;i=byte_read(0x2200);//读取位数write_com(0x01);//清屏display(0x80," memory number ",16);write_com(0x80+0x4f);//定位指针为第二行第16位(最后一位)write_com(0x0c);//不显示光标write_com(0x04);//写一种字符指针减一for(;i>=0;i--)//读取数组{cnumf[i]=byte_read(0x2201+i);write_data(cnumf[i]);}write_com(0x06);//还原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)//光标起始位(第一行0x80,第二行0x80+0x40) {uchar i=0;write_com(s);//定位指针位置write_com(0x06);write_com(0x0c);//不显示光标while(i<=16){write_data(32);i++;}//输入16个空格write_com(s);//指针归位write_com(0x0e);//显示光标}//显示字符函数void display(int s,char str[16],uchar l)//定义显示起点,显示数组,显示字符个数{ int j=0;write_com(s);write_com(0x06);for(j=0;j<l;j++)write_data(str[j]);}/*==============初始化函数===============*/void init(){lcden=0;//写命令模式num1=0;num2=0;//数据清零led=0;//亮屏write_com(0x38);//设立16*2显示,5*7点阵,8位数字据接口write_com(0x0e);//光标不闪烁write_com(0x06);//写字符后指针自动加一write_com(0x01);//显示清零,指针清零write_com(0x80);//指针定位为第一行首位TMOD=0x01;//开定期器T0,并设立为16位定期模式,且启动仅受TR0控制TH0=0x4c;TL0=0x00;//装入初值65536-46080,初值=2^16-计数个数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(key<10){num=0;while(key<10){num=num*10+key;write_data(key+0x30);key=keyscan();}}if (key==10){ write_data(csign[0]);for(key=keyscan();key<10;key=keyscan()) {num=num+key/pow(10,i);write_data(key+0x30);i++;}}if(sign<0)write_data(')');if(key>=11&&key<=14)//如果按下运算符write_data(csign[key-10]);//显示运算符key_value=key;//记录运算符num=sign*num;return num;}//数字输入函数0float num_input0(){float num=num2;//无操作返回num2char key,i=1;key=keyscan();clear(0x80);//清除第一行if(key<10){num=0;while(key<10){num=num*10+key;write_data(key+0x30);key=keyscan();}}if (key==10){ write_data(csign[0]);for(key=keyscan();key<10;key=keyscan()){num=num+key/pow(10,i);write_data(key+0x30);i++;}}if(key>=11&&key<=14)write_data(csign[key-10]);key_value=key;return num;}/*==============数字输出函数==============*/void num_output(float num){int j=0,k=13;//定义输出字符个数memory(num);//储存成果clear(0x80+0x40);//清除第二行write_com(0x80+0x4f);//定位指针为第二行第16位(最后一位)write_com(0x0c);//不显示光标write_com(0x04);//写一种字符指针减一sprintf(cnumf,"%14.6f",num);//将要显示数字转化为数组if(num>=9999999||num<=-9999999)//超过范畴报错{clear(0x80);display(0x80+0x40," Error ",16);while(1);}while (cnumf[k]==48||cnumf[k]==46)//当数组不为0或小数点时{k=k-1;//记录实际数组长度(例如12.100000实际长度为4)if(cnumf[k+1]==46)//检测到小数点跳出break;}for(j=k;j>=0;j--)//显示数字num,不显示尾数零(如12.00000显示为12)write_data(cnumf[j]);write_com(0x06);//还原1602设立:写一种字符指针加一}/*==================功能选取函数==============*/void function_choose(){uchar j=0;while(1){switch(j%2)//页面选取{case 0:display(0x80,"1 calculate > +",16);//显示菜单display(0x80+0x40,"2 advance < -",16);break;case 1:display(0x80,"3 equation > +",16);//显示菜单display(0x80+0x40,"4 information< -",16);break;}fun_value=keyscan();//获取功能值switch(fun_value){case 11:j++;continue;case 12:j--;continue;case 1:break;case 2:break;case 3:break;case 4:break;default:continue;}break;}SectorErase(0x);//擦除扇区byte_write(0x,fun_value);//储存功能值}/*================中断计时================*/ void T0_time()interrupt 1{uchar t;int r;//随机种子TH0=0x4c;TL0=0x00;//重装初值以保证中断正常循环t++;//记录进入该中断次数r++;srand(r);if(t==6)//每0.30s time加一{time++;t=0;}if(time>=200)//1min 灭屏led=1;}/*===============计算函数================*/void calculate(){num2=num_input0();//获取num2,记录运算符,并判断与否为持续运算while(key_value<=14&&key_value>=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(0x80+0x40);write_data('=');//显示等号}}/*===============高档计算================*/ void advanced(){uchar k=0;float x=0,y=0;float z=0;while(1){display(0x80,"1x^y 3cos 5ln >+",16);//显示菜单display(0x80+0x40,"2sin 4tan 6ra <-",16);k=keyscan();//获取功能值if(k>0&&k<=6){ init();switch(k){case 1:{x=num_input();//获取xwrite_data('^');y=num_input();//获取yz=pow(x,y);}break;case 6:{display(0x80,"rand[",5);x=num_input();//获取xwrite_data(',');y=num_input();//获取ywrite_data(']');write_data('=');//显示等号if(x>y){init();display(0x80+0x40," Error ",16);while(1);}do{z=rand()%((int)x-(int)y-1)+(int)x;num_output(z);k=keyscan();}while(k==15);}continue;case 2:{display(0x80,"sin ",4);x=num_input();//获取xz=sin(x);}break;case 3:{display(0x80,"cos ",4);x=num_input();//获取xz=cos(x);}break;case 4:{display(0x80,"tan ",4);x=num_input();//获取xz=tan(x);}break;case 5:{display(0x80,"ln ",3);x=num_input();//获取xz=log(x);}break;}write_data('=');//显示等号num_output(z);}keyscan();//等待任意键}}/*===================解方程函数================*/ void equation(){ long i=0;float a=0,b=0;float x=20;//定义方程中变量a b xinit();write_data('a');write_data('=');a=num_input();//显示并获取awrite_com(0x80+0x40);write_data('b');write_data('=');b=num_input();//显示并获取bif(floor(a)+floor(b)==fabs(a)+fabs(b)&&a*b!=0)//如果a,b均为正整数{ if(a==1&&b==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(0x01);//清屏num_output(x);//第二行显示方程解display(0x80+0x40,"x=",2);//显示"x=''}else{write_com(0x01);//清屏display(0x80+0x40," Error ",16);//报错while(1);//程序停止}display(0x80,"any key continue",16);//第一行显示"any key continue" keyscan();//等待任意键}/*===================主函数================*/void main(){init();while(1){fun_value=byte_read(0x);//读取功能值switch(fun_value){case 1:calculate();break;case 2:advanced();break;case 3:equation();break;case 4:{display(0x80,"made by fcy ",16);display(0x80+0x40," -10-26 ",16);keyscan();}break;default: {SectorErase(0x);//擦除扇区byte_write(0x,1);}//储存功能值}}}。

相关文档
最新文档