标题:
51单片机简单计算器用数码管显示
[打印本页]
作者:
liuda
时间:
2015-1-21 22:03
标题:
51单片机简单计算器用数码管显示
是用51hei单片机开发板 电路图详见:
http://www.51hei.com/f/51hei-5.pdf
的数码管部分, 用2个74hc573 锁存,p0口作为数据口 ,p3.6和p3.7分别是段和位的锁存端口.
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P3^6;//573段选使能
sbit wela=P3^7;//573位选使能
sbit beep=P3^4;//蜂鸣器
uchar temp,key;//按键变量
uchar fun;//加,减,乘,除,标志位
long int num1,num2,res;//num1与num2是2个要运算的变量,res是结果
uchar aa,dis;//aa 2个运算数标志位 dis 2个运算数与结果标志
uchar code table[]={0x00,0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数码管段码
uchar code weixuan[]={0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//数码管位码
void delay(unsigned char i)//延时
{
uchar j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void bee()//蜂鸣器
{
beep=0;
delay(255);
delay(255);
beep=1;
}
key_scan()//按键检测
{
P1=0xfe;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xee:
key=0;
break;
case 0xde:
key=1;
break;
case 0xbe:
key=2;
break;
case 0x7e:
key=3;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
P1=0xfd;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed:
key=4;
break;
case 0xdd:
key=5;
break;
case 0xbd:
key=6;
break;
case 0x7d:
key=7;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
P1=0xfb;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xeb:
key=8;
break;
case 0xdb:
key=9;
break;
case 0xbb:
key=10;
break;
case 0x7b:
key=11;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
P1=0xf7;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:
key=12;
break;
case 0xd7:
key=13;
break;
case 0xb7:
key=14;
break;
case 0x77:
key=15;
break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
}
void Init()//初始化
{
num1=0;
num2=0;
wela=1;
P0=0xdf;
wela=0;
dula=1;
P0=table[1];
dula=0;
key=16;
aa=0;
dis=0;
res=0;
}
void dis_play(long int nm)//显示函数
{
uchar a1,a6;//a1位段选变量,a6为位选变量
long int shu;
shu=nm;
if(shu==0)
{
wela=1;
P0=0xdf;
wela=0;
dula=1;
P0=table[1];
dula=0;
}
else
{
for(a6=0;a6<6;a6++)
{
a1=shu%10;//shu%10 shu比10小a1=shu本身
if(shu!=0)
{
a1=a1+1;
}
shu=shu/10;//shu/10 shu比10小 shu为0
P0=table[a1];
dula=1;
dula=0;
P0=weixuan[a6];
wela=1;
wela=0;
delay(5);
}
}
}
void display()//显示选择函数,dis 0或1显示运算数,dis为2显示结果
{
switch (dis)
{
case 0:{
dis_play(num1);
}
break;
case 1:{
dis_play(num2);
}
break;
case 2:{
dis_play(res);
}
break;
}
}
void shanshuo()//数码管闪烁
{
wela=1;
P0=0xff;
wela=0;
delay(255);
}
void check()//运算函数
{
if(key!=16)
{
bee();
if(key>=10)
{
switch (key)
{
case 10:Init();break; // CE
case 11:{
switch (fun)//加,减,乘,除选择标志位
{
case 0:res=num1+num2,dis=2;break;//加法
case 1:res=num1-num2,dis=2;break;//减法
case 2:res=num1*num2,dis=2;break;//乘法
case 3:res=num1/num2,dis=2;break;//除法
}
};break; // =
case 12:fun=0,aa=1,shanshuo();break; // +
case 13:fun=1,aa=1,shanshuo();break; // -
case 14:fun=2,aa=1,shanshuo();break; // *
case 15:fun=3,aa=1,shanshuo();break; // /
}
}
else
{
switch (aa)//运算变量赋值标志位
{
case 0:{
num1=num1*10+key;//把按键检测到的值赋给num1运算变量1
};break;
case 1:{
dis=1;
num2=num2*10+key;//把按键检测到的值赋给num2运算变量2
};break;
}
}
}
key=16;
}
void main()
{
Init();
while(1)
{
key_scan();
check();
display();
}
}
复制代码
作者:
南天白云
时间:
2015-1-23 14:47
学习中
作者:
绿源学习者
时间:
2015-1-23 16:16
呵呵很好不过没有仿真就不想用你的程序了
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1