里面是的例子和怎么运用
源代码在线查看: 加减乘除计算器程序.c
软件大小: |
3 K |
上传用户: |
caim3587 |
|
|
关键词: |
|
下载地址: |
免注册下载 普通下载
|
|
/*本人倾力编写的简易计算器程序,可实现八位数的加减乘除功能
显示和键扫描部分程序是参考他人的著作:磁动力工作室明浩大侠
写的简易计数器程序,马忠梅等老师写的单片机C程序设计一书
*********编写:姜海峰 E-mail:jihafesz@163.com******
日期:2004.03.08
奉献给广大初学者,以做参考,如有疑问欢迎与本人联系共同探讨*/
//P3口接4×4行列式键盘
#include
#define uchar unsigned char
#define uint unsigned int
#define LED P0 //LED输出
#define LED0 P2_0 //LED控制
#define LED1 P2_1 //LED控制
#define LED2 P2_2 //LED控制
#define LED3 P2_3 //LED控制
#define LED4 P2_4 //LED控制
#define LED5 P2_5 //LED控制
#define LED6 P2_6 //LED控制
#define LED7 P2_7 //LED控制
uchar code LEDDis[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};//共阳0-9的LED笔划
uchar code keynb[]={0x11,0x12,0x14,0x18,0x21,0x22,0x24,0x28,0x41,0x42,0x44,0x48,0x81,0x82,0x84,0x88};
static uchar LEDN[6];
uchar key,newkey,oldkey; //扫描的键值,新键值,旧键值
bit valueflag;//键值标值志位,有值则为1,无值为0
static unsigned long data value,valuefirst,valuesecond;//键值,按符号键之前按键值,按符号键之后按键值
uchar keycounter,keytemp,symbol;//数字键按下计数器,键值暂存器,符号键值暂存器
void dlms(void);
uchar kbscan(void);
void dlms(void) //延时0.000804s程序
{
uint i;
for(i=0;i }
uchar kbscan(void)
{uchar sccode,recode;
P3=0xf0;//发全0行扫描码*,列线输入
if((P3&0xf0)!=0xf0)//若有键按下
{dlms();//延时去抖动
if((P3&0xf0)!=0xf0)
{sccode=0xfe;//逐行扫描初值
while((sccode&0x10)!=0) //判断是否扫描结束
{P3=sccode;//输出行扫描码
if((P3&0xf0)!=0xf0)
{recode=((P3&0xf0)|0x0f);
return((~sccode)+(~recode));
}
else sccode=(sccode }
}
}
return(0x00);
}
void main(void)
{
dlms();
//初始化变量
valueflag=0;
value=valuefirst=valuesecond=0;
symbol=0;
EA = 1; //允许CPU中断
ET0 = 1; //定时器0中断打开
TMOD = 0x1; //设定时器0为模式1,16位模式
TH0=0xB1;
TL0=0xDF; //设定时值为20000us(20ms)
TR0 = 1; //开始定时
while(1)
{
newkey=key;
if((oldkey!=newkey)&&(key!=0x00)&&(key!=0x88)&&(key!=0x84)&&(key!=0x81)&&(key!=0x82)&&(key!=0x48)&&(key!=0x44))//按下的是数字键处理
{
if(symbol!=0&&keycounter==0)
value=0;//如果是按了符号之后第一次按下数字键则清零value后重新计算其值
valueflag=1;
keycounter++;
if(keycounter>8)keycounter=0;
if(key==keynb[0])keytemp=0;
else if(key==keynb[1])keytemp=1;
else if(key==keynb[2])keytemp=2;
else if(key==keynb[3])keytemp=3;
else if(key==keynb[4])keytemp=4;
else if(key==keynb[5])keytemp=5;
else if(key==keynb[6])keytemp=6;
else if(key==keynb[7])keytemp=7;
else if(key==keynb[8])keytemp=8;
else if(key==keynb[9])keytemp=9;
switch(keycounter)
{
case 1:value=keytemp;break;
case 2:value=value*10+keytemp;break;
case 3:value=value*10+keytemp;break;
case 4:value=value*10+keytemp;break;
case 5:value=value*10+keytemp;break;
case 6:value=value*10+keytemp;break;
case 7:value=value*10+keytemp;break;
case 8:value=value*10+keytemp;break;
default:break;
}
}
else if(key==0x88&&symbol!=0&&valueflag==0) //'='号程序
{
valuesecond=value;
keycounter=0;
if(symbol=='+')
{value=valuefirst+valuesecond;
symbol=0;}
else if(symbol=='-')
{value=valuefirst-valuesecond;
symbol=0;}
else if(symbol=='*')
{value=valuefirst*valuesecond;
symbol=0;}
else if(symbol=='/')
{value=valuefirst/valuesecond;
symbol=0;}
}
else if(key==0x84) //'C'号程序
{value=0;
valueflag=0;
keycounter=0;
valuefirst=0;
valuesecond=0;
}
else if(key==0x82&&valueflag!=0&&symbol==0)//'/'号程序
{
symbol='/';
keycounter=0;
valuefirst=value;
}
else if(key==0x81&&valueflag!=0&&symbol==0)//'*'号程序
{
symbol='*';
keycounter=0;
valuefirst=value;
}
else if(key==0x48&&valueflag!=0&&symbol==0)//'-'号程序
{
symbol='-';
keycounter=0;
valuefirst=value;
}
else if(key==0x44&&valueflag!=0&&symbol==0)//'+'号程序
{
symbol='+';
keycounter=0;
valuefirst=value;
}
oldkey=newkey;
/*如果键一直按下,则只算按下一次因为(oldkey一直等于newkey),松开后再按下
oldkey就不等于newkey,因此键值会增加一位,因为中断时间只有20ms ,一次按键过
程中会产生多次中断,故设置此两变量来判别*********************************/
/*以下为数码管显示程序*/
LEDN[7]=value/10000000;
LEDN[6] = (value-10000000*(long)LEDN[7])/1000000;
LEDN[5] = (value-10000000*(long)LEDN[7]-1000000*(long)LEDN[6])/100000;
LEDN[4] = (value-10000000*(long)LEDN[7]-1000000*(long)LEDN[6]-100000*(long)LEDN[5])/10000;
LEDN[3] = (value-10000000*(long)LEDN[7]-1000000*(long)LEDN[6]-100000*(long)LEDN[5]-10000*(long)LEDN[4])/1000;
LEDN[2] = (value-10000000*(long)LEDN[7]-1000000*(long)LEDN[6]-100000*(long)LEDN[5]-10000*(long)LEDN[4]-1000*(long)LEDN[3])/100;
LEDN[1] = (value-10000000*(long)LEDN[7]-1000000*(long)LEDN[6]-100000*(long)LEDN[5]-10000*(long)LEDN[4]-1000*(long)LEDN[3]-100*(long)LEDN[2])/10;
LEDN[0] = (value-10000000*(long)LEDN[7]-1000000*(long)LEDN[6]-100000*(long)LEDN[5]-10000*(long)LEDN[4]-1000*(long)LEDN[3]-100*(long)LEDN[2]-10*(long)LEDN[1]);
if(LEDN[7]==0) //第7位显示,如有前缀0,则不显示
{LED=LEDDis[10];
LED7 = 0;
dlms();
LED7 = 1;}
else
{LED=LEDDis[LEDN[7]];
LED7 = 0;
dlms();
LED7 = 1;}
if(LEDN[7]==0&&LEDN[6]==0)//第6位显示,如有前缀0,则不显示
{LED=LEDDis[10];
LED6 = 0;
dlms();
LED6 = 1;}
else
{LED=LEDDis[LEDN[6]];
LED6 = 0;
dlms();
LED6 = 1;}
if(LEDN[7]==0&&LEDN[6]==0&&LEDN[5]==0)//第5位显示,如有前缀0,则不显示
{LED=LEDDis[10];
LED5 = 0;
dlms();
LED5 = 1;}
else
{LED=LEDDis[LEDN[5]];
LED5 = 0;
dlms();
LED5 = 1;}
if(LEDN[7]==0&&LEDN[6]==0&&LEDN[5]==0&&LEDN[4]==0)//第4位显示,如有前缀0,则不显示
{LED=LEDDis[10];
LED4 = 0;
dlms();
LED4 = 1;}
else
{LED=LEDDis[LEDN[4]];
LED4 = 0;
dlms();
LED4 = 1;}
if(LEDN[7]==0&&LEDN[6]==0&&LEDN[5]==0&&LEDN[4]==0&&LEDN[3]==0)//第3位显示,如有前缀0,则不显示
{LED=LEDDis[10];
LED3 = 0;
dlms();
LED3 = 1;}
else
{LED=LEDDis[LEDN[3]];
LED3 = 0;
dlms();
LED3 = 1;}
if(LEDN[7]==0&&LEDN[6]==0&&LEDN[5]==0&&LEDN[4]==0&&LEDN[3]==0&&LEDN[2]==0)//第2位显示,如有前缀0,则不显示
{LED=LEDDis[10];
LED2 = 0;
dlms();
LED2 = 1;}
else
{LED=LEDDis[LEDN[2]];
LED2 = 0;
dlms();
LED2 = 1;}
if(LEDN[7]==0&&LEDN[6]==0&&LEDN[5]==0&&LEDN[4]==0&&LEDN[3]==0&&LEDN[2]==0&&LEDN[1]==0)//第1位显示,如有前缀0,则不显示
{LED=LEDDis[10];
LED1 = 0;
dlms();
LED1 = 1;}
else
{LED=LEDDis[LEDN[1]];
LED1 = 0;
dlms();
LED1 = 1;}
LED=LEDDis[LEDN[0]];//第0位显示,如有前缀0,则不显示
LED0 = 0;
dlms();
LED0 = 1;
}
}
//定时器0中断外理中键扫描
void KeyAndDis_Time0(void) interrupt 1 using 2
{
TH0=0xB1; //重赋初值
TL0=0xDF;
key=kbscan();//调键扫描子程序
}