基于51单片机的简易计算器利用AT89C51作为系统主控,借助矩阵键盘作为输入器件,数码管作为显示器件,该系统可通过按键进行数字、操作符的输入,系统支持加、减、乘、除等功能,如果最后结果小于等于0,则系统显示0,当除数为0的时候,结果强制设置为0。

一、硬件设计

1、数码管显示

        本次设计利用四位共阴数码管进行显示,使用单独的IO口控制,其中段码的引脚为P0引脚,分别使用P10、P12、P13、P14进行位选,采用扫描的方式进行动态显示,这就要求比较高的实时性,一般情况下使用定时器进行扫描。电路图如下:

2、矩阵按键

        本次设计有输入数字、运算符、清除等指令,由于使用到的按键比较多,因此使用矩阵键盘是一个合适的选项,一般来说矩阵按键也是扫描实现,但是矩阵按键IO口占用少,属于是用单片机时间性能换取IO资源。电路图如下:

二、软件设计

1、数码管

        定时器扫描数码管的逻辑是利用定时器循环从数码管缓冲区获取数字信息,由于定时器使用中断时间,因此可以有效保证数码管扫描的实时性,在实际使用中,只需要改变数码管缓冲区的数据就可以实现显示数据的改变,并且不会影响主程序的运行。

#include <REGX52.H>

//10在Data[]里的索引是空0x00
unsigned char nixie_Buf[9]={0,10,10,10,10,10,10,10,10};
unsigned char Data[]={0x3f,0x30,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40,0x79,0x3E};

//将需要显示的值传递进来
void nixie(unsigned char Location,number)
{
	//把数组nixie_Buf的Location位换成number
	nixie_Buf[Location]=number;
}

void nixie_Scan(unsigned char Location,number)
{
	 P0=0x00;	
	 switch(Location)
	{
		 case 1:P1_0=0;P1_1=1;P1_2=1;P1_3=1;break;
		 case 2:P1_0=1;P1_1=0;P1_2=1;P1_3=1;break;
		 case 3:P1_0=1;P1_1=1;P1_2=0;P1_3=1;break;
		 case 4:P1_0=1;P1_1=1;P1_2=1;P1_3=0;break;
		 default:break;
	}
	P0=Data[number];
}

void nixie_Loop()
{
	static unsigned char i=1;
	//依次扫描数码管(通过遍历数组nixie_Buf的值)
	nixie_Scan(i,nixie_Buf[i]);
	i++;
	if(i>=9){i=1;}
}

2、矩阵键盘

        矩阵按键使用扫描的方式实现,本次设计采用列扫描的方式,通过循环给某一列低电平,同时循环检测时哪行按下,结合当前扫描列和按下按键行,定位到具体按下按键。

#include <REGX52.H>
#include "delay.h"

unsigned char MatrixKey()
{
	unsigned char KeyNumber=255;
	P2=0xff;
	P2_3=0;
	if(P2_7==0){delay(20);while(P2_7==0);delay(20);KeyNumber=0;}
	if(P2_6==0){delay(20);while(P2_6==0);delay(20);KeyNumber=4;}
	if(P2_5==0){delay(20);while(P2_5==0);delay(20);KeyNumber=8;}
	if(P2_4==0){delay(20);while(P2_4==0);delay(20);KeyNumber=12;}
	
	P2=0xff;
	P2_2=0;
	if(P2_7==0){delay(20);while(P2_7==0);delay(20);KeyNumber=1;}
	if(P2_6==0){delay(20);while(P2_6==0);delay(20);KeyNumber=5;}
	if(P2_5==0){delay(20);while(P2_5==0);delay(20);KeyNumber=9;}
	if(P2_4==0){delay(20);while(P2_4==0);delay(20);KeyNumber=13;}
	
	P2=0xff;
	P2_1=0;
	if(P2_7==0){delay(20);while(P2_7==0);delay(20);KeyNumber=2;}
	if(P2_6==0){delay(20);while(P2_6==0);delay(20);KeyNumber=6;}
	if(P2_5==0){delay(20);while(P2_5==0);delay(20);KeyNumber=10;}
	if(P2_4==0){delay(20);while(P2_4==0);delay(20);KeyNumber=14;}
	
	P2=0xff;
	P2_0=0;
	if(P2_7==0){delay(20);while(P2_7==0);delay(20);KeyNumber=3;}
	if(P2_6==0){delay(20);while(P2_6==0);delay(20);KeyNumber=7;}
	if(P2_5==0){delay(20);while(P2_5==0);delay(20);KeyNumber=11;}
	if(P2_4==0){delay(20);while(P2_4==0);delay(20);KeyNumber=15;}
	return KeyNumber;
}

3、定时器扫描数码管

        定时器配置函数

#include <REGX52.H>
/**
  * @brief  定时器初始化
  * @param  无
  * @retval 无
  */
void Timer0_Init(){
	//TMOD=0x01;
	TMOD&=0xf0;//1与任何数&为原数,0与任何数|为原数
	TMOD|=0x01;
	TF0=0;
	TR0=1;
	TH0=0xfc;
	TL0=0x18;
	ET0=1;
	EA=1;
	PT0=0;
}

        定时器中断函数扫描数码管

void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count1;
	TL0=0X18;
	TH0=0xfc;
	T0Count1++;
	if(T0Count1>=2)
	{
		T0Count1=0;
		nixie_Loop();
	}		
}

三、功能演示

1、运算逻辑

        输入,左操作数,按下加操作符,在输入右操作数,按下等于号,可以得出运算数据。如下图,左操作数为12,右操作数为3,结果时15.

2、归0情况

        如果减数小于被减数,此时运算为负数,本次设计不支持负数运算,所以运行为负数会清零。

        当除数为0时,运算结果也是清零。

四、项目总结

        本次项目使用矩阵按键加数码管实现了一个简单的计算器,计算器实现有加、减、乘、除等功能。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