计算器设计实验报告一、实验设计主要分工04009320文斌:算法设计,LCD显示。
04** 张希:界而(按钮控件)设计,文件内容读取。
共同调试、完善设计。
二、程序设计实现功能效果(1)支持整数、小数基本加减乘除运算;(2)有优先级的判别讣算。
优先级由高到低一次为括号运算、乘除运算、加减运算。
(3)支持键盘输入和触摸屏输入;(4)能读取指左目录下文本内容(内容为汁算表达式)并计算得出结果,将内容和结果显示在LCD上。
程序任务开始后,等待键盘或触摸屏的输入。
输入键有0~9数字键、+-*/()运算符、del 退格键、clear清屏键、read读指定目录文本内容并计算键、enter* =键、'小数点键。
每当有字符输入时,触摸屏相应键显示“AAA”,100ms后恢复原相应按键符号,同时LCD 屏幕上显示相应字符。
当输入'del'键时,屏幕显示去掉最后一位字符。
当输入'二'号后,得出计算结果,结果显示于表达式的下一行。
若是除零错误,则结果显示为"/0ERR0R!”。
若有非法字符(触摸点不能识别为设计按键符则视为非法字符),则结果输出为“Syntax Error!!”。
若表达式有运算符连续输入,则忽略前面的运算符,只取最后一位运算符计算,正常显示数字结果。
当输入* clear键时,情况显示区域。
当输入'read'键时,从指龙目录文本文件中读取表达式并计算。
将表达式内容和汁算结果显示在LCD上。
LCD显示界而如下:三、程序算法实现1、计算算法首先将输入的0为数字、+-*/ ()运算符的内容存储于一个全局变M cal [number]中,表达为中缀表达式。
用void str2repol ()函数,将输入字符串cal [number]转换成逆波兰表达式并存于全局数组char repol [maxs]中。
str2repol ()函数中缀表达式转成逆波兰后缀表达式算法如下:(1)首先构造一个运算符栈stack[maxs],此运算符在栈内遵循越往栈顶优先级越高的原则。
(2)读入一个中缀表示算术表达式str[maxs](注:str [i]=cal [i])<>(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出到repol[maxs]中。
(4)如果不是数字,该字符则是运算符,此时需比较优先关系。
步骤如下:若为左括号'(‘则压入运算符栈顶:若为其他运算符,则将该字符与运算符栈顶的运算符的优先关系相比较。
若该字符优先关系高于此时运算符栈顶的运算符,则将该运算符入栈。
若该字符优先关系不高于此时运算符栈顶的运算符,则将栈顶的运算符从栈中弹岀到repol[maxs],直到栈顶运算符的优先级低于当前运算符,将该字符入栈。
若为有括号'(',则弹出运算符栈顶的运算符至到repol[maxs],直到遇到左括号惮出并作废此开括号。
(5)重复上述操作。
中缀表达式转成逆波兰后缀表达式后,calculate ()函数计算后缀表达式的值算法如下: 用局部数组stackEtop]存放运算结果,top初值为0.(1)依次读入后缀表达式repolEmaxs]的字符ch,循环判断ch。
(2)若ch为运算符,则stack [top-1]与stack [top]做相应运算。
若运算只需单操作数则stack [top]做相应运算。
运算结果存F stack [top-1] <>然后top ---------。
否则ch为数字或小数点,为数字则d=*d+ch-' 0’ ; (d初始值为0,用丁-存放连续数字字符的数学值)。
遇小数点,d保持原值。
小数点后的数字符与小数点前的数字符一样处理,i记录小数点后的数字符个数。
最后d=d/(10*i), top++;stack[top]二d。
注:若str2repol()函数遇非法字符时,LCD输出相应提示,不调用calculate。
若calculate ()函数遇除零,则不做运算,LCD输出“/0ERR0R!”。
2、按键控件3、LCD输岀显示将字符串转为Unicode编码,在指定坐标处用文本模式显示字符串。
实现函数如下:void lcddisplay (char *str, int xx, int yy)PDC pdc;;err=l :将输入字符串转成逆波兰表达式:(6) void calculate():计算函数 功能:判别标志位err 。
为1则输出"Syntax Error ! ! M 并退出,否则继续-〉 判别逆波兰表达式内容;判别小数点-〉对数字做相应加权判别运算符-〉做相应运算调用double 型转字符串函数;调用字符串结果显示函数。
(7) char *doub2str(double d, char *str): double 型转字符串函数功能:判别d 是否为负数。
是则字符串首位置'-';d 取反,继续->判别d 小数部分是否为零。
是则整数转字符串,否则再继续一〉小数转字符串 将double 型数字转换成字符串类型:存储字符串并返回。
(8) void lcddi splay (char *str, int xx, in t yy):字符串显示函数功能:将字符串str[]显示在LCD 的指定坐标(xx, yy)o (int)d; 则标志位d(9)void redraw (char key):重画按钮函数功能:响应相应函数:重画相应按钮;延时100ms后恢复原按钮。
(10)char zb2key (int x, int y):坐标转按键函数功能:将触摸点坐标(X, y)转换成相应按键字符。
(11)void dcr (char key):退格、清屏、读文件函数功能:响应退格键,屏幕显示去除最后一位字符,当前输入后前一次输入置'\0':响应清屏键,清楚显示区域内容:响应读文件,调用读文件函数。
(12)void readfileO :读文件函数功能:读取指定目录文本文件:显示文本内容;计算内容(表达式)并显示。
(13)void clc 0 :清屏函数功能:清除显示区域内容。
六、完整【】程序itinclude "・・ /ucos-ii/" /* uC/OS interface */^include "・• /ucos~ii/add/,z^include "・・ /ucos"ii/add/,z^include "・・/inc/"#include<>#include "・・/inc/sys/"#include "・・/src/gui/"^include <>^include <>char TextFilename[]=7sys/ucos/f j/"; ・ \n〃);OSTaskCreate (Main.Task, (void *)0, (OS.STK *)&血in_Stack[STACKSIZET],Main_Task_Prio);OSAddTask_Init (1);LCD^printf(^Starting uCOS一II.・・\n");LCD_printf ('"Entering graph mode・・・ \n");LCD_ChangeMode (DspGraNIode);OSStart 0;return 0;}{ /*判定为数字*/repol[t]=ch:t++;ch二str[i];i++;}i—;repo 1 [t]二'二’;t++;/*if(ch<* O' &&ch>' 9' &&ch!='.'){er= error!;lcddisplay(er, xz, yz+20); ch=,二';}ch二str[i];i++;}while(top!=0) {repolLt]=stack[top];t++;top—;}repo 1 [t]二'二’;}void calculate 0{ /*计算后缀表达式的值*/double stack[maxs], dO, dl, dd; /*作为栈使用*/ unsigned int re;char ch, *restr, *rez;int t=l, top=0, counter, i ; /*t 为ex下标,top为stackT标*/ static int zh=l:ch=repol[t];t++;while(ch!=,二'){switch(ch){case ' +':stackCtop-l]=stack [top-1] +stack[top];top-一;break;,>case 一 :stack[top-1]=stack[top-1]-stack[top];top—;break;case ' *':stack Ltop-l]=stack [top-1] * stack [top];top—;break;case ' I' :if (stack[top] !=0)stackEtop~l]=stack[top-l]/stack[top:;else {printf C\n\t除零错误! \n"); lcddisplay("ERROR!", xz, yz);{if(ch!='・'&&zh=l){dl二*dl+ch」O';}if (ch==,・’)zh=O;if(ch!='・'&&zh=O){dO=*dO+ch-' O'; counter++;}ch=repolZt];t++;};d 一二(int)d;for(i=0;i<10;i++){d *二10;str[j++] = (int)d+'0‘;d 一二(int)d;}while (str[—j]==,0’); str[++j] = ' \0';}return str;}int readline(char* str, int n, FILE *pfile){int i;for (i=0; i<=n; i++){if (fread(str, 1, 1, pfile) !=1) return 0;if(*str==*\n ){str++;*str=0; return i;}str++;return i; }。