单片机C语言简易计算器

合集下载

单片机简易计算器程序代码

单片机简易计算器程序代码
{i=table1[num];fuhao=2;if(eq==0){ gz++;write_date(0x30+i);}
else{write_com(0x01);write_date(0x41) ;write_date(0x4e);write_date(0x53);write_date(0x30+i);a=daan;gz=gz+4;}
{fuhao=3;i=table1[num];if(eq==0){gz++; write_date(0x30+i);}
else {write_com(0x01);write_date(0x41) ;write_date(0x4e);write_date(0x53);write_date(0x30+i);a=daan;gz=gz+4;}
}//3表示乘号已按
if(g==1)
{g=0;gg(gz);fuhao=6;if(eq==0){gz=gz+3;write_date(0x43);write_date(0x4f);write_date(0x53);}
else{write_com(0x01);write_date(0x43);write_date(0x4f);write_date(0x53);write_date(0x4e);write_date(0x41) ;write_date(0x4e);write_date(0x53);b=daan;gz=gz+6;}
if(g==0)
{
write_com(0x01);
a=0;
b=0;
flag=0;
fuhao=0;
eq=0;
ad=0;bd=0;afd=0;bfd=0;

单片机(44按键与数码管制作的简易计算器,含原理图)

单片机(44按键与数码管制作的简易计算器,含原理图)
{
return (i+j*4);//返回键码
}
temp <<= 1;
}
}
}
#endif
#ifndef _wei_h_
#define_wei_h_
int mei;
int wei(int num1,int num2,int num3,int num4,int num5,int num6,int num7 )
if(P1 != 0xf0)//第三次判断有无按键按下
{
m = Keyscan();
if(0<=m && m<=9)
{
if(ch==1)
{Key_Value= Key_Value*10+m;}
else{Key_Value=m;ch=1;}
}
else
{
if(m==15)
{
Key_Value=0;n=0;l=0;
简易计算器(矩阵键盘+数码管)
#include <reg52.h>
#include <as.h>
#include<sd.h>
#include<math.h>
#include<df.h>
#define uint unsigned int
#define uchar unsigned char
long int Key_Value,n;
{mei=4;return mei;}
else
{
if(num6!=0)
{mei=3;return mei;}
else
{
if(num7!=0)
{mei=2;return mei;}

基于51单片机的简易计算器c程序

基于51单片机的简易计算器c程序

/*...............菜鸟一枚,不好勿喷→_→............................【简易计算器的功能简介】【时间紧,先做个简易的吧,复杂的算法太难,没那么多时间写【现在也不太会→_→】,以后再研究→_→】此程序是完全基于开发板的,可在板子上直接测试【程序跑飞的概率比较大,还不太明白是哪的问题】可实现总数小于等于九位【long int】的数字的加减乘除运算【每次只能进行一项】,可清楚修改输入的数据,由于键盘等因素显示【4X4】,没有小数点键,故无法直接进行小数运算,进行除法运算时,小数点后最多可保留6位,第7位进行四舍五入。

显示器采用1602,输入或修改时开光标并闪烁,输入数据超出9位,有警告提示,加上运算符总的输入不超过15位【超过10输入逻辑已经错误】。

显示结果时关光标【重复按下时结果不变】,显示结果后,也可对输入端进行修改,按下等于键再次显示结果。

2015/1 qq:1036894850 */#include"reg52.h"#include"stdio.h"#define uchar unsigned charsbit rs=P2^4;//lcd的控制线口sbit rw=P2^5;sbit ep=P2^6;uchar ip[15];//存输入的数据,15位【理论上10位就够了】'$'记运算符'*'记为负号uchar sign;//存运算符int k=0,equ=0,sk=0,ksk=0,sg=0;void write_data(uchar dat); //给1602写数据void write_com(uchar com);void lcdinit();void delay(int z);void warn();void key_deal(uchar key);void sdeal(uchar i);void key_sub_deal();void key_equ_deal();void key_del_deal();uchar scankey();void main(){uchar key=0xff;lcdinit(); //1602初始化,结果输出位显示0,数据输入位光标闪烁。

单片机简易计算器可算小数

单片机简易计算器可算小数

51单片机简易计算器#include<reg51.h>#include<math.h>#define uchar unsigned char #define uint unsigned int sbit beep=P2^3;sbit dula=P2^6;sbit wela=P2^7;sbit rw=P1^1;sbit rs=P1^0;sbit lcden=P2^5;void yunsuan();void keyinput(char s);void write_data(char ddata);void write_com(char command);void display(long a);void init();void dealerror();void dataoverflow();void welcome();char code table1[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};char code table2[]="789/456*123-.0=+";char j,k,temp,temp1,temp2,key,mchar,m,flag2=0,flag3=0; long x,y,num;int operators,input,iny;char error[5]="error";char overflow[8]="overflow";char welcome_[16]="welcome to use !";void delay(uint x)//延时{uint a,b;for(a=x;a>0;a--)for(b=10;b>0;b--);}void delay_ms(uint x)//延时{uint a,b;for(a=x;a>0;a--)for(b=110;b>0;b--);}void write_com(uchar com)//写命令{P0=com;rs=0;lcden=0;delay(10);lcden=1;delay(10);lcden=0;}void write_data(uchar date)//写数据{P0=date;rs=1;lcden=0;delay(10);lcden=1;delay(10);lcden=0;}long ming(int x){long m;switch(x){case 9:m=1000000000;return m;break; case 8:m=100000000;return m;break; case 7:m=10000000;return m;break; case 6:m=1000000;return m;break;case 5:m=100000;return m;break;case 4:m=10000;return m;break;case 3:m=1000;return m;break;case 2:m=100;return m;break;case 1:m=10;return m;break; case 0:m=1;return m;break; }}void display(long a){long d;int i,flag1=0,temp,c=-1;init();if(a<0){a=a*c;write_data('-');}for(i=9;i>=0;i--){d=ming(i);temp=a/d;a=a%d;if((temp==0)&&(flag1==0)) ;else{write_data(0x30+temp);flag1=1;}if(i==2){write_data('.');flag1=1;}}}void init()//LCD初始化{rw=0;dula=0;wela=0;write_com(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口delay(20);write_com(0x0e); //显示模式设置delay(20);write_com(0x06); //显示模式设置:光标右移,字符不移delay(20);write_com(0x01); //清屏幕指令,将以前的显示内容清除 delay(20);}void yunsuan() // 运算{if (iny){switch(operators){case 1:x=x+y;num=x;if(num<10000000000&&num>-10000000000){display(num);}elsedataoverflow();break;case 2:x=x-y;num=x;if(num<10000000000&&num>-10000000000) {display(num);}elsedataoverflow();break;case 3:x=x*y;num=x/100;if(num<10000000000&&num>-10000000000) {display(num);}elsedataoverflow();break;case 4:if (y==0)dealerror();else{if(y<100){x=x*100;y=y*100;}y=y/100;x=x/y;num=x;if(num<10000000000&&num>-10000000000) {display(num);}elsedataoverflow();}break;}y=0;}}void dealerror()//除数为0{int i=0;write_com(0x01);for(i=0;i<5;i++)write_data(error[i]);}void dataoverflow()//数值溢出{int i=0;write_com(0x01);for(i=0;i<8;i++)write_data(overflow[i]);}void welcome()//欢迎界面{int i=0;write_com(0x01);for(i=0;i<16;i++)write_data(welcome_[i]);}void keyinput(char s) //键盘输入{if(s<='9'&&s>='0') //判断按下的键是否为数值{if(flag3==0)num=num*10+100*(s-'0');elsenum=num*10+10*(s-'0');if(flag2==1){num=num/10;flag3=1;}if (operators>0){y=num;iny=1;}elsex=num;if(num<10000000000&&num>-10000000000) //当前数值是否超出限定范围display(num);elsedataoverflow();}elseswitch(s){case '.':/*iny=0;operators=0;*/flag2=1;break;case '=':write_data(table2[14]); delay(10);yunsuan();iny=0;operators=0;num=0;flag2=0;flag3=0;break;case '+':if (operators)yunsuan();operators=1;write_data(table2[15]); num=0;flag2=0;flag3=0;break;case '-':if (operators)yunsuan();operators=2;write_data(table2[11]); num=0;flag2=0;flag3=0;break;case '*':if (operators)yunsuan();operators=3;write_data(table2[7]); num=0;flag2=0;flag3=0;break;case '/':if (operators)yunsuan();operators=4;write_data(table2[3]); num=0;flag2=0;flag3=0;break;}}void main() //主函数{char i;char flag0=1;init();welcome();for(i=0;i<10;i++) delay_ms(100);init();while(1){P3=0xf0;temp1=P3;P3=0x0f;temp2=P3;temp=temp1|temp2; while(P3!=0x0f){beep=0;}beep=1;for(i=0;i<16;i++) {if(temp==table1[i]) {m=table2[i];flag0=0;}}if(flag0==0) {keyinput(m); flag0=1; }}}。

C语言实现简易计算器(可作加减乘除)

C语言实现简易计算器(可作加减乘除)

C语⾔实现简易计算器(可作加减乘除)C语⾔实现简易计算器(加减乘除)计算器作为课设项⽬,已完成答辩,先将代码和思路(注释中)上传⼀篇博客已增添、修改、整理⾄⽆错且可正常运⾏虽使⽤了栈,但初学者可在初步了解栈和结构语法后理解代码#include <stdlib.h>#include <stdio.h>#include <string.h>#define IsDouble 0#define IsChar 1//_______________________________________________________________________________________________________________________________________________________ //1.⽀持浮点数和字符的栈typedef struct {char * buffer;int typesize;int top;int max;} stack;stack * CreateStack(int max, int typesize);//创建⼀个栈void DestroyStack(stack *);//释放栈的空间void ClearStack(stack *);//清空栈int Push(stack *, void *);//⼊栈int Pop(stack *, void *);//出栈int GetSize(stack *s);//得到栈的⼤⼩int GetTop(stack *, void *);//找到栈顶int IsEmpty(stack *);//判断是否为空栈,空则下溢int IsFull(stack *);//判断栈是否已满,满则溢出stack * CreateStack(int max, int typesize){stack * s = (stack*)malloc(sizeof(stack));//为栈s malloc内存if (!s) return 0;//为结构中buffer元素malloc内存s->buffer = (char *)malloc(sizeof(char) * max * typesize);if (!s->buffer) return 0;//初始化结构中的栈顶,最⼤值,类型⼤⼩s->top = -1;s->max = max;s->typesize = typesize;return s;}void DestroyStack(stack* s){free(s->buffer);//先释放buffer的空间free(s);//在释放s的空间}void ClearStack(stack * s){s->top = -1;//清空栈(栈头位置归零)}int Push(stack * s, void * data){if (IsFull(s)) return 0;//如果栈已满则return 0,防⽌溢出//栈未满则将栈头移动打动下⼀位置,并将data中的元素拷⼊栈中buffer的第top位置s->top++;memcpy(s->buffer + s->top*s->typesize, data, s->typesize);//⼊栈成功return 1return 1;}int Pop(stack * s, void * data){if (IsEmpty(s)) return 0;//出栈判断栈是否为空,若为空则return 0//栈未空则将buffer中top位置的字符拷⼊data记录,并让栈头向前移动⼀个位置memcpy(data, s->buffer + s->top*s->typesize, s->typesize);s->top--;//成功则return 1return 1;}int GetSize(stack *s){return s -> top+1;//栈头位置+1得到⼤⼩}int GetTop(stack *s, void * data){if (IsEmpty(s)) return 0;//如果栈空return 0//栈不为空则将top位置的字符拷回data记录,得到栈头memcpy(data, s->buffer + s->top*s->typesize, s->typesize);//成功则return 1;return 1;}int IsEmpty(stack * s){return s->top == -1;//如果top为-1则栈空}int IsFull(stack * s){return s->top == s->max-1;//如果top为max-1则栈满}//___________________________________________________________________________________________________________________________________________________ //2.定义⼀个cal类型,其中data存数时sign为IsDouble,存字符时,sign为Ischartypedef struct {double data;char sign;} cal;//3.查找对应符号(找到则返回该符号下标)(找不到则说明该部分为数字返回-1)int SearchCode(char ch){char * code = "+-*/()@";//@为终⽌符,算式输⼊结束int index = 0;//while (code[index]){if (code[index] == ch) return index;index++;}return -1;}//4.得到两个符号间的优先级//与SearchCode相对应,char GetPriority(char ch, char next){//创建⼀个perferen表,第i⾏(列)对应SearchCode函数中code中的第i个字符char perferen[7][7] = {">><<<>>",">><<<>>",">>>><>>",">>>><>>","<<<<<=E",">>>>E>>","<<<<<E="};//找到两个形参对应的字符int c = SearchCode(ch);int n = SearchCode(next);//如果找不到对应运算符(字符不是运算符⽽是为数字)return Eif (c==-1 || n==-1) return 'E';//如果找到两个对应运算符则按照优先级表返回两个运算符的优先级return perferen[c][n];}//5.四则运算double add(double a, double b) { return a+b; }double sub(double a, double b) { return a-b; }double mul(double a, double b) { return a*b; }double ddiv(double a, double b) { return a/b; }//整合四种运算double calcu(double a, char ch, double b){double (*calculation[4])(double,double) = {add,sub,mul,ddiv};return calculation[SearchCode(ch)](a,b);}//6.检测字符串int CheckStr(char * buffer){int n;//遍历字符串确保算式中⽆⾮法字符若检测到⾮法字符return 0,若都合法则return 1for (n = 0;buffer[n];n++){if ((SearchCode(buffer[n]) != -1 || buffer[n] == '.' || (buffer[n] >= '0' && buffer[n] <= '9')) && buffer[n] != '@') continue;else return 0;}buffer[n] = '@';//加上终⽌符,表⽰算式结束buffer[n+1] = '\0';return 1;}//7.得到数据转化为double类型存⼊rsint GetDigit(char * buffer, int * n, double * rs){char str[30];int i,j = 0;for (i = 0;SearchCode(buffer[*n]) == -1;i++){str[i] = buffer[*n];//从*n位置开始,将这⼀串数字字符存⼊str(*n)++;}str[i] = '\0';for (i = 0;str[i];i++){if (str[i] == '.') j++;}//如果⼀段⼩数有多个⼩数点或⼩数点在数字⾸尾,return 0if (j>1 || str[i-1] == '.' || str[0] == '.') return 0;//rs接收转化为double的数据*rs = atof(str);//操作成功return 1return 1;}//8.将⽤户输⼊的buffer字符串转化为可供程序运算的calstr数组int resolu(char * buffer, cal * calstr){int i = 0, j = 0;cal c;while (buffer[i]){if (SearchCode(buffer[i]) == -1){//如果得到数据不成功则return 0if (GetDigit(buffer,&i, &c.data) == 0) return 0;//如果成功得到数据则在c.sign标记为浮点数c.sign = IsDouble;//将c存⼊数组calstr中calstr[j++] = c;}else{//若符号为运算符//判断正负号if (buffer[i] == '-' && (buffer[i-1] == '('||buffer[i-1] == '+'||buffer[i-1] == '-'||buffer[i-1] == '*'||buffer[i-1] == '/') || (i==0 && buffer[0] == '-')){ i++;if (GetDigit(buffer,&i, &c.data) == 0) return 0;//在符号的下⼀位开始查找,若找不到数字return 0//否则,给数字取相反数,c.sign标记为浮点数,存⼊calstr中c.data = 0 - c.data;c.sign = IsDouble;calstr[j++] = c;} else//如果是正号,与符号处理⽅式同理if (buffer[i] == '+' && (buffer[i-1] == '('||buffer[i-1] == '+'||buffer[i-1] == '-'||buffer[i-1] == '*'||buffer[i-1] == '/') || (i==0 && buffer[0] == '+')){ i++;if (GetDigit(buffer, &i, &c.data) == 0) return 0;c.sign = IsDouble;calstr[j++] = c;}else{//如果不是正负号,则为运算符,先强制转换为double类型存在c.data⾥,然后c.sign标记为char类型,存⼊calstrc.data = (double)buffer[i++];c.sign = IsChar;calstr[j++] = c;}}}//操作蔡成功则return 1return 1;}//9.计算出结果int result(cal * calstr, double * rs){stack * pst = CreateStack(100,sizeof(char));//运算符栈stack * pnd = CreateStack(100,sizeof(double));//数据栈double num1,num2;int n = 0;char ch = '@';Push(pst, &ch);//在转换得到的calstr中遍历直到终⽌符'@"while(ch != '@' || !(calstr[n].sign == IsChar && (char)calstr[n].data == '@')){//如果calstr的n位上是浮点数,则将这个data压栈进⼊数据栈pnd中if (calstr[n].sign == IsDouble){Push(pnd, &(calstr[n].data));n++;}//反之,如果是运算符,则要检测优先级else{switch( GetPriority(ch, (char)calstr[n].data)){//如果运算符优先级较⼩,则让ch等于优先级⼤的符号并压⼊符号栈pst中case '<':ch = (char)calstr[n].data;Push(pst, &ch);n++;break;//如果结果为等号,让符号出栈暂存到ch中case '=':if (!Pop(pst, &ch)) return 0;n++;break;//如果ch优先级较⾼,则将前两个数字及运算符出栈,分别储存⾄num2,ch,num1中,进⾏运算,得到的结果再次压栈进⼊pnd中 case '>':if (!(Pop(pnd,&num2) && Pop(pst,&ch) && Pop(pnd,&num1))) return 0;num1 = calcu(num1,ch,num2);Push(pnd, &num1);break;//如果符号顺序出错,return 0case 'E':return 0;}}//检测是否可以得到栈顶符号,栈空则return 0if (!GetTop(pst, &ch)) return 0;}//如果栈中得到了最终结果,并且取出pnd中的最终结果到rs,return 1if (GetSize(pnd) == 1 && GetTop(pnd,rs)){DestroyStack(pst);DestroyStack(pnd);return 1;}//否则 return 0else{return 0;}}//10.⽤户交互函数void treatment(){char buffer[100];//⽤户输⼊的字符串(算式)cal calstr[50];//计算⽤的数组double rs = 0;//计算结果printf("Enter your equation:");gets(buffer);//让⽤户输⼊算式buffer//⽤户不输⼊"exit"就不退出while (!(buffer[0]=='e' && buffer[1]=='x' && buffer[2]=='i' && buffer[3]=='t')){//检查buffer中字符君合法,成功将buffer转化为⽤于计算的calstr数组,成功计算出结果存⼊rsif (CheckStr(buffer) && resolu(buffer,calstr) && result(calstr,&rs)){printf("\n%lf\n",rs);}else{printf("\nError!\n");}printf("Enter \"exit\"to quit");printf("\nEnter your equation:");gets(buffer);//再次让⽤户输⼊算式}printf("\nbye\n");}//11.主函数int main(){treatment();}参考⽂献链接如下[参考⽂献]()。

C语言简易计算器的实现

C语言简易计算器的实现

C语言简易计算器的实现C语言简易计算器是一种用于进行基本数学运算的程序。

实现一个简易计算器的关键是要能够解析用户输入的数学表达式,并将其转化为计算机可以理解的形式,然后进行计算,并输出结果。

下面是一个大约1200字以上的示例实现。

```c#include <stdio.h>#include <stdlib.h>#include <stdbool.h>#include <ctype.h>#define MAX_SIZE 100//定义操作符的优先级int getPriority(char op)if (op == '+' , op == '-')return 1;else if (op == '*' , op == '/')return 2;elsereturn 0;//进行四则运算int calculate(int a, int b, char op)switch (op)case '+': return a + b;case '-': return a - b;case '*': return a * b;case '/': return a / b;default: return 0;}//将中缀表达式转换为后缀表达式void infixToPostfix(char* infixExp, char* postfixExp) char stack[MAX_SIZE];int top = -1;int j = 0;for (int i = 0; infixExp[i] != '\0'; i++)if (isdigit(infixExp[i])) { // 数字直接输出到后缀表达式while (isdigit(infixExp[i]))postfixExp[j++] = infixExp[i++];}postfixExp[j++] = ' ';i--;}else if (infixExp[i] == '(') { // 左括号压入栈stack[++top] = infixExp[i];}else if (infixExp[i] == ')') { // 右括号弹出栈内所有操作符并输出到后缀表达式,直到遇到左括号while (top != -1 && stack[top] != '(')postfixExp[j++] = stack[top--];postfixExp[j++] = ' ';}top--; // 弹出栈顶的左括号}else { // 操作符while (top != -1 && getPriority(stack[top]) >=getPriority(infixExp[i]))postfixExp[j++] = stack[top--];postfixExp[j++] = ' ';stack[++top] = infixExp[i];}}while (top != -1) { // 将栈内剩余操作符弹出并输出到后缀表达式postfixExp[j++] = stack[top--];postfixExp[j++] = ' ';}postfixExp[j] = '\0';//计算后缀表达式的值int evaluatePostfix(char* postfixExp)char stack[MAX_SIZE];int top = -1;for (int i = 0; postfixExp[i] != '\0'; i++)if (isdigit(postfixExp[i])) { // 数字压入栈int num = 0;while (isdigit(postfixExp[i]))num = num * 10 + (postfixExp[i++] - '0');stack[++top] = num;i--;}else if (postfixExp[i] == ' ')continue;}else { // 操作符,弹出栈顶的两个数进行计算,并将结果压入栈int b = stack[top--];int a = stack[top--];int result = calculate(a, b, postfixExp[i]);stack[++top] = result;}}return stack[top];int maichar infixExp[MAX_SIZE];printf("请输入中缀表达式:");fgets(infixExp, sizeof(infixExp), stdin); // 读取用户输入//将中缀表达式转换为后缀表达式char postfixExp[MAX_SIZE];infixToPostfix(infixExp, postfixExp);printf("后缀表达式为:%s\n", postfixExp);//计算后缀表达式的值并输出int result = evaluatePostfix(postfixExp);printf("计算结果为:%d\n", result);return 0;```这个简易计算器的实现基于栈的数据结构。

AT89C52单片机简易计算器

AT89C52单片机简易计算器
lnumnow=lnumnow*10+2;
flag=2;
}
if(P3_4==0)//0
{
if(flag==1)
{
lnumbefore=lnumnow;lnumnow=0;digit=0;
}
if(flag==4)
{
lnumnow=0;
}
digit++;
lnumnow=lnumnow*10;
flag=2;
flag=2;
}
if(P3_4==0&&flag!=1)//=
{
switch(signal)
{
case '+':
lnumnow=lnumnow+lnumbefore;
lnumbefore=lnumnow;
break;
case '-':
lnumnow=lnumbefore-lnumnow;
lnumbefore=lnumnow;
break;
}
signal=0;
if(P3_7==0)//除
{
signal='/';
flag=1;
digit=0;
}
if(P3_6==0)//乘
{
flag=1;
signal='*';
digit=0;
}
if(P3_5==0)//减
{
flag=1;
signal='-';
digit=0;
}
if(P3_4==0)//加
lnumnow=lnumnow*10+4;
flag=2;
}

简单计算器(51单片机程序)

简单计算器(51单片机程序)
{
for(i=0;i<8;i++)
{
con[i]=0;
tem[i]=0;
}
count=-1;
flag=0;
} break;
case 0x7b://equal
{
switch(flag)
count++;
switch(temp)
{
case 0xed:
{ num=4;
if(count<8)
con[count]=num;
} break;
case 0xdd:
{ num=5;
if(count<8)
}
for(j=0;j<8;j++)
{
con[j]=0;
tem[j]=0;
} break;
case 0xde:
{ num=1;
if(count<8)
con[count]=num;
} break;
case 0xbe:
{ num=2;
if(count<8)
con[count]=num;
for(i=0;i<8;i++)
{
tem1[i]=tem[i];
}
for(j=0;j<8;j++)
{
con[j]=0;
tem[j]=0;
}
count=-1;
} break;
}
}
}
P1=0xfd;
temp=P1;
temp=temp&0xf0;

用c语言编写简易计算器

用c语言编写简易计算器

在c51中用c语言编写简易计算器#include<reg52.h>#define BYTE unsigned charint jh;int a;int b;int c; /*c是符号*//*按键的值*/sbit P11=P1^3;sbit P12=P1^2;sbit P13=P1^1;sbit P14=P1^0;BYTE disply[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};void delay(int ms) //延时函数{while(ms--){ int h;for( h=0;h<=250;h++){;}}}void get_jianzhi() //获取键盘值的函数{BYTE disi;BYTE gaosi;gaosi=P2;P2=0x0f;delay(10 );disi=P2;gaosi=gaosi+disi;switch(gaosi){case 0xee:{jh=0;break;}case 0xde:{jh=1;break;}case 0xbe:{jh=2;break;}case 0x7e:{jh=3;break;}case 0xed:{jh=4;break;}case 0xdd:{jh=5;break;}case 0xbd:{jh=6;break;}case 0x7d:{jh=7;break;}case 0xeb:{jh=8;break;}case 0xdb:{jh=9;break;}case 0xbb:{jh=10;break;}case 0x7b:{jh=11;break;}case 0xe7:{jh=12;break;}case 0xd7:{jh=13;break;}case 0xb7:{jh=14;break;}case 0x77:{jh=15;break;}}do{P2=0xf0;}while(P2!=0xf0);}void show() /*显示函数*/{BYTE m; /*千位*/BYTE h; /*百位*/BYTE j; /*十位*/BYTE i; /*个位*/P3=0xff;if(c==14){b=0;}else{ }while(P2==0xf0) /*有键按下则跳出循环函数*/{j=0;i=0;h=0;m=0;if(b!=0) /*b不为0则显示b并判断它有几位数*/{if(b>99) {h=b/100;j=(b-h*100)/10;i=b%10;}else{if(b>9){j=b/10;i=b%10;}else{i=b;}}}else{if(a>999){ m=a/1000;h=(a-m*1000)/100;j=(a-m*1000-h*100)/10;i=a%10;}else{if(a>99){h=a/100;j=(a-h*100)/10;i=a%10;}else{if(a>9){j=a/10;i=a%10;}else{i=a;}}}}if(m!=0){ P11=0; P0=disply[i]; delay(5);P0=0x00;P11=1;P12=0;P0=disply[j];delay(5);P0=0x00;P12=1;P13=0;P0=disply[h];delay(5);P0=0x00;P13=1;P14=0;P0=disply[m]; delay(5);P14=1;P0=0x00;}else { if(h!=0){P11=0; P0=disply[i]; delay(5);P0=0x00;P11=1;P12=0;P0=disply[j]; /*判断要显示的数字是几位数*/delay(5);P0=0x00;P12=1;P13=0;P0=disply[h]; delay(5);P0=0x00;P13=1;}else{if(j!=0){P11=0;P0=disply[i];delay(5);P0=0x00;P11=1;P12=0;P0=disply[j]; delay(5);P0=0x00;P12=1;}else{P11=0;P0= P0=disply[i];}}}}}void main(){BYTE k=0; /*用来判断是给a还是b赋值*/P2=0xf0;a=0; /*第一次按键值的初始化*/b=0; /*第二次按键值的初始化*/bat:show();delay(10 );get_jianzhi() ;P2=0xf0;if(jh==15) /*按了清除键的话,全部清零*/ {a=0;b=0;c=0;}else{if(jh>=0&&jh<=9) /*按了数字键*/{if(k==0) /*判断是给a还是b赋值*/{a=a*10+jh;}else{b=b*10+jh;}goto bat;}else{if(a==0&&b==0) /*在开始时只按功能键的话,返回*/{goto bat;}else{k=1;if(b==0){c=jh;}else{switch(c) /*运算法则*/{case 10: { a=a+b;break;}case 11: {a=a-b;break;}case 12: {a=a*b;break;}case 13: {a=a/b;break;}case 15:{ break; } /*按'='的话,不运算*/}c=jh;}goto bat;}}goto bat;}}。

AT89C51单片机C实现简易计算器

AT89C51单片机C实现简易计算器

AT89C51单片机简易计算器的设计一、总体设计根据功能和指标要求,本系统选用MCS-5系列单片机为主控机。

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

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

(2)另外键盘包括数字键(0〜9)、符号键(+、、x、清除键和等号键,故只需要16个按键即可,设计中采用集成的计算键盘。

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

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

系统模块图:二、硬件设计(一)、总体硬件设计本设计选用AT89C51单片机为主控单元。

显示部分:采用LCD静态显示。

按键部分:采用 4*4键盘;利用MM74C92为4*4的键盘扫描IC ,读取输入的键值。

总体设计效果如下图:禺弱蚯>9上bdJlBtJII卜0bk圏】系喘方案图3- -Od 右□ P -C3 1X1 ih- -F I !i ■ ■ ■ B. SK I :就 疔*AJH31 TT3S ■ Nt PI 1Ph J Pl ;PIT PI f.Pll ; 和 ILdfl fD l.-U Fp7j<T r :心ny^ui PFL * ■、工世 鬥沁I *1 ell H ir*j : ■J.tmi =7 muBn ,二 pj ..nir P3⑷ p i*/n 叩.033. ft::r^jub.a:■ . H 1 -E L " H 也 cjzj HBCn “心《.一一「丁 g -...宁"hfL;i 【巒 1— ■ ..2M_ 0 31(二)、键盘接口电路计算器输入数字和其他功能按键要用到很多按键,如果采用独立按键的方式,在这种情况下,编程会很简单,但是会占用大量的I/O 口资源,因此在很多情况下都不采用这种方式,而是采用矩阵键盘的方案。

AT89S52单片机实现简易计算器(C语言程序)

AT89S52单片机实现简易计算器(C语言程序)
AT89S52单片机实现简易计算器(C语言程序)
本文设计基于AT89S52单机的简易计算器。它的功能是:
(1)计算器至少能正常显示8位数。
(2)卡机时,显示0。第一次按下时,显示D1;第二次按下时,显示
D1D2。
(3)计算器能对整数进行简单的加、减、乘、除四则运算,在做除法时
能自动舍去小数部分。
(4)运算结果超过可显示的位数时能进行出错提示。
系统设计
电路原理图
基于AT89S52单片机简易计算器电路原理图
程序流程图
由于本设计主要是算法问题,所以程序采用C语言编写。主函数对单片
机进行初始化,并不断调用扫描函数和运算函数。显示函数采用1ms定时中
断来对显示数据进行实时跟新。基于AT89S52单片机简易计算器程序流程图
如下图所示。
简易计算器程序流程图
代码编写
#include P #include《》
#define LEDS 8
/***按键程序***/ char keyscan();
/***显示程序***/ void display();
char dsp[9]={0,0,12,12,12,12,12,12,12}; //初始化显示数组
/***计算程序***/
总体设计
计算器以AT89S52单片机为核心芯片,通过扫描键盘来得到数据,另外
通过CPU将得到的数据按要求进行运算并将结果送到显示电路进行显示。
框图设计
基于AT89S52单片机的简易计算器由电源电路、单片机主控电路、按键
电路、显示电路和复位电路几部分组成,框图组成如下图所示。
基于AT89S52单片机的简易计算器系统框图
void calculate(char k,char c1[8],char c2[8]);

利用单片机实现简单功能计算器设计

利用单片机实现简单功能计算器设计

基于单片机的多功能计算器设计1.方案论证与选择1.1输入模块方案一:采用独立式按键作为输入模块,其特点:直接用I/O口构成单个按键电路,接口电路配置灵活、按键识别和软件结构简单,但是当键数较多时,占用I/O口较多,比较浪费资源;其原理图如图1所示:图1 独立的功能按键方案二:采用矩阵式键盘作为输入电路,其特点:电路和软件稍复杂,但相比之下,当键数越多时越节约I/O口,比较节省资源。

其原理图如图2所示:图2 矩阵键盘输入本设计使用键盘输入预置用于计算或计时,按键较多。

若采用独立按键,需频繁按键,为软件设计增加负担,且操作界面不友好。

若采用矩阵式按键,可以方便地输入一个数值,使操作界面更具人性化,节约了宝贵的I/O口资源。

通过对比,故采用方案二作为系统输入模块。

1.2显示模块:方案一:用LCD显示,要用LCD显示,需要学习其专用的驱动控制芯片,比如HD61203,软件实现较为复杂,且LCD的价格昂贵。

方案二:采用LED数码管串行静态显示,虽然其显示亮度高,但是如果显示器的位数较多,需要增加锁存器,故而静态显示占用I/O口线较多,CPU的开销较大。

方案三:采用LED数码管并行动态显示,显示亮度不及静态显示,但电路简单,适合于显示位数较多的情况。

表1 用LED显示器显示十六位进制数的字形代码在下图表示:综上所述,采用方案三并行动态显示是本设计最佳显示方案。

LED数码管显示器由6个发光二极管组成,因此也称之为6段LED显示器,其排列形状如上。

注:该设计电路中的6段LED数码显示器是共阳极的。

2.其他硬件电路模块功能介绍:2.1驱动模块该设计的驱动电路是由74LS245来驱动的。

74LS245是我们常用的芯片,用来驱动LED或者其他的设备,它是8路同相三态双向总线收发器,可双向传输数据。

74LS245还具有双向三态功能,既可以输出,也可以输入数据。

当8051单片机的P0口总线负载达到或超过P0最大负载能力时,必须接入74LS245等总线驱动器。

单片机简易计算器

单片机简易计算器

#include <reg52.h>typedef unsigned char uint8;typedef unsigned int uint16;typedef unsigned long uint32;typedef char int8;typedef int int16;typedef long int32;sbit KeyIn1 = P2^4;sbit KeyIn2 = P2^5;sbit KeyIn3 = P2^6;sbit KeyIn4 = P2^7;sbit KeyOut1 = P2^3;sbit KeyOut2 = P2^2;sbit KeyOut3 = P2^1;sbit KeyOut4 = P2^0;sbit ADDR0 = P1^0;sbit ADDR1 = P1^1;sbit ADDR2 = P1^2;sbit ADDR3 = P1^3;sbit ENLED = P1^4;sbit BUZZ = P1^6;#define FADD 10#define FSUB 11#define FMUL 12#define FDIV 13#define FRES 14#define FEQU 15#define KEY_DELAY 300#define BUZ_DELAY 80code uint8 Ledcode[13]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf,0x86}; uint8 Led_n=0;uint8 Led_buf[6];float Tmp1=0, Tmp2=0;int8 C_flag=0;/** 延时*/void delay(uint16 n){while (n--);}/** 蜂鸣器发声*/void buzzer_sound(void){uint16 i;for (i=0; i<BUZ_DELAY; i++){BUZZ = ~BUZZ;delay(100);}BUZZ = 1;}/** 按键扫描*/int8 scan_key(void){int8 val=-1;KeyOut1 = 0;KeyOut2 = 1;KeyOut3 = 1;KeyOut4 = 1;if (KeyIn1 == 0){delay(KEY_DELAY);if (KeyIn1 == 0)val = 1;}if (KeyIn2 == 0){delay(KEY_DELAY);if (KeyIn2 == 0)val = 2;}if (KeyIn3 == 0){delay(KEY_DELAY);if (KeyIn3 == 0)val = 3;}if (KeyIn4 == 0){delay(KEY_DELAY);if (KeyIn4 == 0)val = FADD;}while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));KeyOut1 = 1;KeyOut2 = 0;KeyOut3 = 1;KeyOut4 = 1;if (KeyIn1 == 0){delay(KEY_DELAY);if (KeyIn1 == 0)val = 4;}if (KeyIn2 == 0){delay(KEY_DELAY);if (KeyIn2 == 0)val = 5;}if (KeyIn3 == 0){delay(KEY_DELAY);if (KeyIn3 == 0)val = 6;}if (KeyIn4 == 0){delay(KEY_DELAY);if (KeyIn4 == 0)val = FSUB;}while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0)); KeyOut1 = 1;KeyOut2 = 1;KeyOut3 = 0;KeyOut4 = 1;if (KeyIn1 == 0){delay(KEY_DELAY);if (KeyIn1 == 0)val = 7;}if (KeyIn2 == 0){delay(KEY_DELAY);if (KeyIn2 == 0)val = 8;}if (KeyIn3 == 0){delay(KEY_DELAY);if (KeyIn3 == 0)val = 9;}if (KeyIn4 == 0){delay(KEY_DELAY);if (KeyIn4 == 0)val = FMUL;}while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));KeyOut1 = 1;KeyOut2 = 1;KeyOut3 = 1;KeyOut4 = 0;if (KeyIn1 == 0){delay(KEY_DELAY);if (KeyIn1 == 0)val = 0;}if (KeyIn2 == 0){delay(KEY_DELAY);if (KeyIn2 == 0)val = FRES;}if (KeyIn3 == 0){delay(KEY_DELAY);if (KeyIn3 == 0)val = FEQU;}if (KeyIn4 == 0){delay(KEY_DELAY);if (KeyIn4 == 0)val = FDIV;}while ((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));if (val > 0)buzzer_sound();return val;}/** 验证数据有效性*/bit check_num(float f_num){if (f_num >= 100000)return 1;return 0;}/** 制作数码管错误标志*/void make_led_error(void){int8 i;for (i=0; i<5; i++)Led_buf[i] = Ledcode[10];Led_buf[5] = Ledcode[12];}/** 制作数码管整数数据*/void make_led_inumber(int32 i_num) {bit s_flag=0;int16 sit;int8 i;if (i_num < 0){s_flag = 1;i_num = -i_num;}ET0 = 0;for (i=4, sit=10000; i>=1; i--, sit/=10){if (i_num >= sit)break;Led_buf[i] = Ledcode[10];i_num -= i_num/sit*sit;}for (;i>=1; i--, sit/=10){Led_buf[i] = Ledcode[i_num/sit];i_num -= i_num/sit*sit;}Led_buf[0] = Ledcode[i_num] & 0x7F;if (s_flag)Led_buf[5] = Ledcode[11];elseLed_buf[5] = Ledcode[10];ET0 = 1;}/** 制作数码管浮点数据*/void make_led_fnumber(float f_num) {bit s_flag=0;int32 num;int16 sit;int8 i, decimal, dot_sit=0;if (f_num < 0){s_flag = 1;f_num = -f_num;}num = (int32)(f_num*10000+0.5); for (decimal=4; decimal>0; decimal--) {if (num % 10 != 0)break;num /= 10;}dot_sit = decimal;if (f_num >= 10000)dot_sit = 0;else if (f_num >= 1000)if (decimal >= 1)dot_sit = 1;else if (f_num >= 100)if (decimal >= 2)dot_sit = 2;else if (f_num >= 10)if (decimal >= 3)dot_sit = 3;for (i=0; i<dot_sit; i++)f_num *= 10;num = (int32)(f_num+0.5);ET0 = 0;for (i=4, sit=10000; i>=1; i--, sit/=10) {if (num >= sit)break;if (i == dot_sit)break;Led_buf[i] = Ledcode[10];num -= num/sit*sit;}for (;i>=1; i--, sit/=10){Led_buf[i] = Ledcode[num/sit];num -= num/sit*sit;}Led_buf[0] = Ledcode[num];Led_buf[dot_sit] &= 0x7F;if (s_flag)Led_buf[5] = Ledcode[11];elseLed_buf[5] = Ledcode[10];ET0 = 1;}/** 数码管显示*/void show_num(uint8 *buf){ENLED = 1;switch (Led_n){case 0:ADDR0 = 0;ADDR1 = 0;ADDR2 = 0;P0 = buf[0];break;case 1:ADDR0 = 1;ADDR1 = 0;ADDR2 = 0;P0 = buf[1];break;case 2:ADDR0 = 0;ADDR1 = 1;ADDR2 = 0;P0 = buf[2];break;case 3:ADDR0 = 1;ADDR1 = 1;ADDR2 = 0;P0 = buf[3];break;case 4:ADDR0 = 0;ADDR1 = 0;ADDR2 = 1;P0 = buf[4];break;case 5:ADDR0 = 1;ADDR1 = 0;ADDR2 = 1;P0 = buf[5];break;}ENLED = 0;if (Led_n >= 5)Led_n = 0;elseLed_n++;}/** 计算程序*/void calculate(int8 key_val){float ans;bit err=0;if ((key_val >= FADD) && (key_val <= FDIV)){C_flag = key_val;}else if (key_val == FEQU){switch (C_flag){case FADD: ans = Tmp1+Tmp2; break;case FSUB: ans = Tmp1-Tmp2; break;case FMUL: ans = Tmp1*Tmp2; break;case FDIV: if (Tmp2 == 0){err = 1;break;}else{ans = Tmp1/Tmp2;break;}}if (check_num(ans))err = 1;if (err)make_led_error();elsemake_led_fnumber(ans);C_flag = 0;Tmp1 = 0;Tmp2 = 0;}else if (key_val == FRES){make_led_fnumber(0);C_flag = 0;Tmp1 = 0;Tmp2 = 0;}else{if (C_flag == 0){ans = Tmp1;ans *= 10;ans += key_val;if (check_num(ans))return;elseTmp1 = ans;make_led_inumber(Tmp1);}else{ans = Tmp2;ans *= 10;ans += key_val;if (check_num(ans))return;elseTmp2 = ans;make_led_inumber(Tmp2);}}}main(){int8 key_val;ADDR3 = 1;ENLED = 0;make_led_inumber(0);TMOD = 0x01;TH0 = 0xF8;TL0 = 0xCC;TR0 = 1;ET0 = 1;EA = 1;while (1){key_val = scan_key();if (key_val == -1)continue;calculate(key_val);}}void time0() interrupt 1{TR0 = 0;TH0 = 0xF8;TL0 = 0xCC;show_num(Led_buf);TR0 = 1;}。

单片机C语言简易计算器

单片机C语言简易计算器

课程设计报告课程名称单片机原理及应用设计题目简易计算器设计专业班级姓名学号1。

项目概述中国古代最早采用的一种计算工具叫算筹。

这种算筹多用竹子制成,也有用木头,兽骨充当材料的。

约二百七十枚一束,放在布袋里可以随身携带。

17世纪初,西方国家的计算工具有了较大的发展,英国数学家纳皮尔发明的“纳皮尔算筹”,英国牧师奥却德发明了圆柱形对数计算尺,这种计算尺不仅能做加减乘除,乘方,开方运算,甚至可以计算三角函数,指数函数和对数函数,这些计算工具不仅带动了计算器的发展,也为现代计算器发展奠定了良好的基础,成为现代社会应用广泛的计算工具。

2。

项目要求基于AT89C51单片机的简易计算器,设计要求如下: (1) 计算器至少能正常显示8位数。

(2) 开机时,显示“0”(3) 计算器能对整数进行简单的加减乘除四则运算,在做除法时能自动舍去小数部分 (4) 运算结果超过可显示的位数时能进行出错提示。

3.小组人员组成及分工4.系统设计1.框图设计5.硬件设计(1)电路原理图:(2)元件清单:元件名称型号数量用途单片机AT89C511控制核心电阻10kΩ4按键电路数码管8位共阳极1显示电路按键16按键电路6.软件设计(1)算法流程图:主函数单片机C语言简易计算器显示函数按键函数(2)程序清单:#include〈reg51.H〉/***按键程序***/char keyscan();/***显示程序***/void display();char dsp[9]={0,0,12,12,12,12,12,12,12}; //初始化显示数组/***计算程序***/void calculate(char k,char c1[8],char c2[8]);/***片选***/unsigned char code Select[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};/***码选***/unsigned char code LED_CODES[]={0xC0,0xF9,0xA4,0xB0,0x99, //0-40x92,0x82,0xF8,0x80,0x90, //5-90x86,0xAF,0xFF,0x7F,0xBF,}; //E,r,空格,.,—/***main函数***/void main(void){char i,j,k,c;char a[8],b[8];/***定时1ms***/TMOD=0;//TL0=-(1000/256);//TH0=—(1000%256);EA = 1; //总中断开关ET0 = 1; //开中断TR0 = 1; //启用计数器0LR:do{for(i=1;i〈9;i++) //数字录入循环{dsp[0]=keyscan();if(c==2&&dsp[0]<10) //此段代码验证是否有旧的计算结果在显示,且不再参与新计算{dsp[1]=dsp[0];for(j=2;j<9;j++)dsp[j]=12;c=0;}else if(c==2&&dsp[0]>9) //旧的计算结果将参与新的计算,作为第一个数{c=0;}if(dsp[0]==0&&dsp[1]==0&&dsp[2]==12) //个位为0且十位为空时按下0,按键无效,跳回LR等待正确输入{/***goto跳转标志***/goto LR;}else if(dsp[0]〉9) break; //有操作符按下,跳出数字录入循环else{for(j=i;j>0;j-—)dsp[j]=dsp[j—1]; //移位,以正确显示数字}}if(i==9) //判断是否输入8个有效数字,是则等待操作符,否则直接判断操作符{do //使用do while无论是否第一个数都取一次操作符{dsp[0]=keyscan(); //获取操作符号if(dsp[0]==14||dsp[0]〈10) //按下C或者第9位数字清零{dsp[1]=0;for(i=2;i<9;i++)dsp[i]=12;c=0;}}while((dsp[0]==15)&&(c==0)); //等号被按下,等待新的操作符(仅对第一个数字有效) }else if(dsp[0]==14) //按下C清零{dsp[1]=0;for(i=2;i<9;i++)dsp[i]=12;c=0;}while(dsp[0]==15&&c==0) //未输满8位且是第一个数字即按下等号,等待非等号操作符{dsp[0]=keyscan(); //获取操作符号if(dsp[0]==14||dsp[0]〈10) //按下C或者数字都进行清零,重新输入a{dsp[0]=14; //将dsp[0]置为14,防止因数字清零未能拦截dsp[1]=0;for(i=2;i〈9;i++)dsp[i]=12;c=0;}}}while(dsp[0]==14); //数字输入未完成即按下C,重新等待输入do{if(c==0) //没有数字输入{k=dsp[0]; //存计算符(循环内已排除C、=、数字)for(i=0;i<8;i++) //将第一个数存入a[8]{a[i]=dsp[i+1];}dsp[1]=0; //清零for(i=2;i〈9;i++)dsp[i]=12;c=1; //已输入a/***goto跳转标志***/goto LR;}else if(c==1){for(i=0;i〈8;i++) //将第二个数存入b[8]{b[i]=dsp[i+1];}c=2; //已输入bif(dsp[0]!=15) //b输完后操作符不是等号{calculate(k,a,b);for(i=0;i<8;i++) //将计算结果存入a[8],a值更新{a[i]=dsp[i+1];}k=dsp[0]; //更新计算符c=1;/***goto跳转标志***/goto LR;}}}while((dsp[0]==15)&&(c〈2)); //直到ab输入完成且按下等号calculate(k,a,b); //进行最后计算/***goto跳转标志***/goto LR; //跳回LR,等待新一轮计算while(1); //防止程序跑飞}char keyscan(){char KeyL;char KeyR;char j;do{do{P3=0xF0;P3=P3|0xF0;//行扫描11110000if(P3!=0xF0){KeyL=P3;P3=0x0F;P3=P3|0x0F;//列扫描00001111KeyR=P3;}}while(KeyL==0xF0||KeyR==0x0F);for(j=0;j<12;j++) //延时0.001s=1ms{;}}while(P3!=0x0F);switch(KeyL&KeyR){case 0x28:{return 0;break;}case 0x11:{return 1;break;}case 0x21:{return 2;break;}case 0x41:{return 3;break;}case 0x12:{return 4;break;}case 0x22:{return 5;break;}case 0x42:{return 6;break;}case 0x14:{return 7;break;}case 0x24:{return 8;break;}case 0x44:{return 9;break;}case 0x81:{return 10;break;}//加法(第一行,第四列)case 0x82:{return 11;break;}//减法(第二行,第四列)case 0x84:{return 12;break;}//乘法(第三行,第四列)case 0x88:{return 13;break;}//除法(第四行,第四列)case 0x18:{return 14;break;}//清零(第四行,第一列)case 0x48:{return 15;break;}//计算结果(第四行,第三列)}}void display() interrupt 1 using 1 //利用定时器中断实现间时显示{char i,j,h;ET0=0;for(j=8;j>0;j——) //扫描8次{for(i=7;i>=0;i——) //从高位到低位扫描显示{P2=0;P1=LED_CODES[dsp[8—i]];P2=Select[i];for(h=0;h〈8;h++){;}}}TL0=-(1000/256);TH0=-(1000%256);ET0=1;}void calculate(char k,char a[8],char b[8]){char r[8];long i,x,y;i=0;x=0;y=0;for(i=7;i>0;i-—) //数值转化,将代表空格的12转化为数字0,因为个位不显示空格,默认为0,所以不转化{while(a[i]==12)a[i]=0;while(b[i]==12)b[i]=0;}x=a[4];x=10000*x;x=x+a[0]+a[1]*10+a[2]*100+a[3]*1000+a[5]*100000+a[6]*1000000+a[7]*10000000;y=b[4];y=10000*y;y=y+b[0]+b[1]*10+b[2]*100+b[3]*1000+b[5]*100000+b[6]*1000000+b[7]*10000000;if(k==10)//加法运算{x=x+y;if(x〉99999999) //大于8位,显示”Err"{r[0]=11; //rr[1]=11; //rr[2]=10; //Er[3]=12; //空格r[4]=12;r[5]=12;r[6]=12;r[7]=12;}else{r[0]=x%10;r[1]=(x%100)/10;r[2]=(x%1000)/100;r[3]=(x%10000)/1000;r[4]=(x%100000)/10000;r[5]=(x%1000000)/100000;r[6]=(x%10000000)/1000000;r[7]=x/10000000;}}if(k==11)//减法运算{if(x〈y){x=y—x;if(x>9999999){r[0]=11; //rr[1]=11; //rr[2]=10; //Er[3]=12; //空格r[4]=12;r[5]=12;r[6]=12;r[7]=12;}else{r[0]=x%10;r[1]=(x%100)/10;r[2]=(x%1000)/100;r[3]=(x%10000)/1000;r[4]=(x%100000)/10000;r[5]=(x%1000000)/100000;r[6]=(x%10000000)/1000000;r[7]=x/10000000;for(i=7;i>0;i--) //将有效数字的高一位转化为-号{if(r[i]==0&&r[i—1]!=0){r[i]=14;break;}}}}else{x=x-y;r[0]=x%10;r[1]=(x%100)/10;r[2]=(x%1000)/100;r[3]=(x%10000)/1000;r[4]=(x%100000)/10000;r[5]=(x%1000000)/100000;r[6]=(x%10000000)/1000000;r[7]=x/10000000;}}if(k==12)//乘法运算{i=x;x=x*y;if(y==0){x=0;}else if(x〉99999999||x<i) //积大于99999999或者小于乘数都认为是异常,存在其他可能的溢出,须自行辨别{r[0]=11; //rr[1]=11; //rr[2]=10; //Er[3]=12; //空格r[4]=12;r[5]=12;r[6]=12;r[7]=12;}else{r[0]=x%10;r[1]=(x%100)/10;r[2]=(x%1000)/100;r[3]=(x%10000)/1000;r[4]=(x%100000)/10000;r[5]=(x%1000000)/100000;r[6]=(x%10000000)/1000000;r[7]=x/10000000;}}if(k==13)//除法运算{if(y==0) //被除数不能为0{r[0]=11; //rr[1]=11; //rr[2]=10; //Er[3]=12; //空格r[4]=12;r[5]=12;r[6]=12;r[7]=12;}else{x=x/y;r[0]=x%10;r[1]=(x%100)/10;r[2]=(x%1000)/100;r[3]=(x%10000)/1000;r[4]=(x%100000)/10000;r[5]=(x%1000000)/100000;r[6]=(x%10000000)/1000000;r[7]=x/10000000;}}for(i=7;i〉0;i—-) //数值转化,将高位的无效数字0转化为空格符12{if(r[i]==0)r[i]=12;elsebreak;}for(i=0;i〈8;i++) //将计算结果存入dsp[9],显示数更新{dsp[i+1]=r[i];}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
/***码选***/
unsigned char code LED_CODES[]=
{0xC0,0xF9,0xA4,0xB0,0x99, //0-4
92,0x82,0xF8,0x80,0x90, //5-9
0x86,0xAF,0xFF,0x7F,0xBF,}; //E,r,空格,.,-
{
a[i]=dsp[i+1];
}
dsp[1]=0; //清零
for(i=2;i<9;i++)
dsp[i]=12;
c=1; //已输入a
/***goto跳转标志***/
goto LR;
}
else if(c==1)
{
for(i=0;i<8;i++) //将第二个数存入b[8]
{
b[i]=dsp[i+1];
按键扫描录入函数
计算器加减乘除四则运算
4.
1.框图设计
显示
录入
5.


元件名称
型号
数量
用途
单片机
AT89C51
1
控制核心
电阻
10kΩ
4
按键电路
数码管
8位共阳极
1
显示电路
按键
16
按键电路
6.

主函数
显示函数
按键函数

#include<reg51.H>
/***按键程序***/
char keyscan();
dsp[1]=0;
for(i=2;i<9;i++)
dsp[i]=12;
c=0;
}
}
}
while(dsp[0]==14); //数字输入未完成即按下C,重新等待输入
do
{
if(c==0) //没有数字输入
{
k=dsp[0]; //存计算符(循环内已排除C、=、数字)
for(i=0;i<8;i++) //将第一个数存入a[8]
2.
基于AT89C51单片机的简易计算器,设计要求如下:
(1)计算器至少能正常显示8位数。
(2)开机时,显示“0”
(3)计算器能对整数进行简单的加减乘除四则运算,在做除法时能自动舍去小数部分
(4)运算结果超过可显示的位数时能进行出错提示。
3.
项目组成员
完成课程设计的内容
主函数设计
利用中断持续间时显示
{
c=0;
}
if(dsp[0]==0&&dsp[1]==0&&dsp[2]==12) //个位为0且十位为空时按下0,按键无效,跳回LR等待正确输入
{
/***goto跳转标志***/
goto LR;
}
else if(dsp[0]>9) break; //有操作符按下,跳出数字录入循环
else
{
for(j=i;j>0;j--)
{
dsp[1]=0;
for(i=2;i<9;i++)
dsp[i]=12;
c=0;
}
}
while((dsp[0]==15)&&(c==0)); //等号被按下,等待新的操作符(仅对第一个数字有效)
}
else if(dsp[0]==14) //按下C清零
{
dsp[1]=0;
for(i=2;i<9;i++)
dsp[j]=dsp[j-1]; //移位,以正确显示数字
}
}
if(i==9) //判断是否输入8个有效数字,是则等待操作符,否则直接判断操作符
{
do //使用do while无论是否第一个数都取一次操作符
{
dsp[0]=keyscan(); //获取操作符号
if(dsp[0]==14||dsp[0]<10) //按下C或者第9位数字清零
}
}
}
while((dsp[0]==15)&&(c<2)); //直到ab输入完成且按下等号
calculate(k,a,b); //进行最后计算
/***goto跳转标志***/
goto LR; //跳回LR,等待新一轮计算
dsp[i]=12;
c=0;
}
while(dsp[0]==15&&c==0) //未输满8位且是第一个数字即按下等号,等待非等号操作符
{
dsp[0]=keyscan(); //获取操作符号
if(dsp[0]==14||dsp[0]<10) //按下C或者数字都进行清零,重新输入a
{
dsp[0]=14; //将dsp[0]置为14,防止因数字清零未能拦截
}
c=2; //已输入b
if(dsp[0]!=15) //b输完后操作符不是等号
{
calculate(k,a,b);
for(i=0;i<8;i++) //将计算结果存入a[8],a值更新
{
a[i]=dsp[i+1];
}
k=dsp[0]; //更新计算符
c=1;
/***goto跳转标志***/
goto LR;
LR:do
{
for(i=1;i<9;i++) //数字录入循环
{
dsp[0]=keyscan();
if(c==2&&dsp[0]<10) //此段代码验证是否有旧的计算结果在显示,且不再参与新计算
{
dsp[1]=dsp[0];
for(j=2;j<9;j++)
dsp[j]=12;
c=0;
}
else if(c==2&&dsp[0]>9) //旧的计算结果将参与新的计算,作为第一个数
课程设计报告
课程名称单片机原理及应用
设计题目简易计算器设计
专业班级
姓名
学号
1.
中国古代最早采用的一种计算工具叫算筹。这种算筹多用竹子制成,也有用木头,兽骨充当材料的。约二百七十枚一束,放在布袋里可以随身携带。17世纪初,西方国家的计算工具有了较大的发展,英国数学家纳皮尔发明的“纳皮尔算筹”,英国牧师奥却德发明了圆柱形对数计算尺,这种计算尺不仅能做加减乘除,乘方,开方运算,甚至可以计算三角函数,指数函数和对数函数,这些计算工具不仅带动了计算器的发展,也为现代计算器发展奠定了良好的基础,成为现代社会应用广泛的计算工具。
/***main函数***/
void main(void)
{
char i,j,k,c;
char a[8],b[8];
/***定时1ms***/
TMOD=0;
//TL0=-(1000/256);
//TH0=-(1000%256);
EA = 1; //总中断开关
ET0 = 1; //开中断
TR0 = 1; //启用计数器0
/***显示程序***/
void display();
char dsp[9]={0,0,12,12,12,12,12,12,12}; //初始化显示数组
/***计算程序***/
void calculate(char k,char c1[8],char c2[8]);
/***片选***/
unsigned char code Select[]=
相关文档
最新文档