找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12766|回复: 15
收起左侧

C51简单计算器设计思想、Proteus仿真及源代码

  [复制链接]
ID:98923 发表于 2015-12-9 00:36 | 显示全部楼层 |阅读模式










硬件部分比较简单,当键盘按键按下时它的那一行、那一列的端口为低电平。因此,只要扫描行、列端口是否都为低电平就可以确定是哪个键被按下。

二、主程序流程图



程序的主要思想是:将按键抽象为字符,然后就是对字符的处理。将操作数分别转化为字符串存储,操作符存储为字符形式。然后调用compute()函数进行计算并返回结果。具体程序及看注释还有流程图。


三、程序源代码

#include <reg51.h>#include <intrins.h>

#include <ctype.h>

#include <stdlib.h>


#define uchar unsigned char

#define uint unsigned int


uchar operand1[9], operand2[9];

uchar operator;


void delay(uint);

uchar keyscan();

void disp(void);

void buf(uint value);

uint compute(uint va1,uint va2,uchar optor);


uchar code table[] = {0xc0,0xf9,0xa4,0xb0,0x99,

0x92,0x82,0xf8,0x80,0x90,0xff};


uchar dbuf[8] = {10,10,10,10,10,10,10,10};



void delay(uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}



uchar keyscan()

{

uchar skey;



P1 = 0xfe;

while((P1 & 0xf0) != 0xf0)

{

delay(3);


while((P1 & 0xf0) != 0xf0)

{

switch(P1)

{

case 0xee: skey = '7'; break;

case 0xde: skey = '8'; break;

case 0xbe: skey = '9'; break;

case 0x7e: skey = '/'; break;


default: skey = '#';

}


while((P1 & 0xf0) != 0xf0)

;

}

}



P1 = 0xfd;

while((P1 & 0xf0) != 0xf0)

{

delay(3);


while((P1 & 0xf0) != 0xf0)

{

switch(P1)

{

case 0xed: skey = '4'; break;

case 0xdd: skey = '5'; break;

case 0xbd: skey = '6'; break;

case 0x7d: skey = '*'; break;


default: skey = '#';

}


while((P1 & 0xf0) != 0xf0)

;

}

}




P1 = 0xfb;

while((P1 & 0xf0) != 0xf0)

{

delay(3);


while((P1 & 0xf0) != 0xf0)

{

switch(P1)

{

case 0xeb: skey = '1'; break;

case 0xdb: skey = '2'; break;

case 0xbb: skey = '3'; break;

case 0x7b: skey = '-'; break;


default: skey = '#';

}


while((P1 & 0xf0) != 0xf0)

;

}

}




P1 = 0xf7;

while((P1 & 0xf0) != 0xf0)

{

delay(3);


while((P1 & 0xf0) != 0xf0)

{

switch(P1)

{

case 0xe7: skey = '$'; break;

case 0xd7: skey = '0'; break;

case 0xb7: skey = '='; break;

case 0x77: skey = '+'; break;


default: skey = '#';

}


while((P1 & 0xf0) != 0xf0)

;

}

}


return skey;

}


void main()

{

uint value1, value2, value;

uchar ckey, cut1 = 0, cut2 = 0;

uchar operator;

uchar i, bool = 0;


init:


buf(0);

disp();

value = 0;

cut1 = cut2 = 0;

bool = 0;

for(i = 0;i < 9;i++)

{

operand1 = '\0';

operand2 = '\0';

}


while(1)

{

ckey = keyscan();

if(ckey != '#')

{

if(isdigit(ckey))

{

switch(bool)

{

case 0:

operand1[cut1] = ckey;

operand1[cut1+1] = '\0';

value1 = atoi(operand1);

cut1++;

buf(value1);

disp();

break;

case 1:

operand2[cut2] = ckey;

operand2[cut2+1] = '\0';

value2 = atoi(operand2);

cut2++;

buf(value2);

disp();

break;


default: break;

}

}

else if(ckey=='+'||ckey=='-'||ckey=='*'||ckey=='/')

{

bool = 1;

operator = ckey;

buf(0);

dbuf[7] = 10;

disp();

}

else if(ckey == '=')

{

value = compute(value1,value2,operator);

buf(value);

disp();

while(1)

{

ckey = keyscan();

if(ckey == '$')

goto init;

else

{

buf(value);

disp();

}

}

}

else if(ckey == '$')

{ goto init;}

}

disp();

}


}



