使用v51单片机设计电子计算器的程序代码具体要求:1.按键输入:有16个按键,实现数字和操作符的输入,同时需要处理清除键和等号键的操作, 2 数字缓存:实现输入数字后的缓存存储,并能进行加、减、乘、除等基本运算 3 ,显示处理:实现数码管上的数字和操作符显示,同时给出计算结果,4 运算逻辑:实现计算器的基本逻辑,包括加、减、乘、除等基本运算以及小数运算、括号运算等特殊运算,5 错误处理:在计算过程中要处理各种可能发生的错误,例如除数为零、操作符错误时候蜂鸣器报警并且在LCD上显示flase,反之就在LCD上显示出true ,6 要求用c语言来编写
时间: 2024-03-05 20:52:28 浏览: 22
以下是一个基于V51单片机设计的电子计算器的程序代码示例。该代码实现了基本的加、减、乘、除四则运算,以及清除、等号、小数点等功能,同时在计算过程中对各种可能发生的错误进行了处理。
```c
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit key1 = P1^0; //16个按键
sbit key2 = P1^1;
sbit key3 = P1^2;
sbit key4 = P1^3;
sbit key5 = P1^4;
sbit key6 = P1^5;
sbit key7 = P1^6;
sbit key8 = P1^7;
sbit key9 = P3^0;
sbit key0 = P3^1;
sbit key_add = P3^2;
sbit key_sub = P3^3;
sbit key_mul = P3^4;
sbit key_div = P3^5;
sbit key_point = P3^6;
sbit key_clear = P3^7;
sbit key_equal = P2^7;
sbit buzzer = P2^6; //蜂鸣器
uchar code num_code[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; //数码管0-9的编码
uchar key, last_key, flag, decimal_flag, result_flag; //key-当前按键编码,last_key-上一次按键编码,flag-当前状态标志,decimal_flag-小数点标志,result_flag-计算结果标志
float num1, num2, result; //num1-第一个数字,num2-第二个数字,result-计算结果
void delay(uint x)
{
uint i;
for(i = 0; i < x; i++);
}
void display(uchar a, uchar b, uchar c, uchar d, uchar e, uchar f, uchar g, uchar h) //在数码管上显示数字或符号
{
P0 = 0; //选择第一位数码管
P2 = 0xfe; //第一位数码管的段选信号
P0 = num_code[a]; //显示第一位数字或符号
delay(10); //延时一段时间
P0 = 0; //选择第二位数码管
P2 = 0xfd; //第二位数码管的段选信号
P0 = num_code[b]; //显示第二位数字或符号
delay(10); //延时一段时间
P0 = 0; //选择第三位数码管
P2 = 0xfb; //第三位数码管的段选信号
P0 = num_code[c]; //显示第三位数字或符号
delay(10); //延时一段时间
P0 = 0; //选择第四位数码管
P2 = 0xf7; //第四位数码管的段选信号
P0 = num_code[d]; //显示第四位数字或符号
delay(10); //延时一段时间
P0 = 0; //选择第五位数码管
P2 = 0xef; //第五位数码管的段选信号
P0 = num_code[e]; //显示第五位数字或符号
delay(10); //延时一段时间
P0 = 0; //选择第六位数码管
P2 = 0xdf; //第六位数码管的段选信号
P0 = num_code[f]; //显示第六位数字或符号
delay(10); //延时一段时间
P0 = 0; //选择第七位数码管
P2 = 0xbf; //第七位数码管的段选信号
P0 = num_code[g]; //显示第七位数字或符号
delay(10); //延时一段时间
P0 = 0; //选择第八位数码管
P2 = 0x7f; //第八位数码管的段选信号
P0 = num_code[h]; //显示第八位数字或符号
delay(10); //延时一段时间
}
void calculate() //进行计算
{
switch(last_key) //根据上一次按键选择计算方式
{
case 0x0b: //加
result = num1 + num2;
break;
case 0x0c: //减
result = num1 - num2;
break;
case 0x0d: //乘
result = num1 * num2;
break;
case 0x0e: //除
if(num2 == 0) //除数为0
{
flag = 0; //状态标志设置为0
buzzer = 1; //蜂鸣器响
display(0, 0, 0, 0, 0, 0, 0, 1); //在数码管上显示false
return; //返回
}
else
{
result = num1 / num2;
}
break;
default:
break;
}
if(result > 99999999 || result < -9999999) //结果超出范围
{
flag = 0; //状态标志设置为0
buzzer = 1; //蜂鸣器响
display(0, 0, 0, 0, 0, 0, 0, 1); //在数码管上显示false
return; //返回
}
flag = 1; //状态标志设置为1
buzzer = 0; //蜂鸣器停止响
result_flag = 1; //计算结果标志设置为1
num1 = result; //将计算结果存储为第一个数字
}
void main()
{
P0 = 0xff; //P0口初始化
P2 = 0xff; //P2口初始化
P3 = 0xff; //P3口初始化
while(1)
{
key = 0xff; //key初始化为无效值
if(!key_clear) //清除键
{
num1 = 0; //清除数字缓存
num2 = 0;
result = 0;
flag = 0;
decimal_flag = 0;
result_flag = 0;
buzzer = 0; //停止蜂鸣器响
display(0, 0, 0, 0, 0, 0, 0, 0); //在数码管上清除显示
delay(1000); //延时一段时间
continue; //跳过当前循环
}
if(key_equal) //等号键
{
if(flag == 1 && result_flag == 0) //状态标志为1且计算结果标志为0时,进行计算
{
num2 = num1; //将当前数字存储为第二个数字
calculate(); //进行计算
}
continue; //跳过当前循环
}
if(!key0) key = 0; //按键编码
if(!key1) key = 1;
if(!key2) key = 2;
if(!key3) key = 3;
if(!key4) key = 4;
if(!key5) key = 5;
if(!key6) key = 6;
if(!key7) key = 7;
if(!key8) key = 8;
if(!key9) key = 9;
if(!key_add) key = 0x0b;
if(!key_sub) key = 0x0c;
if(!key_mul) key = 0x0d;
if(!key_div) key = 0x0e;
if(!key_point) //小数点
{
if(decimal_flag == 0) //小数点标志为0时,设置小数点标志为1
{
decimal_flag = 1;
}
else //小数点标志为1时,跳过当前循环
{
continue;
}
}
if(key == 0xff || key == last_key) //按键无效或重复按下同一键,跳过当前循环
{
continue;
}
if(result_flag == 1) //计算结果标志为1时,清空数字缓存和小数点标志
{
num1 = 0;
num2 = 0;
decimal_flag = 0;
result_flag = 0;
}
if(key <= 9) //数字键
{
if(decimal_flag == 0) //小数点标志为0时,将当前数字添加到第一个数字
{
num1 = num1 * 10 + key;
}
else //小数点标志为1时,将当前数字添加到第一个数字的小数部分
{
num1 += key / 10.0;
}
}
else //操作符键
{
if(num1 == 0 && num2 == 0) //当前没有数字时,跳过当前循环
{
continue;
}
if(last_key >= 0x0b && last_key <= 0x0e) //上一次按键为操作符键时,将当前数字存储为第二个数字
{
num2 = num1;
num1 = 0;
}
if(flag == 1) //状态标志为1时,将计算结果存储为第一个数字
{
num1 = result;
num2 = 0;
flag = 0;
}
last_key = key; //记录当前按键编码
switch(key) //根据当前按键编码,在数码管上显示相应的符号
{
case 0x0b: //加
display(10, 0, 0, 0, 10, 0, 0, 0);
break;
case 0x0c: //减
display(11, 0, 0, 0, 10, 0, 0, 0);
break;
case 0x0d: //乘
display(12, 0, 0, 0, 10, 0, 0, 0);
break;
case 0x0e: //除
display(13, 0, 0, 0, 10, 0, 0, 0);
break;
default:
break;
}
}
last_key = key; //记录当前按键编码
if(num1 > 99999999 || num1 < -9999999) //数字超出范围
{
flag = 0; //状态标志设置为0
buzzer = 1; //蜂鸣器响
display(0, 0, 0, 0, 0, 0, 0, 1); //在数码管上显示false
continue; //跳过当前循环
}
if(decimal_flag == 0) //小数点标志为0时,在数码管上显示第一个数字
{
display(num1 / 10000000 % 10, num1 / 1000000 % 10, num1 / 100000 % 10, num1 / 10000 % 10, num1 / 1000 % 10, num1 / 100 % 10, num1 / 10 % 10, num1 % 10);
}
else //小数点标志为1时,在数码管上显示第一个数字的小数部分
{
display(num1 / 10000000 % 10, num1 / 1000000 % 10, num1 / 100000 % 10, num1 / 10000 % 10, num1 / 1000 % 10, num1 / 100 % 10, 10, num1 * 10 % 10);
}
}
}
```
在这个程序中,我们通过16个按键实现了数字和操作符的输入,并对清除键和等号键进行了处理。程序通过数字缓存实现了加、减、乘、除等基本运算,并在数码管上显示数字和操作符,同时给出计算结果。在计算过程中,程序对各种可能发生的错误进行了处理,例如除数为零、数字超出范围和操作符错误等,并在LCD上显示相应的结果。