51单片机 实现计算器功能
51单片机实现多模式计算器
51单⽚机实现多模式计算器介绍单⽚机型号: 普中89C51能够最⼤输出4位数结果,保留两位⼩数。
实现计算器⼀些功能。
适⽤于C51单⽚机。
模式1: 加减陈除模式2: 三⾓函数模式3: 阶乘,开⽅,e的x次⽅,log运算若有错误和不规范之处,还恳请各位看官多多指教。
经验吸取保留两位⼩数的时候由于c语⾔float精度、⽆符号整数和浮点数强制类型转换等问题,总是有误差。
我最后选择将结果加上0.005再进⾏强制类型转换(向下取整)从⽽模拟了四舍五⼊,问题得以解决。
long型很重要,单⽚机⾥float 和long型是4个字节,⽽int是2个字节若处理的数据⼤于255,不想溢出的话就不要⽤int调试的时候,可以使⽤在怀疑有错误的地⽅加上led显⽰,或者数码管显⽰的代码。
根据单⽚机上的显⽰来获取错误反馈。
代码/*Author: WuYE*/#include "reg52.h"#include "math.h"#include "string.h"typedef unsigned char u8;typedef unsigned int u16;#define GPIO_KEY P1 //定义数码管为P1引脚#define GPIO_DIG P0 //定义矩阵键盘引脚#define PI 3.14159sbit LSA = P2 ^ 2; //定义数码管引脚sbit LSB = P2 ^ 3; //sbit LSC = P2 ^ 4; //sbit k1 = P3 ^ 1; //定义独⽴按键引脚sbit k2 = P3 ^ 0; //sbit k3 = P3 ^ 2; //sbit k4 = P3 ^ 3; //u8 code numbertube[20] = { //定义数码管显⽰的数值0x3f, 0x06, 0x5b, 0x4f, 0x66, //显⽰0~9数字0x6d, 0x7d, 0x07, 0x7f, 0x6f, //0Xbf, 0x86, 0xdb, 0xcf, 0xe6, //显⽰0~9带⼩数点数字0xed, 0xfd, 0x87, 0xff, 0xbf //};u8 opkenkey = 0; //按下数码管不再显⽰0000u8 model = 0; //计算器模式为初始模式u8 AllowOutPutResult = 0; //默认不允许输出结果,因为不满⾜计算条件u8 numberseat = 0; //保存当前输⼊的数字的位数u8 number[4]; //保存输⼊的数字的数组u8 StopCalc = 0; //计算结束后就关闭计算器计算功能,但是按键检测功能仍然活跃。
基于51单片机的计算器设计
基于51单片机的计算器设计计算器作为一种常用的电子设备,广泛应用于各个领域。
在本文中,我们将基于51单片机来设计一个简单的计算器,并对其进行详细介绍。
一、设计目标我们所设计的计算器需要具备以下功能:1.实现基本的算术运算,包括加、减、乘、除等;2.具备显示功能,能够将输入和运算结果以数字的形式显示在液晶屏上;3.提供清零和删除功能,方便计算器的操作;4.具备较高的计算精度和稳定性。
二、硬件设计计算器的硬件设计主要包括键盘输入、液晶屏输出和计算程序控制三个部分。
1.键盘输入为了简化设计的复杂度,我们采用矩阵键盘来实现输入功能。
矩阵键盘由多个行和多个列交叉连接而成,通过扫描行和列的方式来检测键盘输入的按键信息。
2.液晶屏输出我们选择16x2字符液晶显示屏来作为计算结果的输出设备。
这种液晶屏可以显示16个字符,每个字符由5x8像素点阵组成,具备较好的显示效果。
3.计算程序控制我们将基于51单片机来编写计算器的计算程序,并通过电路连接键盘输入和液晶屏输出设备。
通过读取键盘输入的按键信息,计算程序能够判断用户输入的数字和操作符,并进行相应的计算操作。
最后,计算结果将以数字的形式显示在液晶屏上。
三、软件设计计算器的软件设计主要包括键盘扫描与输入处理、计算程序控制和液晶屏显示三个模块。
1.键盘扫描与输入处理通过循环扫描矩阵键盘的行和列,可以得到按键信息。
根据按键信息的不同,我们可以判断用户输入的数字和操作符,并将其传递给计算程序模块进行处理。
同时,我们需要对一些特殊按键(如清零和删除)做特殊处理。
2.计算程序控制计算程序模块将根据键盘输入的数字和操作符,进行相应的算术运算。
我们可以采用栈的数据结构来处理运算符和运算数,以实现复杂的算术运算。
3.液晶屏显示计算结果将以数字的形式显示在液晶屏上。
我们可以通过51单片机的GPIO口控制液晶显示屏的操作,包括写入指令和写入数据。
通过设定光标位置及写入数字数据,可以将计算结果显示在液晶屏的指定位置上。
51单片机控制lcd1602实现计算器
//利用51单片机控制LCD1602,实现加减乘除运算#include<reg52.h>#define uint unsigned int#define uchar unsigned char#define DATE_IO P0//P0口并行传输数据(LCD1602的数据端接P0口)sbit RS=P1^0;//LCD1602寄存器选择端sbit E=P1^2; //使能信号端sbit RW=P1^1;//读写控制端sbit deng=P1^3;//结果sbit shuzi11=P3^2;//前面的数字加1(因为我的按键是与P3口相连的)sbit shuzi22=P3^7; //后面的数字加1sbit jia=P3^3;//加号sbit jian=P3^4;//减号sbit cheng=P3^5;//乘号sbit chu=P3^6;//除号uint countqian=0,counthou=0;//数值uchar qian,bai,shi,ge,a=0;uchar code table1[]="0123456789";uchar code table2[]="+-*/";//**********************延时函数***************************************** void delay_us(unsigned int n){if(n==0)return ;while(--n);}void delay_ms(uint i){unsigned char a,b;for (a=1;a<i;a++)for(b=1;b;b++);}void delay(uint z){uint x,y;for(x=110;x>0;x--)for(y=z;y>0;y--);}//***********************************************************************//*********************控制LCD1602的函数*******************************void write_command(uchar come)//写指令函数{RS=0;//选择指令寄存器E=1;//由高电平跳变成低电平时,液晶执行命令DATE_IO=come;delay_us(5);E=0;RS=1;}void write_date(uchar date)//写数据函数{RS=1;//选择数据寄存器E=1;//由高电平跳变成低电平时,液晶执行命令DATE_IO=date;delay_us(5);E=0;RS=0;}//***************************************************************************** ***//**************************液晶初始化函数(基本上就是这个模式)*******************void init()//液晶初始化函数{RW=0;//低电平时进行写操作(高电平时进行读操作)E=0;write_command(0x38);//设置LCD两行显示,一个数据由5*7点阵表示,数据由8跟线传输delay_ms(5);write_command(0x01);//清除屏幕显示delay_ms(5);write_command(0x06);//设定输入方式,增量不移位delay_ms(5);write_command(0x0c);//开整体显示,关光标,不闪烁delay_ms(5);}//***************************************************************************** *****void jiayiqian()//前边数字加1计数函数{if(shuzi11==0)//如果前面加1的按键按下{delay(50);//消除抖动countqian=countqian+1;}if(countqian==999)//记到999归0countqian=0;}void jiayihou()//后边数字加1计数函数{if(shuzi22==0)//如果后面加1的按键按下{delay(50);//消除抖动counthou=counthou+1;}if(counthou==999)//记到999归0counthou=0;}void fuhao()//+,-,*,/运算号{if(jia==0)//如果加号按下{while(!jia);//等待按键的释放write_date(table2[0]);//显示'+'a=1;//加号按下的标志}if(jian==0)//如果减号按下{while(!jian);//等待按键的释放write_date(table2[1]);//显示'-'a=2;//减号按下的标志}if(cheng==0)//如果乘号按下{while(!cheng);//等待按键的释放write_date(table2[2]);//显示'*'a=3; //乘号按下的标志}if(chu==0)////如果除号按下{while(!chu);//等待按键的释放write_date(table2[3]);//显示'/'a=4;//除号按下的标志}}void chaiqian()//将前边各位数字拆开函数{bai=countqian/100;//求百位数字shi=countqian%100/10;//求十位数字ge=countqian%10;//求各位数字}void chaihou()//将后边各位数字拆开函数{bai=counthou/100;//求百位数字shi=counthou%100/10;//求十位数字ge=counthou%10;//求各位数字}void chaijiejia()//将相加结果各位数字拆开函数{qian=(countqian+counthou)/1000;//求千位数字bai=(countqian+counthou)%1000/100;//求百位数字shi=(countqian+counthou)%100/10;//求十位数字ge=(countqian+counthou)%10;//求各位数字}void chaijiejian()//将相减结果各位数字拆开函数{qian=(countqian-counthou)/1000;//求千位数字bai=(countqian-counthou)%1000/100;//求百位数字shi=(countqian-counthou)%100/10;//求十位数字ge=(countqian-counthou)%10;//求各位数字}void chaijiecheng()//将相乘结果各位数字拆开函数{qian=(countqian*counthou)/1000;//求千位数字bai=(countqian*counthou)%1000/100;//求百位数字shi=(countqian*counthou)%100/10;//求十位数字ge=(countqian*counthou)%10;//求各位数字}void chaijiechu()//将相除结果各位数字拆开函数(只取了模值){qian=(countqian/counthou)/1000;//求千位数字bai=(countqian/counthou)%1000/100;//求百位数字shi=(countqian/counthou)%100/10;//求十位数字ge=(countqian/counthou)%10;//求各位数字}void xianshiqian()//显示前边数字{write_command(0x80);//设置显示地址为LCD第一行,一旦首地址确定,显示完第一个数字后,光标会自动加1右移write_date(table1[bai]);//第一位显示百位write_date(table1[shi]); //第二位显示十位write_date(table1[ge]); //第三位显示个位fuhao();//显示运算号delay(50);//改变数值可以修改数字滚动的速度}void xianshihou()//显示后边数字{write_command(0x80+4);//设置显示地址为LCD第一行,一旦首地址确定,显示完第一个数字后,光标会自动加1右移write_date(table1[bai]);//第一位显示百位write_date(table1[shi]); //第二位显示十位write_date(table1[ge]); //第三位显示个位//delay(50);//改变数值可以修改数字滚动的速度}void xianshijie()//显示结果{write_command(0xc0);//设置显示地址为LCD第二行,一旦首地址确定,显示完第一个数字后,光标会自动加1右移write_date(table1[qian]);//第一位显示千位write_date(table1[bai]);//第二位显示百位write_date(table1[shi]); //第三位显示十位write_date(table1[ge]); //第四位显示个位//delay(50);//改变数值可以修改数字滚动的速度}void main()//主函数{init();//调用液晶初始化函数while(1){jiayiqian();//调用前边数字加1计数函数chaiqian();//调用将前边数字各位数字拆开函数xianshiqian();//显示前边数字jiayihou();//调用后边数字加1计数函数chaihou();//调用将后边数字各位数字拆开函数xianshihou();//显示后边数字if(deng==0)//控制显示结果的按键按下{if(a==1)//计算的是加法{chaijiejia();//将结果的各位数字拆分开xianshijie(); //显示结果}if(a==2)//计算的是减法{chaijiejian(); //将结果的各位数字拆分开xianshijie();//显示结果}if(a==3)//计算的是乘法{chaijiecheng();//将结果的各位数字拆分开xianshijie(); //显示结果}if(a==4) //计算的是除法{chaijiechu();//将结果的各位数字拆分开xianshijie(); //显示结果}}}}。
基于51单片机的简易计算器
基于51单片机的简易计算器51单片机是一种广泛应用于嵌入式系统中的常用微控制器。
我们可以利用51单片机的强大功能和丰富的外设资源,设计一个简易计算器。
这个计算器可以进行基本的加减乘除运算,并且具备显示结果的功能。
首先,我们需要准备一块51单片机开发板,一块1602液晶显示屏模块,以及一些按键开关和电阻。
我们可以将运算器主要分为以下几个模块:数码管显示模块、键盘输入模块、运算模块和存储模块。
数码管显示模块:我们使用1602液晶显示屏模块来显示计算器的结果。
我们可以通过51单片机的IO口,将计算结果发送给液晶显示屏模块,实现结果的显示。
键盘输入模块:我们可以使用几个按键开关来实现数字和运算符的输入。
通过对按键的检测,我们可以将用户输入的数字和运算符转化为字符形式,并保存到内存中。
运算模块:我们需要根据用户输入的数字和运算符,进行相应的运算。
我们可以使用栈来实现这个功能。
栈是一种常用的数据结构,具有"先进后出"的特点。
我们可以将用户输入的数字和运算符按照一定的规则入栈,然后按照相应的顺序进行出栈和运算。
最后将结果保存到内存中。
存储模块:我们可以使用内部RAM来保存运算结果。
51单片机的内部RAM具有一定的存储能力,可以满足我们的基本需求。
在编写程序时,我们可以使用汇编语言或者C语言。
通过合理的编程,我们可以实现计算器的各项功能。
总结一下,基于51单片机的简易计算器主要包括数码管显示模块、键盘输入模块、运算模块和存储模块。
我们可以通过合理的编程,将这些模块相互配合,实现一个功能完善的计算器。
这个计算器不仅可以进行基本的加减乘除运算,还可以显示结果,方便用户进行计算。
51单片机实现计算器程序
#include <reg52.h>#include <intrins.h>#include <math.h>#define uchar unsigned char#define uint unsigned intsbit LCD_RS=P2^2;//数据和命令端sbit LCD_EN=P2^0;//使能端sbit LCD_RW=P2^1;sbit CS1=P2^4;sbit CS2=P2^3;uint keytime,keyno[10];uint result,date1,date2,w_date1,w_date2;uint KeyNO1,opercha;uint date10n;uint date10n_d[16];uchar code hz[]={/*-- 文字: 数--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x10,0x92,0x54,0x38,0xFF,0x38,0x54,0x52,0x80,0xF0,0x1F,0x12,0x10,0xF0,0x10,0x00,0x42,0x42,0x2A,0x2E,0x13,0x1A,0x26,0x02,0x40,0x20,0x13,0x0C,0x33,0x60,0x20,0x00,/*-- 文字: 据--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x08,0x08,0x08,0xFF,0x88,0x40,0xFE,0x92,0x92,0x92,0xF2,0x92,0x92,0x9E,0x80,0x00,0x02,0x42,0x81,0x7F,0x40,0x30,0x0F,0xFC,0x44,0x44,0x47,0x44,0x44,0xFC,0x00,0x00,/*-- 文字: 结--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x20,0x30,0xAC,0x63,0x10,0x00,0x08,0x48,0x48,0x48,0x7F,0x48,0x48,0x48,0x08,0x00,0x22,0x23,0x22,0x12,0x12,0x00,0x00,0x7E,0x22,0x22,0x22,0x22,0x22,0x7E,0x00,0x00,/*-- 文字: 果--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x00,0x3E,0x2A,0x2A,0x2A,0xFE,0x2A,0x2A,0x2A,0x3E,0x00,0x00,0x00,0x00,0x21,0x21,0x11,0x11,0x09,0x05,0x03,0xFF,0x03,0x05,0x09,0x09,0x11,0x31,0x11,0x00};uchar code sz[]={0x00,0x00,0xF0,0xF8,0x08,0x68,0xF8,0xF0,0x00,0x00,0x07,0x0F,0x0B,0x08,0x0F,0x07, //0 0x00,0x20,0x20,0x30,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00, //1 0x00,0x30,0x38,0x08,0x88,0xF8,0x70,0x00,0x00,0x0C,0x0E,0x0B,0x09,0x08,0x08,0x00, //2 0x00,0x30,0x38,0x88,0x88,0xF8,0x70,0x00,0x00,0x06,0x0E,0x08,0x08,0x0F,0x07,0x00, //3 0x00,0x00,0xF8,0xF8,0x00,0xE0,0xE0,0x00,0x00,0x03,0x03,0x02,0x02,0x0F,0x0F,0x02, //4 0x00,0xF8,0xF8,0x88,0x88,0x88,0x08,0x00,0x00,0x08,0x08,0x08,0x0C,0x07,0x03,0x00, //5 0x00,0xC0,0xE0,0x78,0x58,0xC8,0x80,0x00,0x00,0x07,0x0F,0x08,0x08,0x0F,0x07,0x00, //6 0x00,0x08,0x08,0x88,0xE8,0x78,0x18,0x00,0x00,0x00,0x0E,0x0F,0x01,0x00,0x00,0x00, //7 0x00,0x70,0xF8,0xC8,0x88,0xF8,0x70,0x00,0x00,0x07,0x0F,0x08,0x09,0x0F,0x07,0x00, //8 0x00,0xF0,0xF8,0x08,0x08,0xF8,0xF0,0x00,0x00,0x00,0x09,0x0D,0x0F,0x03,0x01,0x00, //90x00,0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x00,0x00, //: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x00,0x00//.};/*******************************名称:delay()输入:延时数输出: 无功能:延时********************************/void delay(uint x){int y,z;for(y=x;y>0;y--)for (z=120;z>0;z--);}void write_c(uchar c) //写指令端{LCD_RW=0;LCD_RS=0;LCD_EN=1;P0=c;LCD_EN=0;delay(1);LCD_EN=1;}void write_d(uchar d)//写数据{LCD_RW=0;LCD_RS=1;LCD_EN=1;P0=d;LCD_EN=0;delay(1);LCD_EN=1;}void pianxuan(screen) //片选{switch(screen){case 0:CS1=0;CS2=0;break;case 1:CS1=1;CS2=0;break;case 2:CS1=0;CS2=1;break;case 3:CS1=1;CS2=1;break;}}void qinping(screen)//清屏,从第一行第一列开始{uint x,y; //页的设置位pianxuan(screen);//选择哪个清屏for(x=0xb8;x<0xc0;x++){write_c(x);//页初始值为0XB8到0xc0共八页write_c(0x40);//列的初始地址为0x40,共64列for(y=0;y<64;y++){write_d(0x00);//选择全部清屏}}}/*LCD显示汉字字库函数*/void lcd_display_hanzi(uchar screen,uchar page,uchar lie,uint mun) //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数{int i; //page页其实就是行,是行计数器页指针共九位计数器,高三位为X,低六位为Ymun=mun*32;pianxuan(screen) ; //片选看哪个段write_c(0x40+(lie*16)); //一个汉字占用两个字节write_c(0xb8+(page*2)); //一个字节显示for ( i=0;i<16;i++){write_d(hz[mun++]);}write_c(0x40+(lie*16));write_c(0xb8+(page*2)+1);for (i=0;i<16;i++){write_d(hz[mun++]);}}void lcd_display_shuzi(uchar screen,uchar page,uchar lie,uint mun) //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数{int i; //page页其实就是行,是行计数器页指针共九位计数器,高三位为X,低六位为Ymun=mun*16;pianxuan(screen) ; //片选看哪个段write_c(0x40+(lie*8)); //一个汉字占用两个字节write_c(0xb8+(page*2)); //一个字节显示for ( i=0;i<8;i++){write_d(sz[mun++]);}write_c(0x40+(lie*8));write_c(0xb8+(page*2)+1);for (i=0;i<8;i++){write_d(sz[mun++]);}}void LCD_init(){write_c(0x3f);// 显示开启write_c(0xc0); //显示起始行,从第一位开始,从0到63 write_c(0xb8);// 设置页得地址从0到7write_c(0x40); //设置列的地址,从第一位开始,从0到63 }/*******************************名称:GET_key()输入:无输出: 按键的相应数目功能:扫描按键********************************/uchar GET_key(){uchar Tmp,KeyNO;P1 = 0xf0;delay(1);Tmp = P1;switch(Tmp){case 0xe0: KeyNO = 3; break;case 0xd0: KeyNO = 2; break;case 0xb0: KeyNO = 1; break;case 0x70: KeyNO = 0;}P1 = 0x0f;delay(1);Tmp = P1;switch(Tmp){case 0x0e: KeyNO+= 12; break;case 0x0d: KeyNO+= 8; break;case 0x0b: KeyNO+= 4; break;case 0x07: KeyNO+= 0; break;default: break;}return(KeyNO);}void write_key(){uchar i,j,m,n;m = 7;n = 7;KeyNO1 = GET_key();if (KeyNO1>=0 && KeyNO1<=9){keytime++;}if (KeyNO1>=10 && KeyNO1<=13){/* keytime= keytime-1;for (j=keytime; j>=0;j--){if ((keytime-j) == 0)w_date1=keyno[keytime];else{for (k=0; k<keytime-j; k++){w_date1=keyno[keytime--]*10;}}date1=date1+w_date1;}*/keytime = 0;opercha = KeyNO1;}if (!(opercha>=10 && opercha<=13)){date1=0;if ((keytime-1) < 10 ){keyno[keytime-1] = KeyNO1;if (keytime-1>=0 && keytime-1 <= 7){for (i=keytime; i>0; i--){lcd_display_shuzi(1,0,m,keyno[i-1]);m--;if ((keytime-i) == 0){w_date1=keyno[i-1];}else{for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}}date1=date1+w_date1;}}else{for (i=keytime-8; i>0; i--){lcd_display_shuzi(2,0,n,keyno[i-1]);n--;for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}date1=date1+w_date1;}m=7;for (i=keytime; i>keytime-8; i--){lcd_display_shuzi(1,0,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date1=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}}date1=date1+w_date1;}}}}if ( (opercha>=10 && opercha<=13) && (KeyNO1 != 14) ) {date2=0;if ((keytime-1)<10 && (keytime-1)>=0){keyno[keytime-1] = KeyNO1;if (keytime-1 <= 7){for (i=keytime; i>0; i--){lcd_display_shuzi(1,1,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date2=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date2=keyno[i-1]*10;}}date2=date2+w_date2;}}else{for (i=keytime-8; i>0; i--){lcd_display_shuzi(2,1,n,keyno[i-1]);n--;for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}date2=date2+w_date2;}m=7;for (i=keytime; i>keytime-8; i--){lcd_display_shuzi(1,1,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date2=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date2=keyno[i-1]*10;}}date2=date2+w_date2;}}}}/*if (KeyNO1 == 15){keytime= keytime-1;for (j=keytime; j>=0;j--){if ((keytime-j) == 0)w_date2=keyno[keytime];else{for (i=0; i<keytime-j; i++){w_date2=keyno[keytime--]*10;}}date2=date2+w_date2;}} */if (opercha>=10 && opercha<=13){m=7;if (KeyNO1 == 14){switch(opercha){case 10:result=date1+date2;break;case 11:result=date1-date2;break;case 12:result=date1*date2;break;case 13:result=date1/date2;break;default:break;}for (i=1; ;i++){date10n=1;for (j=0; j<i-1; j++){date10n=date10n*10;}date10n_d[i-1]=(result / date10n) % 10;if (date10n*10>result){j=i;break;}}P3=result / date10n;for (i=0;i<j;i++){lcd_display_shuzi(1,2,m,date10n_d[i]);m--;}/* lcd_display_shuzi(1,2,7,result);P3 =opercha; */}}}void main(){keytime=0;date1=0;date2=0;w_date1=0;w_date2=0;result=0;opercha=0;KeyNO1=16;date10n=1;LCD_init();qinping(0);lcd_display_hanzi(2,0,0,0); //LCD显示汉字"数" //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数lcd_display_hanzi(2,0,1,1); //LCD显示汉字"据"lcd_display_shuzi(2,0,4,1); //LCD显示数字"1"lcd_display_shuzi(2,0,5,10);//LCD显示符号":"lcd_display_hanzi(2,1,0,0); //LCD显示汉字"数"lcd_display_hanzi(2,1,1,1); //LCD显示汉字"据"lcd_display_shuzi(2,1,4,2); //LCD显示数字"2"lcd_display_shuzi(2,1,5,10);//LCD显示符号":"lcd_display_hanzi(2,2,0,2); //LCD显示汉字"结"lcd_display_hanzi(2,2,1,3); //LCD显示汉字"果"lcd_display_shuzi(2,2,4,10);//LCD显示符号":"while(1){P1 = 0x0f;if (P1 != 0x0f){delay(1);if (P1 != 0x0f){write_key();while (P1 != 0x0f);}}}}。
怎样用51单片机做计算器啊?
怎样用51单片机做计算器啊?原理图51单片机简易计算器程序:#include <reg51.h>#include <math.h>#define uchar() unsigned char()#define uint unsigned int//---------定义引脚--------------------bit clr=0;bit ok=0;bit xiaoshu=0;bit jiego=0;bit first_1=1;bit first_2=1;sbit dout = P3^2;sbit load = P2^0;sbit din = P2^1;sbit dclk = P2^2;sbit beer=P0^1;sbit LCD1602_RS=P2^3;sbit LCD1602_RW=P2^4;sbit LCD1602_E=P2^5;//---------定义变量-------------------- uchar() ch451_key=0xff;uchar yun_sign;uchar xiabiao=0;uchar tab[32];uchar tab1[]={"welcome to use!"};uchar tab2[]={" make by JunRu!"};uchar tab3[]={"ERR0R"};float opr_1=0,opr_temp=0,end=0,a;//---------声明函数--------------------void ch451_init(void); //CH451初始化void ch451_write(uint command);//写命令或数据到ch451uchar ch451_read()(void); //读按键值uchar get_char(void);void LCD_init(void);//初始化;void delay(unsigned int k);//延时程序void LCD_inter_command(unsigned char command);//写入控制字void LCD_inter_dat(unsigned char dat);//写入要显示的数据void set_xy(unsigned char x,unsigned char y);//找地址void write(unsigned char date);//写入字符void lcdbusy();//查忙时void display()(void);void spec(void);void get_end(void);void hun_he(uchar n);//-------- 主函数----------------------void main(){uchar i;LCD_init();//LCD初始化;ch451_init();//CH451初始化EA = 1;//打开中断LCD_inter_command(0x01);//清屏for(i=0;i<=14;i++){LCD_inter_dat(tab1[i]);beer=0;delay(4000);//延时beer=1;}LCD_inter_command(0xc0);//从第二行开始显示for(i=0;i<=14;i++){LCD_inter_dat(tab2[i]);beer=0;delay(4000);//延时beer=1;}delay(0xffff);delay(0xffff);LCD_inter_command(0x01);while(1){if(ok){display()();ok=0;clr=1;}}}//----------子函数--------------------void hun_he(uchar n){int j;switch(n){case '+':opr_temp=opr_temp+opr_1;break;case '-':opr_temp=opr_temp-opr_1;break;case '*':opr_temp=opr_temp*opr_1;break;case '/':{if(a==0)//减数为零显错{ LCD_inter_command(0xc0);for(j=0;j<=4;j++){LCD_inter_dat(tab3[j]);beer=0;delay(4000);//延时beer=1;}}else{opr_temp=opr_temp/opr_1;}break;}default:break;}}void ch451_init(void)//CH451初始化{EX0 = 1;din = 0;din = 1;ch451_write(0x403); //开显示ch451_write(0x580); //BCD译码方式}void ch451_write(uint command)//写命令或数据到ch451 { uchar i;load = 0;for(i=0;i<12;i++){din = command&1;dclk = 0;command>>=1;dclk = 1;}load = 1;EX0 = 1;}uchar ch451_read()(void)//读按键值{ uchar key=0x07;uchar i;EX0=0;load = 0;for(i=0;i<4;i++) //将0111读入{din = key &1;dclk = 0;key>>=1;dclk =1;}load = 1;key = 0;for(i=0;i<7;i++) //从CH451读出按键值{key<<=1;key|= dout;dclk =1;}EX0 =1;return key;}void EX0_ISR(void)interrupt 0 //中断程序{uchar temp;ch451_key=ch451_read()(); //将读出的按键值赋给变量spec();if(clr) {LCD_inter_command(0x01);clr=0;}temp=get_char();if(temp){tab[xiabiao++]=temp; LCD_inter_dat(temp);}if(xiabiao>=16)LCD_inter_command(0xc0);//若大于16,则从第2行开始显示if(ok) get_end();beer=0;delay(3000);beer=1;}uchar get_char(void){uchar dis=0;uint temp=0,temp1=0;switch(ch451_key){case 0x40:dis='1';break;case 0x41:dis='2';break;case 0x42:dis='3';break;case 0x48:dis='4';break;case 0x49:dis='5';break;case 0x4A:dis='6';break;case 0x50:dis='7';break;case 0x51:dis='8';break;case 0x52:dis='9';break;case 0x58:dis='0';break;case 0x43:dis='+';break;case 0x4B:dis='-';break;case 0x53:dis='x';break;case 0x5B:dis='/';break;case 0x44:dis='!';break;case 0x5A:dis='=';ok=1; //遇到“=”,开始运算break;case 0x59:dis='.';break; //小数点case 0x5C: //删除键LCD_inter_command(0x01);xiabiao=0;break;default: break;}return dis;}void spec(void) //特殊功能键{switch(ch451_key){case 0x4C:LCD_inter_command(0x10);{if(xiabiao>0)xiabiao-=1;}break; //左移case 0x54:LCD_inter_command(0x14);{xiabiao+=1;}break; //右移default:break;}}void delay(unsigned int k)//延时程序{while (k--);}void LCD_inter_command(unsigned char command)//写入控制字{delay(5000);LCD1602_RS=0;LCD1602_RW=0;LCD1602_E=1;P1=command;LCD1602_E=0;lcdbusy();}void LCD_init(void)//初始化;{delay(5000);LCD_inter_command(0x01);//清屏delay(5000);LCD_inter_command(0x38);//设置为8位的数据接口,两行显示,5、7点字符delay(5000);LCD_inter_command(0x0E);//显示打开,光标开并闪烁delay(5000);}void LCD_inter_dat(unsigned char dat)//写入要显示的数据{delay(5000);LCD1602_RS=1;LCD1602_RW=0;LCD1602_E=1;P1=dat;LCD1602_E=0;lcdbusy();}void lcdbusy()//查忙{P1=0xFF;LCD1602_RS=0;LCD1602_RW=1;LCD1602_E=1;while((P1&0x80)==1);}void display()(void) //转化在LCD上显示计算结果{int temp=end; //浮点数int i;uint xiao_temp;uint xx; //浮点数的整数部分if (end>-32769&&end<32768){xx=fabs(end);xiao_temp=(fabs(end)-xx)*1000;//取出浮点数的小数部分LCD_inter_command(0xc0);if(end<0) LCD_inter_dat('-');beer=0;delay(4000); beer=1;//判断是否为负数,若是则显示负号if(xx>9999) LCD_inter_dat((xx/10000)%10+'0'); beer=0;delay (4000);beer=1;if(xx>999) LCD_inter_dat((xx/1000)%10+'0');beer=0;delay(40 00);beer=1; //在LCD上显示千位的数if(xx>99)LCD_inter_dat((xx/100)%10+'0'); beer=0;delay(400 0);beer=1;//百位if(xx>9)LCD_inter_dat((xx/10)%10+'0');beer=0;delay(4000); b eer=1;//十位LCD_inter_dat(xx%10+'0');beer=0;delay(4000); beer=1;//个位if(xiao_temp!=0) //显示小数部分{LCD_inter_dat('.');beer=0;delay(4000);beer=1;LCD_inter_dat((xiao_temp/100)%10+'0');beer=0;delay(4000); beer=1;LCD_inter_dat((xiao_temp/10)%10+'0');beer=0;delay(4000);b eer=1;LCD_inter_dat(xiao_temp%10+'0');beer=0;delay(4000);beer= 1;}}else {LCD_inter_command(0xc0);//从第二行开始显示for(i=0;i<=4;i++){ LCD_inter_dat(tab3[i]);beer=0;delay(4000);//延时beer=1;}}}void get_end(void)//计算子程序{ float xiaoshu=1;uchar fu_flag=0;uchar xiao_flag=0;uchar lianji_sign;uchar i=0;uchar j;uchar n;//正负标记符while(i<=xiabiao){while(tab[i]<=0x39&&tab[i]>=0x30){n=0;opr_1*=10;opr_1+=tab[i++]-0x30;n='+';}switch(tab[i]){case '.': xiao_flag=1;break;//遇到小数点跳到“if(xiao_flag)”里case '!': fu_flag=1;break;case '+': xiaoshu=1;yun_sign='+';if(opr_temp==0){end=opr _temp=opr_1;}else hun_he(lianji_sign);opr_1=0;lianji_sign='+'; br eak;case '-': xiaoshu=1;yun_sign='-';if(opr_temp==0){end=opr_temp=opr_1;}else hun_he(lianji_sign );opr_1=0;lianji_sign='-'; break;case 'x': xiaoshu=1;yun_sign='x';if(opr_temp==0){end=opr_temp=opr_1;}else hun_he(lianji_sign);opr_1=0;lianji_sign='*';brea k;case '/': xiaoshu=1;yun_sign='/';if(opr_temp==0){end=opr_ temp=opr_1;}else hun_he(lianji_sign);a=opr_1;opr_1=0;lianji_sig n='/';break;case '=':switch(yun_sign)//进行运算{case '+':end=opr_temp+opr_1;break;case '-':end=opr_temp-opr_1;break;case 'x':end=opr_temp*opr_1;break;case '/':{if(a==0)//减数为零显错{ LCD_inter_command(0xc0);for(j=0;j<=4;j++){LCD_inter_dat(tab3[j]);beer=0;delay(4000);//延时beer=1;}}else{end=opr_temp/opr_1;}break;}default:break;}ok=1;//开始进行显示,标志位置1xiabiao=0;//小数的标志位清零break;default:break;}i++;if(xiao_flag)//表示小数{while(tab[i]<=0x39&&tab[i]>=0x30){xiaoshu*=0.1;switch(n){case '+': opr_1=opr_1+(tab[i++]-0x30)*xiaoshu;break; case '-': opr_1=opr_1-(tab[i++]-0x30)*xiaoshu; break ; default:break; }xiao_flag=0;}}if(fu_flag){while(tab[i]<=0x39&&tab[i]>=0x30){n=0;opr_1=-opr_1*10;opr_1=-(opr_1+(tab[i++]-0x30));n='-';fu_flag=0;}}}opr_1=0;opr_temp=0; xiabiao=0; xiaoshu=1;下方为原理图:。
基于51单片机计算器设计
基于51单片机计算器设计计算器是一种常见的电子设备,可以进行数学运算、数据处理等功能。
本文将基于51单片机进行计算器设计。
一、设计目标:1.实现基本的数学运算功能,如加减乘除、取余等。
2.能够进行复杂的数学运算,如平方、开方等。
3.具备记忆功能,能够存储中间结果和运算符号。
4.设置输入界面,允许用户输入数字和操作符。
5.显示运算结果和中间过程。
二、硬件系统设计:1.使用51单片机作为主控芯片,具有高集成度和处理能力。
2.连接光栅液晶显示屏,用于显示数值和操作符。
3.连接矩阵键盘,用于获取用户的输入。
4.连接电源电路,保证计算器正常运行。
三、软件系统设计:1.确定界面设计,包括数值显示区、操作符显示区和功能键区。
2.设计输入处理模块,根据用户输入获取相应的数值和操作符,并进行相应的处理。
3.设计运算模块,根据用户输入的操作符进行相应的数学运算,并将结果存储起来。
4.设计显示模块,将计算结果和中间过程显示在液晶屏上。
5.设计存储模块,用来存储中间运算结果和操作符号。
四、软件流程设计:1.系统初始化:包括设置显示模式、清零中间结果等。
2.输入处理:通过矩阵键盘输入数字和操作符,并进行相应的处理。
3.运算处理:根据用户输入的操作符,进行相应的数学运算,并将结果存储起来。
4.结果显示:将计算结果和中间过程显示在液晶屏上。
5.存储结果:将计算结果和操作符存储起来,以备后续计算。
五、测试和调试:在设计完成后,需要进行系统测试和调试,确保计算器的各项功能正常运行。
首先进行单元测试,验证各个模块的功能是否按照设计要求正确执行。
然后进行综合测试,模拟用户输入各种情况下的运算过程,检测是否能够正确进行运算并显示结果。
如果发现问题,则进行调试和修改,直到计算器满足设计要求。
六、总结:基于51单片机进行计算器设计,可以实现基本的数学运算功能,并具备记忆功能。
设计步骤包括确定硬件系统和软件系统设计,设计界面、输入处理、运算处理、显示和存储模块,进行测试和调试确保计算器功能正常运行。
基于51单片机的简易计算器设计
基于51单片机的简易计算器设计基于51单片机的简易计算器设计一、引言随着微电子技术和嵌入式技术的发展,越来越多的智能化设备被应用于日常生活中。
其中,基于51单片机的简易计算器设计具有广泛的应用价值。
本文将介绍如何使用51单片机设计一个简易计算器,实现加减乘除的基本运算功能。
二、设计方案1.硬件组成:本设计采用51单片机作为主控芯片,与键盘、显示器等外围设备相连。
键盘用于输入数字和运算符,显示器则用于显示运算结果。
2.软件设计:软件部分包括主程序和子程序。
主程序负责初始化硬件、读取键盘输入和显示运算结果。
子程序包括加减乘除的运算子程序,可根据输入的运算符和操作数进行相应的运算。
3.算法实现:在加减乘除的运算子程序中,采用基本的数学运算方法实现。
对于加法,直接将两个操作数相加;对于减法,将两个操作数相减;对于乘法,采用循环相乘的方法;对于除法,采用循环相除的方法。
三、实验结果在实验中,我们成功地使用51单片机设计了一个简易计算器,实现了加减乘除的基本运算功能。
在测试过程中,我们输入了不同的数字和运算符,得到了正确的运算结果。
同时,我们也测试了计算器的稳定性,发现其在连续运算时表现良好,没有出现明显的误差或故障。
四、结论基于51单片机的简易计算器设计具有简单易行、实用性强等优点。
通过实验测试,我们验证了其可行性和稳定性。
此外,该设计还可以根据需要进行扩展和优化,例如增加更多的运算功能、优化算法等。
未来,我们可以进一步研究如何提高计算器的运算速度和精度,以及如何将其应用于更多的实际应用场景中。
五、改进意见与展望1.增加更多的运算功能:例如实现括号、开方、指数等高级运算,满足更复杂的数学计算需求。
2.优化算法:针对现有的加减乘除运算算法进行优化,提高运算速度和精度。
例如采用更高效的除法算法,减少运算时间。
3.增加存储功能:在计算器中加入存储单元,使得用户可以在多个步骤之间进行数据传递和保存。
4.增强人机交互界面:优化显示器的显示效果,增加用户输入的便捷性,提高用户体验。
51单片机简易计算器设计
51单片机简易计算器设计一、设计思路计算器的基本功能包括加法、减法、乘法和除法。
我们可以使用按键作为输入方式,将输入的数字和操作符暂时保存在内存中,然后根据操作符进行相应的运算。
最后再将运算结果显示在数码管上。
具体设计思路如下:1.确定计算器所需的硬件组件:数码管、按键、51单片机和相关电路。
2.定义按键与数字和操作符的对应关系。
3.编写51单片机的程序,实现按键输入、运算和结果显示的功能。
二、硬件设计1.数码管:使用常见的7段数码管作为显示器,通过引脚连接到51单片机的IO口。
2.按键:使用4个按键分别表示数字输入键、加法键、减法键和等于键。
三、软件设计1.初始化:将数码管引脚设为输出模式,将按键引脚设为输入模式。
2.按键处理:采用中断方式检测按键输入,通过编程判断所按的键。
3.数字输入:将按键所对应的数字保存在变量中,最多支持四位数的输入。
4.操作符输入:将按下的操作符保存在变量中。
5.运算:根据保存的操作符进行相应的运算,并将结果保存在变量中。
6.结果显示:将结果显示在数码管上。
四、代码实现下面是一个示例代码的框架,供参考:```c#include <reg52.h>sbit SDA = P0^0; // I2C总线数据线sbit SCL = P0^1; // I2C总线时钟线//定义按键的IO口sbit BUTTON0 = P1^0; // 数字输入键sbit BUTTON1 = P1^1; // 加法键sbit BUTTON2 = P1^2; // 减法键sbit BUTTON3 = P1^3; //等于键unsigned char num1 = 0; // 第一个操作数unsigned char num2 = 0; // 第二个操作数unsigned char op = 0; // 操作符unsigned char result = 0; // 运算结果//判断按键所对应的数字或操作符void buttonif (BUTTON0 == 0) // 数字输入键//将按键所对应的数字保存在变量中//显示数字}else if (BUTTON1 == 0) // 加法键//保存操作符为加号}else if (BUTTON2 == 0) // 减法键//保存操作符为减号}else if (BUTTON3 == 0) //等于键//根据保存的操作符进行相应的运算//将结果保存在变量中//显示结果}void mainwhile (1)button(; // 按键处理}```五、总结通过以上的设计思路和示例代码,我们可以轻松地实现一个简易的计算器。
51单片机实现计算器
#include<>#define uchar unsigned char#define uint unsigned intsbit dula=P2^6;sbit wela=P2^7;sbit B1=P2^3;sbit key1=P3^5;uchar SHZ[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};uint a,b,c,d,e,f,g,num,temp,k,pduan,jieguo,num1,num2,num3,num4,num5; void display7();void djp();void delay(uint z);void keyscan();void display1();void display2();void display3();void display4();void display5();void display6();void jia();void jian();void cheng();void chu();void deng();void qingchu();void main(){while(1){P3=0xff; //与独立键盘连用的关键djp();P3=0xff; //与独立键盘连用的关键keyscan();display7();}}void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void djp() //独立键盘{if(key1==0){delay(5);if(key1==0){num=0; //pduan=5;a=b=c=d=e=f=g=0;while(!key1);delay(5);while(!key1);}}}void display7(){if(num==0){display1();}if(num==1){if(a!=0)display1();}if(num==2){// if(b!=0)// {display1();display2(); // }// if(a!=0)// display1();}if(num==3){// if(c!=0)// {display1();display2();display3();/* }if(b!=0){display1();display2();}if(a!=0)display1();*/ }if(num==4){// if(d!=0)// {display1();display2();display3();display4();/* }if(c!=0){display1();display2();display3();}if(b!=0){display1();display2();}if(a!=0)display1();*/ }if(num==5){// if(e!=0)// {display1();display2();display3();display4();display5();/* }if(d!=0){display1();display2();display3();display4();}if(c!=0){display1();display2();display3();}if(b!=0){display1();display2();}if(a!=0)display1();*/ }if(num==6){// {display1();display2();display3();display4();display5();display6(); /* }if(e!=0){display1();display2();display3();display4();display5();}if(d!=0){display1();display2();display3();display4();}if(c!=0){display1();display2();display3();}{display1();display2();}if(a!=0)display1();*/}// if(pduan==5)// display1();if(num==7)num=6;}void jia(){pduan=1;num1=f*100000+e*10000+d*1000+c*100+b*10+a;num=0;a=b=c=d=e=f=g=0;}void jian(){pduan=2;num2=f*100000+e*10000+d*1000+c*100+b*10+a;num=0;a=b=c=d=e=f=g=0;}void cheng(){pduan=3;num3=f*100000+e*10000+d*1000+c*100+b*10+a;num=0;a=b=c=d=e=f=g=0;}void chu(){pduan=4;num4=f*100000+e*10000+d*1000+c*100+b*10+a;num=0;a=b=c=d=e=f=g=0;}void qingchu(){g=0;a=b;b=c;c=d;d=e;e=f;f=g;if(num==0){num=1;// pduan=5;}num--;}void deng(){num5=f*100000+e*10000+d*1000+c*100+b*10+a;num=0;if(pduan==1){jieguo=num5+num1;a=jieguo%10;b=jieguo%100/10;c=jieguo%1000/100;d=jieguo%10000/1000;e=jieguo%100000/10000;f=jieguo/100000;}if(pduan==2){jieguo=num2-num5;a=jieguo%10;b=jieguo%100/10;c=jieguo%1000/100;d=jieguo%10000/1000;e=jieguo%100000/10000;f=jieguo/100000;}if(pduan==3){jieguo=num5*num3;a=jieguo%10;b=jieguo%100/10;c=jieguo%1000/100;d=jieguo%10000/1000;e=jieguo%100000/10000;f=jieguo/100000;}if(pduan==4){jieguo=num4/num5;a=jieguo%10;b=jieguo%100/10;c=jieguo%1000/100;d=jieguo%10000/1000;e=jieguo%100000/10000;f=jieguo/100000;}if(f==0) //确定位数{if(e==0){if(d==0){if(c==0){if(b==0){if(a==0)num=0;else num=1;}else num=2;}else num=3;}else num=4;}else num=5;}else num=6;}void keyscan(){P3=0xfe; //第一部分temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);P3=0xfe;temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xee:g=1;f=e;e=d;d=c;c=b;b=a;a=g;num++;break;case 0xde:g=2;f=e;e=d;d=c;c=b;b=a;a=g;num++;break;case 0xbe:g=3;f=e;e=d;d=c;c=b;b=a;a=g;num++;break;case 0x7e:jia();break;}B1=0;temp=temp&0xf0;while(temp!=0xf0){temp=P3;temp=temp&0xf0;}delay(5);P3=0xff;B1=1;}}P3=0xfd; //第二部分temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);P3=0xfd;temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xed:g=4;f=e;e=d;d=c;c=b;b=a;a=g;num++;break;case 0xdd:g=5;f=e;e=d;d=c;c=b;b=a;a=g;num++;break;case 0xbd:g=6;f=e;e=d;d=c;c=b;b=a;a=g;num++;break;case 0x7d:jian();break;}B1=0;temp=temp&0xf0;while(temp!=0xf0){temp=P3;temp=temp&0xf0;}delay(5);P3=0xff;B1=1;}}P3=0xfb; //第三部分temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);P3=0xfb;temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xeb:g=7;f=e;e=d;d=c;c=b;b=a;a=g;num++;break;case 0xdb:g=8;f=e;e=d;d=c;c=b;b=a;a=g;num++;break;case 0xbb:g=9;f=e;e=d;d=c;c=b;b=a;a=g;num++;break;case 0x7b:cheng();break;}B1=0;temp=temp&0xf0;while(temp!=0xf0){temp=P3;temp=temp&0xf0;}delay(5);P3=0xff;B1=1;}}P3=0xf7; //第四部分temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);P3=0xf7;temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xe7:deng();break;case 0xd7:g=0;f=e;e=d;d=c;c=b;b=a;a=g;num++;if(num==1)num=0;break;case 0xb7:qingchu();break;case 0x77:chu();break;}B1=0;temp=temp&0xf0;while(temp!=0xf0){temp=P3;temp=temp&0xf0;}delay(5);P3=0xff;B1=1;}}}void display1(){wela=1; //第1个数字P0=0xdf;wela=0;P=0x00;dula=1;P0=SHZ[a];dula=0;delay(1);dula=1;P0=0x00;dula=0;P0=0xff;}void display2(){wela=1; //第2个数字P0=0xef;wela=0;P=0x00;dula=1;P0=SHZ[b];dula=0;delay(1);dula=1;P0=0x00;dula=0;P0=0xff;}void display3(){wela=1; //第3个数字P0=0xf7;wela=0;P=0x00;dula=1;P0=SHZ[c];dula=0;delay(1);dula=1;P0=0x00;dula=0;P0=0xff;}void display4(){wela=1; //第4个数字P0=0xfb;wela=0;P=0x00;dula=1;P0=SHZ[d];dula=0;delay(1);dula=1;P0=0x00;dula=0;P0=0xff;}void display5(){wela=1; //第5个数字P0=0xfd;wela=0;P=0x00;dula=1;P0=SHZ[e];dula=0;delay(1);dula=1;P0=0x00;dula=0;P0=0xff;}void display6(){wela=1; //第6个数字P0=0xfe;wela=0;P=0x00;dula=1;P0=SHZ[f];dula=0;delay(1);dula=1;P0=0x00;dula=0;P0=0xff; }。
基于51单片机计算器设计
基于51单片机计算器设计计算器是一种常用的计算工具,用来进行加减乘除等基本运算。
本文将介绍基于51单片机的计算器设计,主要包括功能设计、硬件设计和软件设计。
一、功能设计:1.基本计算功能:实现加法、减法、乘法和除法四种基本运算功能。
2.小数运算功能:支持小数的四则运算。
3.多位数运算功能:支持多位数的四则运算。
4.括号运算功能:支持括号运算,可以进行复杂的运算。
5.求平方功能:支持对一个数求平方。
6.求开方功能:支持对一个数求开方。
7.求倒数功能:支持对一个数求倒数。
8.清零功能:清零计算器,重新开始计算。
9.删除功能:删除输入的数字或者运算符。
二、硬件设计:硬件设计主要包括51单片机、LCD显示屏、矩阵按键、蜂鸣器和电源电路等。
1.51单片机:作为计算器的核心控制器,负责接收输入的数据和指令,并进行相应的计算和显示。
2.LCD显示屏:用于显示计算器的输入和输出结果。
3.矩阵按键:用于接收用户输入的数字和运算符。
4.蜂鸣器:用于发出提示音,比如输入错误时进行报警。
5.电源电路:提供计算器运行所需的电源。
三、软件设计:1.输入处理:计算器通过矩阵按键接收用户输入的数字和运算符,并使用数组保存输入的数据和指令。
2.数字运算:计算器需要根据用户输入的数字和运算符进行相应的运算,如加法、减法、乘法和除法等。
3.显示处理:计算器使用LCD显示屏将输入和计算结果显示出来。
4.错误处理:计算器需要对用户输入错误进行相应的处理,如输入非法字符时进行提示或报警。
5.性能优化:计算器需要进行相关的性能优化,如加入负责时间延迟,以适应不同的使用场景。
四、总结:本文介绍了基于51单片机的计算器设计,包括功能设计、硬件设计和软件设计。
这种计算器可以实现基本的四则运算功能,并支持小数运算、多位数运算和括号运算等复杂运算。
通过合理的硬件设计和软件设计,可以使得计算器更加稳定和可靠。
这种设计不仅可以提高计算器的使用体验,还可以为用户提供更多的计算功能和更加便捷的计算方式。
51单片机实现的简易计算器
51单片机实现的简易计算器1. 4X4键盘输入,点阵字符型液晶显示。
2. 由于所采用的浮点程序库的限制(MCU平台只找到这个……),浮点运算采用3字节二进制补码表示,有效数字6位。
对于输入输出,采用3字节BCD码浮点数格式,有效数字只有4位,因此最终有效数字只有4位。
3. 可进行连续输入,例如:1.23+4.56*8.23/234.8 ,但是运算结果为从左到右,这也是8位简易计算器的方式。
4. 可进行错误判断,溢出、除零等错误将显示一个字符E 。
5. 由于键盘只有16个按键,安排如下:+---------------+| 7 | 8 | 9 | + || 4 | 5 | 6 | - || 1 | 2 | 3 | * || 0 | . | = | / |+---------------+6. 按键的缺少导致取消了一些特殊函数,即开根号,三角函数(sin, cos, tan, ctg)的实现,由于这些函数在浮点程序库中均已提供,如果硬件允许,在原来的框架上添加这些附加功能是很容易的(可以看作和+, -, *, /等价的按键操作,调用不同的子程序进行运算即可)7. 按两次= 等于清灵。
因为按键实在太少,才采用了这个做法。
8. 相应举例:按键结果说明- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -123+= 123 按下等号而没有第二个操作数,保留第一个操作数并认为此次运算结束(等号的功能)123+321/111 4.0 等价于(123+321) / 1112.3+5.4=/0.1+ 77 等号后直接按 / ,则将前面的运算结果作为第一个操作数1/0= E 错误显示9. 不足使用3字节的浮点数表示,不可避免的带来了数表示的不精确,加上有效数字比较少,因此计算结果很容易产生误差,尤其是进行连续多次运算后,结果和精度较高的科学计算器的误差会很快达到0.01以上,当然这个差距和所测试的用例也有关系,4位有效数字导致了数字123456只能表示为123400,最后两位有效数字被摒弃了。
基于51单片机的计算器设计
基于51单片机的计算器设计一、引言计算器(Calculator)是一种专用的电子计算设备,用于简便地进行基本数学计算。
随着科技的发展,计算器的功能也逐渐丰富,并在日常生活中得到广泛应用。
本文将介绍一种基于51单片机的计算器设计方案,以满足人们对计算器的基本需求。
二、设计方案1.硬件设计(1)51单片机:作为计算器的核心,负责处理各项计算任务。
(2)显示屏:用于显示用户输入的数据和计算结果。
(3)按键模块:用于接收用户输入的数字和操作符。
(4)存储器:用于存储用户输入的数据和计算结果。
(5)电源模块:用于为计算器供电。
2.软件设计计算器的软件设计主要包括输入处理、运算处理和输出显示三个模块。
(1)输入处理:当用户按下数字键或操作符键时,计算器会根据当前输入的字符进行相应的处理。
例如,数字键按下后,将数字添加到当前输入的数字中;操作符键按下后,将当前输入的数字和操作符添加到存储器中。
(2)运算处理:当用户按下等号键时,计算器会根据存储器中的数字和操作符进行相应的运算处理。
例如,当存储器中包含两个数字和一个操作符时,计算器会根据操作符进行相应的运算,并将结果保存到存储器中。
(3)输出显示:当计算器完成运算处理后,将结果显示在显示屏上供用户查看。
同时,计算器还需要提供清除键和退格键等功能,以方便用户进行操作。
三、实现步骤1.初始化:将51单片机的各引脚设置为输入或输出,并设置相应的初始参数。
同时,初始化存储器、显示屏和按键模块等硬件设备。
2.输入处理:通过按键模块检测用户输入,并根据当前输入的字符进行相应的处理。
例如,当用户按下数字键时,将数字添加到当前输入的数字中;当用户按下操作符键时,将当前输入的数字和操作符添加到存储器中。
3.运算处理:当用户按下等号键时,计算器会根据存储器中的数字和操作符进行相应的运算处理。
例如,当存储器中包含两个数字和一个操作符时,计算器会根据操作符进行相应的运算,并将结果保存到存储器中。
基于51单片机的简易教学计算器设计
基于51单片机的简易教学计算器设计设计目的:本设计旨在基于51单片机实现一个简易的教学计算器,可以进行基本的四则运算,并具备一些辅助功能,帮助学生进行数学计算和学习。
设计要求:1.显示器:使用液晶显示器(LCD)来显示操作数和计算结果。
2.键盘输入:设计一个按键矩阵作为输入设备,用于输入数字和操作符。
3.四则运算:实现加法、减法、乘法和除法四种基本运算。
4.辅助功能:提供开平方、取倒数等辅助功能。
5.界面友好:界面清晰、操作简单。
硬件设计:1.51单片机(AT89C52):作为计算器的核心芯片,控制程序运行和与外围设备的交互。
2.液晶显示器(LCD):用于显示操作数和计算结果。
3.按键矩阵:用于输入数字和操作符。
4.运算模块:用于进行四则运算和辅助功能计算。
软件设计:1.系统初始化:初始化51单片机和LCD屏幕,设置键盘矩阵的引脚。
2.输入处理:通过按键矩阵检测用户输入,并将输入的字符存储在缓冲区中。
3.表达式计算:根据用户输入的表达式,通过逆波兰表达式算法将其转换为后缀表达式,并进行计算得到结果。
4.显示结果:将计算结果显示在LCD屏幕上。
5.辅助功能:根据用户选择的辅助功能,进行相应的计算,并显示结果。
6.重置功能:提供清零功能,将计算器的状态和显示结果重置。
操作流程:1.系统初始化:开机时,系统进行初始化,屏幕显示“计算器”字样。
2.输入操作数和操作符:用户通过按键矩阵输入操作数和操作符。
3.计算结果:用户输入“=”符号后,计算器根据输入的表达式进行计算,并将结果显示在LCD屏幕上。
4.辅助功能:在计算结果显示完成后,用户可选择进行辅助功能,如开平方、取倒数等操作。
5.重置功能:用户可通过按下“C”键进行重置,将计算器状态和显示结果清零。
总结:本设计基于51单片机实现了一个简易的教学计算器,具备基本的四则运算功能和一些辅助功能。
其使用液晶显示器作为显示设备,利用按键矩阵进行输入操作,通过逆波兰表达式算法进行计算,并将结果显示在屏幕上。
基于51单片机简易计算器课程设计报告
基于51单片机简易计算器课程设计报告引言:计算器是现代社会中常见的电子设备之一,它能够帮助人们进行各种数学运算,提高计算效率。
本文将介绍基于51单片机的简易计算器的设计过程及实现方法。
一、设计目标本次设计的目标是实现一个简易计算器,能够进行基本的加减乘除运算,并能够显示计算结果。
通过该设计,旨在加深学生对51单片机的理解,培养其实际操作能力。
二、硬件设计1. 电源模块:采用稳压电源模块,提供稳定的电压给单片机及其他电路模块。
2. 单片机模块:采用51单片机,作为计算器的核心控制模块,负责接收按键输入、进行运算和显示结果。
3. 按键模块:设计合适的按键电路,用于输入数字和操作符。
4. 显示模块:采用数码管或液晶显示屏,显示计算结果。
5. 连接线:将各个模块连接起来,确保信号的传输畅通。
三、软件设计1. 初始化:设置单片机的工作模式、端口方向和初始状态。
2. 按键扫描:通过轮询的方式检测按键是否被按下,若有按键按下则进行相应的处理。
3. 输入处理:根据按键的顺序和操作符的位置进行输入的处理,将输入的数字和操作符分别存储在相应的变量中。
4. 运算处理:根据输入的操作符进行相应的运算,得出计算结果。
5. 结果显示:将计算结果通过数码管或液晶显示屏进行显示。
6. 清零处理:在计算结果显示完毕后,对相关的变量进行清零处理,以便进行下一次的计算。
四、功能实现1. 加法运算:通过按下"+"按键,输入第一个数字,再按下"="按键,输入第二个数字,最后按下"="按键,计算并显示结果。
2. 减法运算:通过按下"-"按键,输入第一个数字,再按下"="按键,输入第二个数字,最后按下"="按键,计算并显示结果。
3. 乘法运算:通过按下"*"按键,输入第一个数字,再按下"="按键,输入第二个数字,最后按下"="按键,计算并显示结果。
新基于51单片机的简易计算器
新基于51单片机的简易计算器一、引言计算器是一种广泛应用的电子设备,用于进行常见的数值运算。
在现代社会,计算器是广大人们日常生活和学习中常用的工具之一、本文将介绍一种新基于51单片机的简易计算器的设计和实现,该计算器具有计算基本四则运算的功能,并且操作简便、界面友好。
二、设计实现1.系统硬件设计该计算器的硬件主要由51单片机、LCD显示屏、按键开关、电源等组成。
(1)51单片机:使用51系列单片机作为计算器的核心处理器,它具有处理能力强、易编程等特点,可以快速实现计算功能。
(2)LCD显示屏:采用16*2字符LCD显示屏,用于显示计算结果和用户输入的数字。
(3)按键开关:设置数字键盘开关、运算符键盘开关、等号键开关等,用户通过按下对应的按键输入数字和运算符。
(4)电源:使用直流电源供电,通过稳压电路和滤波电路提供稳定的电压和电流。
2.系统软件设计该计算器的软件主要由嵌入式C语言编写,实现了计算基本四则运算的功能。
(1)初始化:在系统启动时对各个设备进行初始化设置,包括LCD显示屏的初始化、按键开关的初始化等。
(2)用户输入:通过按键开关读取用户输入的数字和运算符,将其保存在缓冲区中。
(3)计算功能:根据用户输入的数字和运算符,通过判断运算符的类型进行相应的数值计算,并将结果保存在特定的寄存器中。
(4)结果显示:将计算结果从寄存器中读取并显示在LCD显示屏上,用户可以直观地看到计算结果。
三、系统特点1.硬件结构简单:该计算器的硬件结构简单,主要由几个常见元件组成,易于制作和调试。
2.操作简便:用户只需通过按键输入数字和运算符,即可完成计算操作,无需进行复杂的设置和调试。
3.界面友好:通过LCD显示屏直观地显示计算结果,用户可以清楚地了解计算过程和结果。
4.功能强大:该计算器可以进行基本的四则运算,满足大多数日常计算需求。
四、应用范围该简易计算器可以广泛应用于日常生活和学习中,包括商品购物计算、数学运算、财务统计等场景。
(完整)基于51单片机的简易计算器设计
(完整)基于51单片机的简易计算器设计基于51单片机的简易计算器设计计算器作为一种常见的电子设备,既能满足日常生活的计算需求,又能帮助人们提高工作效率。
本文将介绍基于51单片机的简易计算器的设计。
该计算器具备加减乘除的基本计算功能,并支持用户输入和结果显示。
下面将从材料准备、电路连接和程序设计三个方面详细介绍该计算器的设计。
一、材料准备在设计计算器之前,我们需要准备以下材料:1. 51单片机开发板:用于控制计算器的整个运行过程;2. 液晶显示屏:用于显示用户输入的数字和计算结果;3. 数字按键:用于用户输入数字和运算符;4. 连接线:用于连接51单片机开发板、液晶显示屏和数字按键。
二、电路连接1. 连接液晶显示屏和51单片机开发板:将液晶显示屏的VCC、GND、SCL和SDA引脚分别与开发板上对应的引脚连接。
2. 连接数字按键和51单片机开发板:将数字按键的引脚依次与开发板上的IO口引脚连接,其中有一根引脚需要连接到开发板的中断口。
三、程序设计1. 初始化设置:在程序开始时,进行液晶显示屏和数字按键的引脚初始化设置,以及相应的中断设置。
2. 输入处理:通过数字按键输入,获取用户输入的数字和运算符,并将其保存到相应的变量中。
3. 运算处理:根据用户输入的运算符,对相应的数字进行加、减、乘、除的运算,并将结果保存到一个变量中。
4. 结果显示:将运算结果显示在液晶显示屏上,以便用户查看计算结果。
5. 重置处理:在每次运算结束后,对相关变量进行重置,以便下一次计算。
通过以上程序设计,我们可以完成基于51单片机的简易计算器的设计。
在实际使用过程中,用户只需要通过数字按键输入相应的数字和运算符,计算器就可以自动进行运算,并将结果显示在液晶显示屏上,方便用户进行查看。
总结本文介绍了基于51单片机的简易计算器的设计。
通过合理的材料准备、电路连接和程序设计,我们可以实现一个具备加减乘除功能的计算器。
该计算器不仅能满足人们日常的计算需求,还能帮助提高工作效率。
基于51单片机的简易计算器设计
基于51单片机的简易计算器设计设计一个基于51单片机的简易计算器,主要功能包括加减乘除四则运算和百分数计算。
下面是设计的详细步骤:1.硬件设计:-使用51单片机作为主控芯片。
-连接16x2的LCD显示屏,用于显示输入和计算结果。
-连接16个按键开关,用于输入运算符和数字。
-连接4个LED灯,用于指示四则运算的选择。
2.软件设计:-初始化LCD显示屏,并显示欢迎信息。
-监听按键输入,在接收到输入后,根据输入的按键值判断操作类型。
-如果按键值对应数字键,保存输入的数字,并在LCD上显示当前输入的数字。
-如果按键值对应四则运算符(+、-、*、/),保存当前输入的数字,并保存运算符。
-如果按键值对应等号(=),根据保存的数字和运算符进行相应的运算,计算结果保存并显示在LCD上。
-如果按键值对应清零(C),将所有保存的数据清空,并显示初始状态。
-如果按键值对应百分号(%),将当前数字除以100并显示在LCD上。
3.主要函数说明:- void init_lcd(:初始化LCD显示屏。
- void display_lcd(char* str):将指定字符串显示在LCD上。
- void clear_lcd(:清空LCD显示屏。
- char get_key(:获取按键输入的值。
- void calculate(:根据保存的数字和运算符进行计算。
- void add_digit(char digit):将输入的数字添加到当前数字中。
- void set_operator(char op):保存运算符。
- void clear_data(:清空所有保存的数据。
4.主要流程:-初始化LCD显示屏并显示欢迎信息。
-在循环中监听按键输入,并根据输入的按键值进行相应的操作。
-根据不同的按键值,调用不同的函数进行处理。
-最后计算结果显示在LCD上。
以上是基于51单片机的简易计算器设计的详细步骤和主要函数说明。
你可以根据这个设计框架进行具体的代码实现。
基于51单片机的简易计算器设计
基于51单片机的简易计算器设计一、引言计算器是一种执行基本数学运算的电子设备,现在市面上有各种类型的计算器,从小型的手持计算器到大型的科学计算器。
本设计基于51单片机设计了一种简易计算器,可以实现加法、减法、乘法和除法等基本运算。
二、设计思路1.系统硬件设计本设计使用的51单片机芯片选择了常用的STC89C52芯片,具有强大的功能和稳定性。
外设有键盘、数码管和LCD液晶显示屏。
2.系统软件设计系统的软件设计基于C语言进行,使用51单片机的汇编语言和C语言进行编程。
软件主要分为键盘输入处理、运算处理和结果显示三个部分。
三、系统硬件设计1.键盘输入部分使用4x4矩阵键盘作为输入设备,将键盘的4行4列分别接入到51单片机的4个IO口上,通过行列扫描的方式来检测按键的状态。
2.数码管显示部分使用共阳极的数码管来显示结果,通过提供适当的电压和信号控制来显示所需的数字。
3.LCD液晶显示屏为了方便用户查看输入和结果,本设计还使用了LCD液晶显示屏。
通过串口通信将结果传输到液晶显示屏上进行显示。
四、系统软件设计1.键盘输入处理通过行列扫描的方式检测键盘的按键状态,当检测到按键按下时,将对应的按键值存储起来。
2.运算处理根据用户的输入进行相应的运算处理。
根据检测到的按键值进行不同的运算操作,如加法、减法、乘法和除法。
3.结果显示将运算的结果通过串口通信传输到LCD液晶显示屏上进行显示。
五、系统实现1.硬件连接将键盘的行列引脚接到51单片机的对应IO口上,数码管和LCD液晶显示屏也分别连接到单片机的IO口上。
2.软件编码通过C语言编写系统软件,包括键盘输入处理、运算处理和结果显示三个模块。
3.调试测试将编写好的软件烧录到单片机上,通过键盘输入进行测试,并观察数码管和LCD液晶显示屏上的输出结果。
六、总结本设计基于51单片机实现了一个简易计算器,通过键盘输入进行基本的运算操作,并将结果通过数码管和LCD液晶显示屏进行显示。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
51单片机多为计算器汇编程序此程序并不仅仅局限于255以内操作FIR0 EQU 30HFIR1 EQU 31HFIR2 EQU 32HFIR3 EQU 33H ;第一个操作数SEC0 EQU 34HSEC1 EQU 35HSEC2 EQU 36HSEC3 EQU 37H ; 第二个操作数LIN0 EQU 38HLIN1 EQU 39HLIN2 EQU 40HLIN3 EQU 41H ; 数据暂存RES0 EQU 42HRES1 EQU 43HRES2 EQU 44HRES3 EQU 45H ;结果暂存区XLINE EQU 46HYLINE EQU 47H ;记录按键按键位置SYMBLE EQU 48H ;操作符存储DDE0 EQU 49HDDE1 EQU 50HDDE2 EQU 51H ;用于延时FLEL4 EQU 52HFLEL5 EQU 53HFLEL6 EQU 54HBEFOR EQU 55HHH BIT 01H ;比较大EE BIT 02H ;比较相等FIL BIT 03H ;溢出标记FLAG BIT 04H ;有无按键标记ERR BIT 05H ;错误标记YESY BIT 06H ; 有无操作符按键标记NUM BIT 07H ;按键个数标记YESN BIT 08H ;有无数字按键标记ORG 0000HLJMP MAINORG 0003HLJMP INTERUPTMAIN:MOV IE,#01H ;初始化MOV SP,#6FHLCALL CLRISETB IT0SETB EADISPLAY: ;数码管显示函数CJNE R3,#00H,TT1MOV R3,#0AHTT1: CJNE R3,#0AH,STARTDCJNE R2,#00H,TT2MOV R2,#0AHTT2: CJNE R2,#0AH,STARTDCJNE R1,#00H,STARTDMOV R1,#0AHSTARTD: MOV A,R0LCALL TRANS ;将所要显示的值转化为数码管对应的数据MOV P2,AMOV P1,#10HLCALL DELAY10msMOV A,R1LCALL TRANSMOV P2,AMOV P1,#20HLCALL DELAY10msMOV A,R2LCALL TRANSMOV P2,AMOV P1,#40HLCALL DELAY10msMOV A,R3LCALL TRANSMOV P2,AMOV P1,#80HLCALL DELAY10msMOV A,P0ANL A,#0F0HCJNE A,#0F0H,YESYESLJMP LOOP8YESYES: LCALL INTERUPTJNB FLAG,LOOP8CLR FLAGLCALL LOCATIONLCALL KEYLOOP8: LJMP DISPLAY/////////////////////////////////////////////// INTERUPT: ;确定有无按键CLR FLAGMOV XLINE,#00HMOV YLINE,#00H ;初始化LCALL DELAY100msMOV A,P0 ;判断是否有按键按下ANL A,#0F0HCJNE A,#0F0H,YESLJMP LOOP7YES: SETB FLAG ;是按键,置位标记位,及行列线MOV XLINE, P0MOV YLINE, P1LOOP7: RETILOCATION: ;确定按键位置CLR FLAGMOV R6,#00H ;初始化MOV A,XLINE ;取出行线的高四位,存入R7中ANL A,#0F0HMOV R6,AMOV R7,#05H ;循环比较次数MOV P1,#01H ;P1口重新初始化COMPARE: ;循环比较,查找按键位置MOV A,P0ANL A,#0F0HCJNE A,#0F0H,TIMEMOV A,P1ANL A,#0FHADD A,R6MOV R6,A ;确定按键位置LJMP LOOP9;TIME: ;比较次数以及为下次循环做准备MOV A,P1RL AMOV P1,ADJNZ R7,COMPARELOOP9: RET;////////////////////乘法程序///////////////////////////////////////////////////// MULI: ;将第二个操作数的第一位一次与第一个操作数相乘CLR ERRMOV RES0,#00HMOV RES1,#00HMOV RES2,#00HMOV RES3,#00HMOV FLEL4,#00HMOV FLEL5,#00HMOV FLEL6,#00H ;初始化处理MOV A,SEC0 ;判断第一位是否为0JZ SECOND ;为0,进行下一位操作MOV A,FIR0MOV B,SEC0MUL ABMOV RES0,A ;将乘积放入对应的结果存储区中MOV A,FIR1MOV B,SEC0MUL ABMOV RES1,AMOV A,FIR2MOV B,SEC0MUL ABMOV RES2,AMOV A,FIR3MOV B,SEC0MUL ABMOV RES3,ALCALL DEALJB FIL,BBSECOND: MOV A,SEC1 ;第二位操作JZ THIRD ;判断第二位是否为0,MOV A,FIR0MOV B,SEC1MUL ABADD A,RES1 ;结果从第二位开始存起MOV RES1,AMOV A,FIR1MOV B,SEC1MUL ABADD A,RES2MOV RES2,AMOV A,FIR2MOV B,SEC1MUL ABADD A,RES3MOV RES3,AMOV A,FIR3MOV B,SEC1MUL ABADD A,FLEL4MOV FLEL4,ALCALL DEALJB FIL,BBLJMP THIRDBB: LJMP FILEDTHIRD: MOV A,SEC2JZ FOURTHMOV A,FIR0 ;计算结果从第三位开始存储MOV B,SEC2MUL ABADD A,RES2MOV RES2,AMOV A,FIR1MOV B,SEC2MUL ABADD A,RES3MOV RES3,AMOV A,FIR2MOV B,SEC2MUL ABADD A,FLEL4MOV FLEL4,AMOV A,FIR3MOV B,SEC2MUL ABADD A,FLEL5MOV FLEL5,ALCALL DEALJB FIL,FILEDFOURTH: MOV A,SEC3JZ LOOP1MOV A,FIR0MOV B,SEC3 ;计算结果从第四位开始存储MUL ABADD A,RES3MOV RES3,AMOV A,FIR1MOV B,SEC3MUL ABADD A,FLEL4MOV FLEL4,AMOV A,FIR2MOV B,SEC3MUL ABADD A,FLEL5MOV FLEL5,AMOV A,FIR3MOV B,SEC3MUL ABADD A,FLEL6MOV FLEL6,ALCALL DEALJB FIL,FILEDLJMP LOOP1FILED: SETB ERRLOOP1: RET////////////////////////////////////////////////////////////////////////////////////////////////// /////////////加法程序///////////////////////ADDI:CLR ERR ;初始化处理MOV A,FIR0ADD A,SEC0MOV RES0,A ;第一位相加MOV A,FIR1ADD A,SEC1MOV RES1,A ;第二位相加MOV A,FIR2ADD A,SEC2MOV RES2,A ;第三位相加MOV A,FIR3ADD A,SEC3MOV RES3,A ;第四位相加LCALL DEALJB FIL,FILED1LJMP LOOP2FILED1:SETB ERRLOOP2: RET//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////除法程序////////////////////////////////////////////////DIVI:CLR ERRMOV LIN3,FIR3MOV LIN2,FIR2MOV LIN1,FIR1MOV LIN0,FIR0MOV FIR3,#00HMOV FIR2,#00HMOV FIR1,#00HMOV FIR0,#00H ;初始化处理MOV A,SEC0CJNE A,#00H,STARTMOV A,SEC1CJNE A,#00H,STARTMOV A,SEC2CJNE A,#00H,STARTMOV A,SEC3CJNE A,#00H,STARTSETB ERRLJMP LOOP4 ;判断除数是否为0START: MOV R7,#01HCLR ERRFIST:MOV FIR3,R7LCALL MULI ;第一次小JB ERR,DEAL3LCALL COMPJB EE,EQUUU ;相等,结束JB HH,DEAL3;结果大MOV A,R7INC AMOV R7,ACJNE R7,#0AH,FISTDEAL3: MOV A,R7DEC AMOV FIR3,AMOV R7,#01HCLR ERRCLR HHSECD: MOV FIR2,R7LCALL MULIJB ERR,DEAL2LCALL COMPJB EE,EQUUUJB HH,DEAL2MOV A,R7INC AMOV R7,ACJNE R7,#0AH,SECDDEAL2: MOV A,R7DEC AMOV FIR2,AMOV R7,#01HCLR ERRCLR HHTHID: MOV FIR1,R7LCALL MULIJB ERR, DEAL1LCALL COMPJB EE,EQUUUJB HH,DEAL1MOV A,R7INC AMOV R7,ACJNE R7,#0AH,THIDDEAL1:MOV A,R7DEC AMOV FIR1,AMOV R7,#01HCLR ERRCLR HH FORTH: MOV FIR0,R7LCALL MULIJB ERR,DEAL0LCALL COMPJB EE,EQUUUJB HH,DEAL0MOV A,R7INC AMOV R7,ACJNE R7,#0AH,FORTHDEAL0: MOV A,R7DEC AMOV FIR0,ACLR ERREQUUU: MOV RES0,FIR0MOV RES1,FIR1MOV RES2,FIR2MOV RES3,FIR3RETLOOP4: SETB ERRRET//////////////////////////////////////////////////////////////////////////////////// /////////////////////减法程序///////////////////////////////////////SUBBI:CLR ERRMOV A,FIR0CJNE A,SEC0,DE0 ;判断是否相等MOV RES0,#00H ;相等,结果置0LJMP SECDDDE0: JC DE00 ;判断是否需要借位SUBB A,SEC0 ;无需借位MOV RES0,ALJMP SECDDDE00: MOV A,FIR1CJNE A,#00H,NEXT1;判断十位是否可借MOV A,FIR2CJNE A,#00H,NEXT2; 判断百位是否可借MOV A,FIR3CJNE A,#00H,NEXT3 ; 判断千位是否可借SETB ERR ;没有借位,清空MOV A,FIR0ADD A,#0AHSUBB A,SEC0MOV RES0,ALJMP SECDDNEXT2:DEC FIR2MOV FIR1,#09HMOV A,FIR0ADD A,#0AHSUBB A,SEC0MOV RES0,ALJMP SECDDNEXT3:DEC FIR3MOV FIR1,#09HMOV FIR2,#09HMOV A,FIR0ADD A,#0AHSUBB A,SEC0MOV RES0,ASECDD:MOV A,FIR1CJNE A,SEC1,DE1 ;判断是否相等MOV RES1,#00H ;相等,结果置0LJMP THIDDDE1: JC DE11 ;判断是否需要借位SUBB A,SEC1 ;无需借位MOV RES1,ALJMP THIDDDE11: MOV A,FIR2CJNE A,#00H,NEXT22; 判断百位是否可借MOV A,FIR3CJNE A,#00H,NEXT23 ; 判断千位是否可借SETB ERR ;没有借位,清空NEXT22:DEC FIR2MOV A,FIR1ADD A,#0AHSUBB A,SEC1MOV RES1,ALJMP THIDDNEXT23:MOV FIR2,#09HMOV A,FIR1ADD A,#0AHSUBB A,SEC1MOV RES1,ATHIDD:MOV A,FIR2CJNE A,SEC2,DE2 ;判断是否相等MOV RES2,#00H ;相等,结果置0LJMP FOURTHHDE2: JC DE22 ;判断是否需要借位SUBB A,SEC2 ;无需借位MOV RES2,ALJMP FOURTHHDE22: MOV A,FIR3CJNE A,#00H,NEXT33 ; 判断千位是否可借SETB ERR ;没有借位,清空NEXT33:DEC FIR3MOV A,FIR2ADD A,#0AHSUBB A,SEC2MOV RES2,AFOURTHH:MOV A,FIR3CJNE A,SEC3,DE3 ;判断是否相等MOV RES3,#00H ;相等,结果置0LJMP LOOP5DE3: JC DE33 ;判断是否需要借位SUBB A,SEC3 ;无需借位MOV RES3,ALJMP LOOP5DE33: SETB ERRLOOP5: RET////////////////////////////////////////////////////////////////////////////////////// ////////////////数据处理程序/////////////////////DEAL:CLR FILMOV A,RES0DIV ABMOV RES0,BADD A,RES1MOV RES1,A ;除以10,余数保留在本位,商加到高一位MOV A,RES1MOV B,#0AHDIV ABMOV RES1,BADD A,RES2MOV RES2,AMOV A,RES2MOV B,#0AHDIV ABMOV RES2,BADD A,RES3MOV RES3,AMOV A,RES3MOV B,#0AHDIV ABMOV RES3,BADD A,FLEL4MOV FLEL4,AMOV A,FLEL4CJNE A,#00H, AAMOV A,FLEL5CJNE A,#00H,AAMOV A,FLEL6CJNE A,#00H,AALJMP LOOPAA: SETB FILLOOP: RET/////////////////////////////////////////////////////////////////////////////////////////////比较结果与数据暂存的大小////////////////////////////////////////// COMP:CLR HHCLR EEMOV A,RES3CJNE A,LIN3,NEQ; 比较千位CJNE A,LIN2,NEQ ;比较百位MOV A,RES1CJNE A,LIN1,NEQ ; 比较十位MOV A,RES0CJNE A,LIN0,NEQ ;比较个位SETB EE ;两个数字相等LJMP LOOP3NEQ:JC LOOP3SETB HH ;表明RES小修改DIVI 及时清掉标记LOOP3: RET///////////////移位程序/////////////////////////////////MOVI: MOV A,R2MOV R3,AMOV A,R1MOV R2,AMOV A,R0MOV R1,AMOV A,R7MOV R0,ARET/////////////////////////////////////////////////////////////////////////////////////////TRANS: ;逐一比较,将数据转化为数码管数据CJNE A,#00H,TRA1 ;0MOV A,#3FHLJMP LOOP6TRA1: CJNE A,#01H,TRA2 ;1MOV A,#06HLJMP LOOP6TRA2: CJNE A,#02H,TRA3 ;2MOV A,#5BHLJMP LOOP6TRA3: CJNE A,#03H,TRA4 ;3MOV A,#4FHLJMP LOOP6TRA4: CJNE A,#04H,TRA5 ;4LJMP LOOP6TRA5: CJNE A,#05H,TRA6 ;5MOV A,#6DHLJMP LOOP6TRA6: CJNE A,#06H,TRA7 ;6MOV A,#7DHLJMP LOOP6TRA7: CJNE A,#07H,TRA8 ;7MOV A,#07HLJMP LOOP6TRA8: CJNE A,#08H,TRA9 ;8MOV A,#7FHLJMP LOOP6TRA9: CJNE A,#09H,CLOSE ;9MOV A,#6FHLJMP LOOP6CLOSE: CJNE A,#0AH,LOOP6 ;关闭MOV A,#00HLOOP6: RET///////////////////////////////////////////////////按键操作////////////////////////// KEY: ;按键相应的操作MOV A,R6 ;按键E1 数字1CJNE A,#0E1H, KEYE2 ;读取按键,并确定是否为数字1CJNE R4,#04H,YES1 ;判断是否越界LCALL CLRI ;越界处理清空LJMP LOOP10YES1:SETB YESN ;将有无数字按键置1MOV A,R4INC AMOV R4,A ;溢出标记位加1MOV R7,#01HLCALL MOVI ;存入R中JB YESY,SEC11;是否已有操作符LCALL RTOFIR ;无操作符,存入FIR中LJMP LOOP10SEC11: LCALL RTOSEC ;有操作符。