我在用51单片机设计简易计算器,目前只能进行最大五位正整数的加减乘除的运算。 怎样才能设计出负数运算
将所有数据都计算为正整数,并分别处理正负号的方法。例如,如果两个数相减,首先判断被减数是否更大。
减数和减数相加。
数字翻转并相减后,结果前会加上负号。
在乘法和除法中,如果两个数的乘法和除法的符号不同,则结果为负。
直接使用C语言库函数根据浮点类型计算数据类型,结果为负数和小数,然后转换为字符串进行显示。
基于51单片机的简易计算器设计,急
//函数0123456789+-×÷=清除表3-1 3.2计算器软件设计
#include
#define intunsignedint//
#defineucharunsignedchar
sbitlcden=P2^3;//定义引脚
sbitrs=P2 ^4;
sbitrw=P2^0;
sbitbusy=P0^7;
chari,j,temp,num,num_1;
龙加,b,c; //第一个数字b; 第二个数字c, 获取数字
floata_c,b_c;
ucharflag, fuhao;//flag表示符号键是否被按下; 夫豪透露。
点击了哪个符号
ucharcodetable[]={7,8,9,0,4,5,6,0,1,2,3,0,0,0,0,0};< /p >
ucharcodetable1[] ={
7,8,9,0x2 f-0x30,
4,5,6,0x2a-0x30,
1,2,3,0x2d-0x30,
voiddelay(ucharz)//延迟函数
{
uchary;
0;z--)for(y=0;y<110;y++);
} voidcheck()//忙或不工作 判断
{
do{
P0=0xFF;
rs=0; //命令
rw=1; //读取
lcden=0; // 禁止读写
delay(1);//等待液晶显示器处理数据
lcden= 1; //允许读取
}(bus sy==1);//判断是否空闲; 1 忙; 0空闲
}
voidwrite_com(ucharcom)//写命令函数
{
P0=com; //com命令设置P0口
rs=0;
rw=0;
lcden=0;
check( ) ;
lcden=1;
}
voidwrite_date(uchardate)//写入数据函数
{
P0=日期;
rs=1;
rw=0;
lcden =0;
check();
lcden=1;
}
voidinit()//初始化
{
num=-1;
lcden=1;//使能信号为高
write_com(0x38);//8位; 2行
write_com(0x0c);//显示开启,光标关闭不闪烁*/
write_com(0x06);//扩展模式不改变显示? 关闭 没有眨眼。
num_1=0;
i=0;
j=0;
a=0; // 先做吧。
参与人数
b=0; //加入操作的第二个数字
c=0;
flag=0;//flag表示是否按下某个符号键,
fuhao=0;//fuhao表示按下哪个符号
voidkeyscan()//键盘扫描仪
{
P3=0xfe;
if(P3!=0xfe)
{
delay(20);//延迟20ms
if(P3!=0x fe)
{
temp=P3&0xf0;
按钮(临时)
{
case0xe0:num =0;
鸽子;
case0xd0:num=1;
break;
case0xb0:num=2;
break;
case0x70:num=3;break;
}
}
while(P3! =0xfe);
if(num==0 ||num==1||num==2)//如果按下“7”; '8' 或 '9
{
if(j!=0)
{
if(j!=0)
{
write_com(0x01)
}
if(fla ag==0)//符号按钮尚未按下
{
a=a*10+table [num]
}
else//如果符号按钮被点击
{
标志=1;
fuhao=4;//4表示点击分区标志
}
i=table1[num];
write_date(0x30+i);
}
P3=0xfd;
if(P3!=0xfd)
i f(P3!=0xfd)
{
延迟(5);
if(P3!=0xfd)
{
temp=P3&0xf0;
按钮 (临时)
{
case0xe0:num=4;
break;
case0xd0:num=5;
break;
ca se0xb0:num=6;
break;
case0x70:num=7;
break;
}
}
同时(P3!=0x fd);
if(num==4||num==5||num==6&&num!=7)// '4'; 如果按下“5”或“6”
{
if(j!=0)
{
write_com(0x01 );
j=0;
}
if(flag==0)//不按符号键
{
a=a*10+table[num];
}
else//如果符号按钮被点击
{
b=b*10 + 表 [num];
}
}
else//如果使用“/”
{
flag=1 ;
fuhao=3;//表示点击数字3。
}
i=table1[num];
write_date(0x30+i);
}
P3=0xbb;if(P3!=0xfb)
{
延迟(5);
如果 (P3!=0xfb)
{
temp=P3&0xf0;
按钮(temp)
{
case0xe0:num=8; /p>
break;
case0xd0:num=9;
打破;
case0xb0:num=10;
中断。
case0x70:num=11;
中断;
}
}
if(num==8||n um==9||num==10)//你'1'; 如果按下“2”或“3”
{
if(j!=0 )
{
write_com(0x01 );
j=0;
}
if(flag==0)//符号按钮尚未按下
{
a=a*10+table[num];
}
else//如果符号按钮被点击
{
b=b*10+table[num];
}
}
elseif(num==11)//'-'
{
flag=1;
fuhao =2; //按2表示你按了减号
}
i=table1[num];
write_date(0x30+i);
}
P3=0xf7 ;
if(P3!=0xf7)
{
延迟(5);
<if(P3!=0xf7)
{
temp=P3&0xf0;
更改(临时)
{
case0xe0:num=12 ;
中断;
case0xd0:num=13;
打破;
case0xb0:num=14;
中断;
case0x70:num=15;
中断;
}
}
while(P3!=0xf7) ;
更改(数字 )
{
case12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//点击的是“清除”
打破,
a=a*10;write_date(0x30);
P1=0;
}
elseif(flag==1)//如果符号单击按钮
{
b=b*1 0;
write_date(0x30);
}
}
break;
case14:{j =1;
if(fuhao= =1){write_com(0x80+0x4f); // 按等号键,光标到达第二行最后一个显示位置。
write_com(0x04); 写完后, 数据 光标返回空白
c=a+b;
while(c!=0)
{
write_date ( 0x30+c %10);
c=c/10 ;
}
write_date(0x3d); //再写一次"="
a=0;b=0;flag=0;fuhao=0 ;
}
els eif(fuhao= =2){write_com(0x80+0x4f); // 光标到达第二行最后一个显示位置
write_com(0x04); // 设置从最后写入数据。
向前 写入一条数据后; 光标移回空格
//(逻辑上说顺序错误,可以显示与上一段相同的)
if(a-b>0)
c=a-b;
其他
c=b-a;
while(c!=0)
{
write_date(0x30+c%10);
c =c/10;
}
i f(a-b<0)
write_date(0x2d);
write_date(0x3d); //再写一次"=
a=0;b=0;flag=0;fu hao=0;
}
elseif(fuhao==3){write_com(0x80+0x4f);
write_com(0x04);
c=a*b;
while(c!=0)
{
write_date(0x30+c%10);
c=c/10;
}
write_date(0x3d);
a=0;b=0;flag= 0;fuhao=0;
}
elseif(fuhao==4){write_ com(0x80+0x4f);
write_com(0x04);
i=0;
c=(long)(((float)a/b )*1000);
while(c!=0)
{
write_date(0x30+c%10);
c=c/10;
i++;
if(i==3)
write_date(0x2e);
}
if(a/b<=0)
write_date(0x30);
write_date(0x3d);
a=0;b=0;flag=0;fuhao=0;
}
}
break;
case15:{ _date(0x30+table1[num]);flag=1;fuhao=1;}
break;
}
}
main()
{
init();
while(1)
{
keyscan();
}
}
基于51单片机简易计算器设计
本文将详细介绍基于51单片机设计一个简单计算机的整个过程,包括硬件电路设计、软件程序实现、仿真、PCB制造等步骤。使用Proteus7.8进行仿真,结合AltiumDesigner完成原理图和PCB设计,使用Keil4/5作为编译器,用C语言编写程序,以下是和功能具体设计步骤。
硬件设计包括按钮模块、LCD1602显示模块和51单片机作为核心控制器三部分。
按键模块采用4*4矩阵键盘提供输入功能; LCD1602负责显示数据; 微控制器作为系统控制中心,执行控制逻辑和数据处理。
软件程序主要包括主程序、按键扫描程序和LCD1602显示程序。
主程序负责总体协调,按键扫描程序负责读取输入的按键,显示程序根据计算结果显示数据。
性能指标如下:采用51单片机设计一个简单的计算器,支持基本的加、减、乘、除运算,最大运算结果可以达到9999*9999。
通过 Proteus 仿真验证设计准确性。
仿真图给出了硬件电路的连接以及在LCD1602上显示数据所需的关键操作。
通过按键输入测试加、减、除等运算功能,结果正确显示在第二行。
原理图是使用AD软件绘制的,并详细描述了每个组件的连接方式。
PCB设计是通过Proteus完成的。
与实物作品相比,Proteus仿真在运行环境、调试方法、电路连接、运行速度、功能实现等方面都与实物有所不同。
源程序中,主程序代码实现了系统的整体控制逻辑。
设计报告提供详细的信息列表,包括常见问题的解决方案、流程、模拟、原理图和 PCB、提案报告、功能要求、设计报告、讲解视频等。
为了帮助读者更好地设计,文章还提供了相关资源链接,包括AltiumDesigner安装与越狱、KEIL+Proteus单片机仿真设计指南、KEIL安装与越狱、Proteus组件搜索、Proteus安装、简单Proteus使用指南以及单片机学习文档、资料手册、答辩技巧、设计报告概要等
求助:关于80C51单片机简易计算器设计的程序,要求是汇编语言。 谢谢哈
ORG0000HSTART:MOV78H,#0; 初始化:78H放段码0,其余放熄灭码MOV79H、#10MOV7AH、#10MOV7BH、#10MOV7CH、#10MOV7。DH, #10MOVR5, #0;R5 — 击键次数。
初始设置为0MOV30H。
#0;30H——功能键存储单元。
初始设置为0MOV40H。
最初,#0;40H 的单位设置为 0MOV41H。
单元#0;41H 初始设置为0MOV41H。
初始设置为0LOOP:LCALLDIRLCALLKEYINCR5; 自由传输程序决定按哪个键 S1:CJNEA、#10、S2; 如果不是“+”键,则转到S2LJMPFUN。
如果是“+”键,则转到; FUNS2:CJNEA,#11,S3; 这不是“-”键,转到S3LJMPFUN 这是“-”键,转到S4LJMPFUN; 这是“*”键; 跳转键至 FUNS4:CJNEA,#13,S5; 这不是“/”键,转到S5LJMPFUN; “/”键,转到FUNS5:CJNEA,#14,S6;如果是“=”键,转到FUNS6:CJNEA,#15,N1; 如果不是“CL”键,则转到N1LJMPSTART; 如果是“CL”键,则转到STARTN1:CJNER5,#。
1、N2确定LJ键将被按下多少次; MPD11N2:CJNER5,#2,N3LJMPT2N3:CJNER5,#3,N4LJMPT3N4:CJNER5,#4,N5LJMPT4N5:CJNER5,#5,N6LJMPT 5N6:CJNER5,#6,STARTLJMPT6D11:MOVR4,AMOV78H,A;输入值发送到显示缓冲区 MOV79H,#10MOV7AH,#10MOV7BH,#10MOV 7CH,#10MOV7DH,#10LJMPLOOPT2:MOVR7,AMOVB,#10MOVA,R4MULABADDA,R7MOVR4,AMOV7AH,#10MOV7BH,#10MOV7CH,#10MOV7DH,#10MOV79H,78H; 从个位到十位的数字 MOV78H,R7; 新数字 – 个位 LJMPLOOPT3:MOVR7,AMOVB,#10MOVA,R4MU LABADDA,R7MOVR4,AMOV7BH,#10MOV7CH,#10MOV7DH,#10MOV7AH,79H 从十到百 MOV79H, 78H 从个到十 MOV78H, R7; ;新数字-个位数 LJMPLOOPT4:MOVR7,AMOVB,#10MOVA,R4MULABADDA,R7MOVR4,AMOV7CH,#10MOV7DH,#10MOV7BH,7AH MOV7AH,79HMOV79H,78HMOV78H,R7LJMPLOOPT5:MOVR7,AMOV7DH,#10MOVA,R4MULABADDA,R7MOVR4,AMOV7DH, #10MOV7CH,7BHMOV7BH,7AHMOV7AH,79HMOV79H,78HMOV78H,R7LJMPLOOPT6:MOVR7,AMOVB,#10MOVA,R4MUL 阿巴达,R7MOVR4,AMOV7DH,7CHMOV7CH,7BHMOV7BH,7AHMOV7AH,79HMOV79H,78HMOV78H,R7LJMPLOOPMOV7C H,7BHMOV7BH,7AHMOV7AH,79HMOV79H,78HMOV78H,R7LJMPLOOPFUN:MOV78H,#10MOV79H,#10MOV7AH,#10MO VR0,30H;交换最后功能键 MOV30H,AMOVA,R0CJNEA,#10,FUN1;速率功能键 LJMPADDY;"+"FUN1:CJNEA,#11,FUN2LJMPS UBT;"-"FUN2:CJNEA,#12,FUN3LJMPMULT;"*"FUN3:CJNEA,#13,FUN4LJMPDIVI;"/"FUN4:CJNEA,#14,FUN5 ;第一次按功能键,即 A=#0LJMPEQUA;"="FUN5:MOV40H,R4;保存第一个数字 MOVR5,#0;将按键计数清零 LJMPBCD;将其分割成 bcd 代码以便稍后显示:LJMPSTART; 溢出处理ADDY:MOVA,40H; 将第一个数字发送到累加器ADDA、R4; 将第一个数字与第二个数字相加 JBCY、OF; 溢出MOV40H,A; 保存此结果 MOVR5, #0; 清除键数 LJMPBCDSUBT:MOVA,40HSUBBA,R4JBCY,OFMOV40H,AMOVR5,#0LJMPBCDMULT:MOVA,40HMOVB,AMOVA,R 4MULABJBOV,OFMOV40H,AMOVR5,#0LJMPBCDDIVI:MOVA,R4MOVB,AMOVA,40HDIVABJBOV,OFMOV40H,AMOVR5,#0LJMPBCDEQUA:MOVR5,#0LJMPBCDBCD:MOVB,#10MOVA,40H; 结果被发送到DIVAB累加器; 结果除以10MOV41H,A; “private”暂存于MOVA,B; 取一位图MOV78H,A; 发送一位显示缓存MOVA,41HJZRETURN,结果为一位,返回LOOPMOVB,#10MOVA,41HDIVABMOV41H,AMOVA,BMO; V79H,A; 十位发送到MOVA显示缓冲区,41HJZRETURN; 结果是一个两位数,返回LOOPMOV7AH,A; 百位数字被发送到显示缓冲区。
RETURN:LJMPLOOP动态映射子程序DIR; :MOVDPTR,#TAB;数码管译码表首地址 MOVR0,#78H;映射缓冲区单地址 MOVA,#0FEH;单选信号 MOVR1,ALD1:MOVA,@R0MOVCA,@A+D PTR; 观察台MOVP2、R1; 共阳极位选择发送到MOVP0、A的P2端口; 字段码发送到端口P0 LCALLDELAY1ms; 1ms延时设置子程序R0指向下一个MOVA模块; ,P1; JNBACC.5,LD2; 确定是否发送了6个RLA号码; 指示下一位 MOVR1,A; 将位选择信号存储回R3SJMPLD1; 去显示下一个数字LD2:RET; 发送6个号码后返回TAB。
:DB0 C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,80H,90H,0FFH 共阳极解码表 DELAY1ms:MOVR6,#2LOOP1:MOVR7,# 248NOPLOOP2:DJNZR7,LOOP2DJNZR6,LOOP1RETKEY:LCALLKS; 调用按键检测子程序JNZK1; 按 LCALLDELAY2 键继续; 使用延迟去抖动ACALLDIR; 调用动态显示AJMPKEY; 返回继续检测按钮K1:LCALLDELAY2; 去抖延迟LCALLKS,当按键再次按下时调用检测按键函数JNZK2; 进入下一步的按键 ACALLDIR; 调用动态显示AJMPKEY; 无键返回继续检测 K2:MOVR2,#0EFH; 将扫描到的值发送到暂存器R2 MOVR3,#00H; 将第一列值发送到R3临时存储器; storage K3:MOVP1,R2;将R2的值发送到端口P1 L0:JBP1.0,L1;P1.0为1,转到L1MOVA,#00H;将该行的第一个值发送到ACCAJMPLK;转到key值处理程序 L1:JBP1。
1,L2;P1.1对应1进入L2MOVA,#04H;发送第二行值到ACCAJMPLK;进入键值处理程序L2:JBP1.2,L3;P1.2对应1转到 L3MOVA, #08 H;将第三行值发送到 ACCAJMPLK;转到键值处理程序 L3:JBP1.3,NEXT;P1.3 为 1 并转到 NEXT MOVA,#0CH;将第四行值发送到 ACCLK:ADDA ,R3; 将行值和列值相加后的键值发送到APUSHACC; 将值A发送到临时堆栈存储器K4:LCALLDELAY2; 调用去抖程序LCALLKS; 继续而不释放按钮; 键返回检测POPACC; 将堆栈值发送到 ACCMOVDPTR、#KEYTABMOVCA、@A+DPTRETNEXT:INCR3; 列值加一MOVA,R2将R2值发送到AJNBACC.7; ,钥匙; 扫描完成后,进入KEY进行下一次RLA扫描; 完成扫描之前,将值左移一位并扫描下一列MOVR2,A; 将ACC值发送到暂存器R2,前往; K3继续KS:MOVP1,#0FH;将端口P1,四位高,四位低,1 MOVA,P1,读端口P1,5,6,11,7,8,9,12,15,0 ,14 ,13;键值表DELAY2:MOVR6,#2H;延迟去抖子程序 LP1:MOVR7,#0FAHLP2:DJNZR7,LP2DJNZR6,LP1RETEND