uint compute(uint va1,uint va2,uchar optor)

{

uint value;


switch(optor)

{

case '+' : value = va1+va2; break;

case '-' : value = va1-va2; break;

case '*' : value = va1*va2; break;

case '/' : value = va1/va2; break;


default : break;

}

return value;

}



void buf(uint val)

{

uchar i;

if(val == 0)

{

dbuf[7] = 0;

i = 6;

}


else

for(i = 7; val > 0; i--)

{

dbuf = val % 10;

val /= 10;

}


for( ; i > 0; i--)

dbuf = 10;

}



void disp(void)

{

uchar bsel, n;


bsel=0x01;

for(n=0;n<8;n++)

{

P2=bsel;

P0=table[dbuf[n]];

bsel=_crol_(bsel,1);

delay(3);

P0=0xff;

}

}

C51简单计算器.zip

1.24 MB, 下载次数: 242, 下载积分: 黑币 -5

回复

使用道具 举报

ID:112618 发表于 2016-4-10 10:08 | 显示全部楼层
楼主你好,我刚入门,对51引脚不懂,下载你的帖子还是一部分看不懂,你能帮我改下这个吗?
E1A{TO2{G5LH8BKS$@OG134.png
回复

使用道具 举报

ID:117574 发表于 2016-5-10 18:33 来自手机 | 显示全部楼层
Fandy 发表于 2016-4-10 10:08
楼主你好,我刚入门,对51引脚不懂,下载你的帖子还是一部分看不懂,你能帮我改下这个吗?

你现在回了吗
回复

使用道具 举报

ID:114732 发表于 2016-5-14 16:19 | 显示全部楼层
先谢楼主的分享
回复

使用道具 举报

ID:145691 发表于 2016-11-2 14:34 | 显示全部楼层
负数能运算不
回复

使用道具 举报

ID:146409 发表于 2016-11-6 14:01 | 显示全部楼层
初学者来参考参考
回复

使用道具 举报

ID:156892 发表于 2016-12-22 16:07 | 显示全部楼层
计算按键和显示屏元件名是什么呀
回复

使用道具 举报

ID:157940 发表于 2016-12-27 08:53 | 显示全部楼层
谢谢楼主
回复

使用道具 举报

ID:153199 发表于 2017-1-1 12:22 | 显示全部楼层
很详细的资料
回复

使用道具 举报

ID:171316 发表于 2017-3-16 20:05 | 显示全部楼层
谢谢楼主
回复

使用道具 举报

ID:168012 发表于 2017-3-17 08:57 | 显示全部楼层
厉害,厉害
回复

使用道具 举报

ID:212212 发表于 2017-6-19 09:26 | 显示全部楼层
有没有汇编语言的
回复

使用道具 举报

ID:242365 发表于 2017-10-24 17:59 | 显示全部楼层
可以共享一下吗
回复

使用道具 举报

ID:336429 发表于 2018-5-24 14:52 | 显示全部楼层
被认为是不安全的文件不能下载,想要下载下来学习学习的。

捕获.PNG
回复

使用道具 举报

ID:794325 发表于 2020-7-1 15:35 | 显示全部楼层
楼主你好,用了你的代码,有一些问题,不知道如何修改,想询问一下您,不知道如何上传图片。。。
  1. operand1 = '\0';
复制代码
这里出现错误
error C213: left side of asn-op not an lvalue,是下面这部分代码中的
  1. init:

  2. buf(0);
  3. disp();
  4. value = 0;
  5. cut1 = cut2 = 0;
  6. bool = 0;
  7. for(i = 0;i < 9;i++)
  8. {
  9. operand1 = '\0';
  10. operand2 = '\0';
  11. }
复制代码
回复

使用道具 举报

ID:794325 发表于 2020-7-1 17:00 | 显示全部楼层
上面那个我加了个[i]就可以了,但是运行的时候为什么数码管不显示数字啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表