51单片机实现三位十进制数加减乘除运算

51单片机实现三位十进制数加减乘除运算

一.题目

51单片机IO接口作业

请将附件给出的Proteus图用51单片机完成一个计算器功能。

1、显示采用动态分时8位共阳数码管输出。

2、采用4*4矩阵键盘输入,键盘上已经标识对应键。

3、完成三位十进制数的加、减、乘、除运算。

4、开机显示最右边数码管显示‘0’,输入按键值后依次左移。"+—*/"数码管显示分别“A B C D”。

按要求上交实验报告(加、减、乘、除的对应的Proteus仿真截图一定要有,下载到开发板图也必须有)。

二.实验思路

程序分为以下几步:

  1. 数码管显示模块,数码管上显示数字
  2. 矩阵键盘模块,用户按下按键返回相应的按键值
  3. 主函数,实现加减乘除运算,偷了点懒,其实加减乘除运算也可以独立出来做成一个模块

三.程序代码

#include<reg52.h>
 //共阳极数码管
unsigned char code segCodeTable[16] = {0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e};
//位码表
unsigned char code posCodeTable[8] = {
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
unsigned char code key_value[16]={0xD7,0xEB,0xDB,0xBB,0xED,0xDD,0xBD,0xEE,0xDE,0xBE,0x77,0x7B,0x7D,0x7E,
0xB7,0xE7};//键盘标识对应的键盘值 
void dis_seg7(unsigned long num,unsigned char dec_hex);
unsigned char keyscan();
void delayms (void);
unsigned char pre_P1;

void main()
{
	unsigned char key0=0,key1=0,key2=0;
	unsigned char value = 0,j = 0;
	unsigned char state = 0;
	unsigned char dec_hex = 10;
	unsigned int NUMA = 0,NUMB = 0;
	unsigned long dis_num = 0;
	while(1)
	{
		value = keyscan();
		//if((pre_P1 == 0xf0)&&(P1 != 0xf0))
		//实现数码管显示多位数字
		if((pre_P1 == 0xf0)&&(P1 != 0xf0))
		{
			if(value >= 0 && value <= 9)
			{
				dec_hex = 10;
				key2 = key1;
				key1 = key0;
				key0 = value;
				dis_num = 100*key2 + 10* key1 + key0;
			}
			//按下操作符+-*/前,保存数码管显示数字dis_num到NUMA
			//	key0 = 0;key1 = 0;
			//key2 = 0;dis_num = value;
			//上述四条语句的目的:按下操作符显示对应的16进制数;
			//实现数码管的清零,即实现120+150,数码管一次显示120;
			//A(表示加号);150
			else if(value>=10&&value<=13)
			{
				NUMA = dis_num;
				key0 = 0;
				key1 = 0;
				key2 = 0;
				dis_num = value;
				dec_hex = 16;
				if(value == 10 )
				{
					state ='+';			
				}
				else if(value == 11)
				{
					state = '-';
				}
				else if (value == 12)
				{
					state = '*';
	
				}
					else if (value == 13)
				{
					state = '/';
				}
			}
			//按下等号时,保存数码管显示数字dis_num到NUMB,实现计算
			else if(value == 14)
			{
				dec_hex = 10;
				key0 = 0;
				key1 = 0;
				key2 = 0;
				NUMB = dis_num;
				if(state == '+')
				{
					dis_num = NUMA + NUMB;
				}
				else if(state == '-')
				{
					dis_num = NUMA - NUMB;
				}
					else if(state == '*')
				{
					dis_num = NUMA * NUMB;
				}
					else if(state == '/')
				{
					dis_num = NUMA / NUMB;
				}
			
			} 
			//数码管清零
			else if(value == 15)
			{
				dec_hex = 10;
				key0 = 0;
				key1 = 0;
				key2 = 0;
				NUMA = 0;
				NUMB = 0;
				dis_num = 0;			
			}
		}
		pre_P1 = P1;
		dis_seg7(dis_num,dec_hex);
		for(j = 0;j < 200;j++);
	}	
}


//七段数码管显示模块
void dis_seg7(unsigned long num,unsigned char dec_hex)
{
	char i = 0,count = 8;
	unsigned int j =0;
	char dis_data = 0;
	for(i = 0;i < count;i++)
	{
		dis_data = num % dec_hex;
		num = num / dec_hex;
		P2 = segCodeTable[dis_data];
		P3 = posCodeTable[i];
		for(j = 0;j < 200;j++);
		P2 = 0xff; //清除余晖
		if(num == 0)
		{
			break;
		}
	}	 
}


//延时模块
void delayms (void)
{
unsigned char i;
for (i=200;i>0;i--);
}


//按键扫描模块
unsigned char keyscan()
{
	unsigned char rowscan,colscan,row_col,i;
	static unsigned char value;
	P1 = 0xf0;	//P1输出 0xf0
	if((P1&0xf0) != 0xf0) //P1读入数据,判断是否有按键按下
	{
		delayms();//延时消抖
		if((P1&0xf0) != 0xf0)
		{
			//本代码采用逐行扫描的方式来确定按下的按键
			rowscan = 0xfe;
			 while((rowscan&0x10)!=0)
			 {
			 	P1 = rowscan;
				colscan = P1 & 0xf0;
				if(colscan != 0xf0)
				{
					//确定按下按键的行号与列号,查表,返回按键值
					row_col = colscan | (rowscan&0x0f);
					for(i = 0;i<16;i++)
					{
						if(row_col == key_value[i])
						{
							value = i;
							
						}
					}
					break;
				}
				else 
				{
					 rowscan = (rowscan << 1) | 0x1;
				}
			 }
		}
	}
	return value;
}

四.运行结果

1.加法

123 + 456 = 579

image-20210428192551440

image-20210428192632301

image-20210428192705666

image-20210428192738306

2.减法

789 - 123 = 666

image-20210428192903244

image-20210428192938888

image-20210428193015322

image-20210428193047695

3.乘法

100 * 234 = 23400

image-20210428193129775

image-20210428193153045

image-20210428193224389

image-20210428193241823

4.除法

480/160 =3

image-20210428193428830

image-20210428193500788

image-20210428193549611

image-20210428193609649
github下载链接
代码及proteus工程下载

  • 11
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值