⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 key.c

📁 C51弹片机简单计算器
💻 C
字号:
//P3口接4×4行列式键盘
#include <AT89X51.H>
#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,0x86,0x88};//共阳0-9, ,E,R的LED笔划
uchar code keynb[]={0x28,0x14,0x24,0x44,0x12,0x22,0x42,0x11,0x21,0x41,
					0x88,0x84,0x82,0x81,0x48,0x18};//'+''-''*''/''=''C'
static uchar LEDN[8];
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<200;i++){}
}

uchar kbscan(void)            
{
	uchar sccode,recode;
    P3=0xf0;//发全0行扫描码*,列线输入
    if((P3&0xf0)!=0xf0)//若有键按下
    {
		dlms();//延时去抖动
		sccode=0xfe;//逐行扫描初值
        while((sccode&0x10)!=0) //判断是否扫描结束
        {
			P3=sccode;//输出行扫描码
            if((P3&0xf0)!=0xf0)
            {
				recode=((P3&0xf0)|0x0f);
                return((~sccode)+(~recode));
            }    
            else sccode=(sccode<<1)|0x01;//左移一位,并将末位补一
        }                       
    }
    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!=0x82)&&(key!=0x81)&&(key!=0x48)&&(key!=0x18))//按下的是数字键处理
		{
			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==0x48&&symbol!=0&&valueflag==1)          //'='号程序
		{
			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==0x18)                //'C'号程序
		{
			value=0;
			symbol=0;
			valueflag=0;
			keycounter=0;
			valuefirst=0;
			valuesecond=0;
		}
		else if(key==0x81&&valueflag!=0&&symbol==0)//'/'号程序
		{
			symbol='/';
			keycounter=0;
			valuefirst=value; 	
		}
		else if(key==0x82&&valueflag!=0&&symbol==0)//'*'号程序
		{
			symbol='*';
			keycounter=0;
			valuefirst=value;
		}
		else if(key==0x84&&valueflag!=0&&symbol==0)//'-'号程序
		{
			symbol='-';
			keycounter=0;
			valuefirst=value;
		}
		else if(key==0x88&&valueflag!=0&&symbol==0)//'+'号程序
		{
			symbol='+';
			keycounter=0;
			valuefirst=value;
		}
		oldkey=newkey;      
//如果键一直按下,则只算按下一次因为(oldkey一直等于newkey),松开后再按下oldkey就不等于newkey,因此键值会增加一位,因为中断时间只有20ms ,一次按键过程中会产生多次中断,故设置此两变量来判别
   
//以下为数码管显示程序
	if(value>99999999){LEDN[0]=12;LEDN[1]=12;LEDN[2]=11;LEDN[3]=LEDN[4]=LEDN[5]=LEDN[6]=LEDN[7]=0x00;}
	else{   
	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 = 1;
		dlms();
		LED7 = 0;}
	else
	{
		LED=LEDDis[LEDN[7]];
		LED7 = 1;
		dlms();
		LED7 = 0;}

	if(LEDN[7]==0&&LEDN[6]==0)//第6位显示,如有前缀0,则不显示
	{
		LED=LEDDis[10];
		LED6 = 1;
		dlms();
		LED6 = 0;}
	else
	{
		LED=LEDDis[LEDN[6]];
		LED6 = 1;
		dlms();
		LED6 = 0;}

	if(LEDN[7]==0&&LEDN[6]==0&&LEDN[5]==0)//第5位显示,如有前缀0,则不显示
	{
		LED=LEDDis[10];
		LED5 = 1;
		dlms();
		LED5 = 0;}
	else
	{
		LED=LEDDis[LEDN[5]];
		LED5 = 1;
		dlms();
		LED5 = 0;}

	if(LEDN[7]==0&&LEDN[6]==0&&LEDN[5]==0&&LEDN[4]==0)//第4位显示,如有前缀0,则不显示
	{
		LED=LEDDis[10];
		LED4 = 1;
		dlms();
		LED4 = 0;}
	else
	{
		LED=LEDDis[LEDN[4]];
		LED4 = 1;
		dlms();
		LED4 = 0;}

	if(LEDN[7]==0&&LEDN[6]==0&&LEDN[5]==0&&LEDN[4]==0&&LEDN[3]==0)//第3位显示,如有前缀0,则不显示
	{
		LED=LEDDis[10];
		LED3 = 1;
		dlms();
		LED3 = 0;}
	else
	{
		LED=LEDDis[LEDN[3]];
		LED3 = 1;
		dlms();
		LED3 = 0;}

	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 = 1;
		dlms();
		LED2 = 0;}
	else
	{
		LED=LEDDis[LEDN[2]];
		LED2 = 1;
		dlms();
		LED2 = 0;}

	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 = 1;
		dlms();
		LED1 = 0;}
	else
	{
		LED=LEDDis[LEDN[1]];
		LED1 = 1;
		dlms();
		LED1 = 0;}


	LED=LEDDis[LEDN[0]];//第0位显示,如有前缀0,则不显示
	LED0 = 1;
	dlms();
	LED0 = 0;
}}

//定时器0中断外理中键扫描
void KeyAndDis_Time0(void) interrupt 1 using 2
{
	TH0=0xB1;  //重赋初值
	TL0=0xDF; 
	key=kbscan();//调键扫描子程序
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -