计算器功能包括:
1、支持8位数内(0~99999999)的包括加、减、乘、除的非负整数运算。
2、软件清零功能。
3、通过串口通信输入功能。
4、八位共阴极数码管显示。
注:
不具有断电后储存的功能,参与计算的数字一旦超出规定,如果是运算数按前8位记录。
在程序实现上核心有两个模块:显示和键扫。
程序实现:
显示:
通过取模获得每位数,然后通过查库(数列)获得对应的段码和位码,再依次扫描显示到数码管上。显示程序如下:
#include <Delay.h>//调用延时函数
#define DataPort P1//定义数码管数据来源端口
sfr P1=0x90;
sfr P2=0xA0;
//定义P1和P2口
sbit LATCH1=P2^1;//定义段锁存
sbit LATCH2=P2^2;//定义位锁存
void Display(unsigned long int Number)
{
unsigned int segment_code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned int bit_code[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
//设置段码和位码
unsigned int x[8];//将数字分离出来的每一位
unsigned int i,j;
for(i=0;Number>=1;i++)
{
x[i]=Number%10;
Number=(Number-x[i])/10;
}
j=i;
for(i=0;i<j;i++)
{
DataPort=bit_code[i];
LATCH2=1;
LATCH2=0;
DataPort=segment_code[x[i]];
LATCH1=1;
LATCH1=0;
DelayMs(1);
}
}
因为数码管是动态扫描的,肉眼会捕捉到数码管变化,类似动漫的原理,加上1ms左右延时即可在8位内“静态显示”。
延时函数如下(tms的延时效果):
void DelayUs2x(unsigned char t)
{
while(--t);
}
void DelayMs(unsigned char t)
{
while(t--)
{
DelayUs2x(245);
DelayUs2x(245);
}
}
调试样例如下:
void Display(unsigned long int Number);
main()
{
Display(99999999);
}
调试结果如下:
键扫:
本方法采用行列扫描的方法,键盘定义如下:
键扫代码如下:
#define KeyPort P0//定义键盘端口
void Delay(unsigned int xms);//声明延时函数
sfr P0=0x80;//定义P0端口
sbit h_1=P0^0;
sbit h_2=P0^1;
sbit h_3=P0^2;
sbit h_4=P0^3;
sbit l_1=P0^4;
sbit l_2=P0^5;
sbit l_3=P0^6;
sbit l_4=P0^7;
//定义行列
unsigned char KeyScan()
{
unsigned char KeyCode=0;
KeyPort=0xff;
l_4=0;
if(h_1==0){Delay(20);while(h_1==0);Delay(20);KeyCode=1;}
if(h_2==0){Delay(20);while(h_2==0);Delay(20);KeyCode=2;}
if(h_3==0){Delay(20);while(h_3==0);Delay(20);KeyCode=3;}
if(h_4==0){Delay(20);while(h_4==0);Delay(20);KeyCode=4;}
KeyPort=0xff;
l_3=0;
if(h_1==0){Delay(20);while(h_1==0);Delay(20);KeyCode=5;}
if(h_2==0){Delay(20);while(h_2==0);Delay(20);KeyCode=6;}
if(h_3==0){Delay(20);while(h_3==0);Delay(20);KeyCode=7;}
if(h_4==0){Delay(20);while(h_4==0);Delay(20);KeyCode=8;}
KeyPort=0xff;
l_2=0;
if(h_1==0){Delay(20);while(h_1==0);Delay(20);KeyCode=9;}
if(h_2==0){Delay(20);while(h_2==0);Delay(20);KeyCode=10;}
if(h_3==0){Delay(20);while(h_3==0);Delay(20);KeyCode=11;}
if(h_4==0){Delay(20);while(h_4==0);Delay(20);KeyCode=12;}
KeyPort=0xff;
l_1=0;
if(h_1==0){Delay(20);while(h_1==0);Delay(20);KeyCode=13;}
if(h_2==0){Delay(20);while(h_2==0);Delay(20);KeyCode=14;}
if(h_3==0){Delay(20);while(h_3==0);Delay(20);KeyCode=15;}
if(h_4==0){Delay(20);while(h_4==0);Delay(20);KeyCode=16;}
return KeyCode;//返回码用于查表
}
void Delay(unsigned int xms)
{
unsigned char i,j;
while(xms--)
{
i=2;
j=239;
do
{
while(--j);
}
while(--i);
}
}
再通过查表的方法避免返回0的情况,代码如下:
unsigned char KeyTab(unsigned char Char)
{
switch (Char)
{
case 1:return 7;break;
case 2:return 4;break;
case 3:return 1;break;
case 4:return 0;break;
case 5:return 8;break;
case 6:return 5;break;
case 7:return 2;break;
case 8:return '~';break;
case 9:return 9;break;
case 10:return 6;break;
case 11:return 3;break;
case 12:return '=';break;
case 13:return '+';break;
case 14:return '-';break;
case 15:return '*';break;
case 16:return '/';break;
}
}
计算程序如下:
unsigned long int Regulation(unsigned long int x,unsigned long int y,char m)
{
unsigned long int z;
switch(m)
{
case '+':z=x+y;break;
case '-':z=x-y;break;
case '*':z=x*y;break;
case '/':z=x/y;break;
}
return z;
}
综上结合后主函数:
#include <Function.h>
sfr P2=0xA0;
sbit Switch=P2^0;//另外定义的整个清零开关
main()
{
unsigned char X,Y,M,p;
unsigned long int A=0,B=0,Num;
while(1)
{
if(!Switch)
{
p=0;
A=0;
B=0;
Num=0;
}
X=KeyScan();
if(X)
{
if(X>0&&X<12&&X!=8)
{
if(p==0)
{
Y=KeyTab(X);
A=A*10+Y;
Num=A;
}
else
{
Y=KeyTab(X);
B=B*10+Y;
Num=B;
}
}
else if(X==12)
{
if(p==0)
{
Num=A;
}
else
{
Num=Regulation(A,B,M);
}
}
else if(X==8)
{
if(p==0)
{
A=(A-Y)/10;
Num=A;
}
else
{
B=(B-Y)/10;
Num=B;
}
}
else
{
M=KeyTab(X);
p++;
}
}
Display(Num);
}
}
Function头文件:
#ifndef _FUNCTION_H_
#define _FUNCTION_H_
void Display(unsigned long int Number);
unsigned char KeyScan();
unsigned char KeyTab(unsigned char Char);
unsigned long int Regulation(unsigned long int x,unsigned long int y,char m);
#endif
其中因为数组位数问题Display函数定义如下:
#define DataPort P1
sfr P1=0x90;
sfr P2=0xA0;
sbit LATCH1=P2^1;
sbit LATCH2=P2^2;
void DelayUs2x(unsigned char t);
void DelayMs(unsigned char t);
void Display(unsigned long int Number)
{
unsigned int segment_code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned int bit_code[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
unsigned int x[9];
unsigned int i,j;
for(i=1;Number>=1;i++)
{
x[i]=Number%10;
Number=(Number-x[i])/10;
}
j=i;
for(i=0;i<j;i++)
{
if(i==0)
{
DataPort=0x7f;
LATCH2=1;
LATCH2=0;
DataPort=0x00;
LATCH1=1;
LATCH1=0;
DataPort=0;
LATCH1=1;
LATCH1=0;
DelayMs(1);
}
else
{
DataPort=bit_code[i-1];
LATCH2=1;
LATCH2=0;
DataPort=segment_code[x[i]];
LATCH1=1;
LATCH1=0;
DelayMs(1);
}
}
}
void DelayUs2x(unsigned char t)
{
while(--t);
}
void DelayMs(unsigned char t)
{
while(t--)
{
DelayUs2x(245);
DelayUs2x(245);
}
}