玩转按键+数码管多文件例程

key.h

#include "system.h"	   //把timer0.h文件包含进来
sbit LSA=P2^2;	   //数码管位选管脚
sbit LSB=P2^3;
sbit LSC=P2^4;

sbit k1=P3^1;
sbit k2=P3^0;
sbit k3=P3^2;
sbit k4=P3^3;	 //定义按键端口
		
void delay(uint i);
void DigDisplay();
uchar KeyScan(uchar mode);
void datapros();
void xssmg();

key.c

#include "key.h"	 //把led.h文件包含进来
#include "system.h"	   //把timer0.h文件包含进来
 
#define KEY1 1	 //按键名称
#define KEY2 2
#define KEY3 3
#define KEY4 4

uchar code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值

uchar DisplayData[8];	//定义8位数组
char datnum1=0,datnum2=0,datnum3=0,datnum4=0;  //数码管显示数值
uchar setflag=0;	  //定时器变量
uchar wei_change=0;  //移位定义


void delay(uint i)	  //延时函数
{
	while(i--);	
}

void DigDisplay()	 //数码管显示位选
{
	uchar i;			//位选变量
	for(i=0;i<8;i++)
	{
		switch(i)	 //位选,选择点亮的数码管,
		{
			case(0):
				LSA=1;LSB=1;LSC=1; break;//显示第7
			case(1):
				LSA=0;LSB=1;LSC=1; break;//显示第6
			case(2):
				LSA=1;LSB=0;LSC=1; break;//显示第5
			case(3):
				LSA=0;LSB=0;LSC=1; break;//显示第4
			case(4):
				LSA=1;LSB=1;LSC=0; break;//显示第3 
			case(5):
				LSA=0;LSB=1;LSC=0; break;//显示第2 
			case(6):
				LSA=1;LSB=0;LSC=0; break;//显示第1 
			case(7):
				LSA=0;LSB=0;LSC=0; break;//显示第0	
		}
		P0=DisplayData[i];//发送段码
		delay(100); //间隔一段时间扫描	
		P0=0x00;//消隐
	}
}

//mode=0 单次   1:连续
uchar KeyScan(uchar mode)		//按键检测函数
{
	static uchar keyen=1;
	if(mode==1)
	{
		keyen=1;
	}
	if(keyen==1&&(k1==0||k2==0||k3==0||k4==0)) //检测按键是否按下
	{
		delay(1000);  //消抖处理
		keyen=0;
		if(k1==0)return KEY1;		 //检测哪个按键按下
		else if(k2==0)return KEY2;
		else if(k3==0)return KEY3;
		else if(k4==0)return KEY4;				
	}
	else if(k1==1&&k2==1&&k3==1&&k4==1)	 //否则 检测按键是否松手
	{
		keyen=1;		
	}
	return 0;	
}

void datapros()
{
	uchar key;
	key=KeyScan(0);	 //key=调用检测按键函数
	
	if(key==KEY4)	   //设置
	{
		setflag++;
		TR0=1;	   //开启定时器
		if(setflag==2)
		{
			TR0=0;		//关闭定时器
			setflag=0;	
		}
	}

	if(setflag==0)	 //默认/退出设置显示
	{
		DisplayData[0]=smgduan[datnum4];   //显示数码管值
		DisplayData[1]=smgduan[datnum3];
		DisplayData[2]=smgduan[datnum2];
		DisplayData[3]=smgduan[datnum1];
	}
	else	  //进入设置  数码管选中闪烁
	{
		if(key==KEY1)	    //按数码管移位变化
		{
			wei_change++;
			if(wei_change>3)wei_change=0;
			DisplayData[0]=smgduan[datnum4];
			DisplayData[1]=smgduan[datnum3];
			DisplayData[2]=smgduan[datnum2];
			DisplayData[3]=smgduan[datnum1];	
		}

		else if(key==KEY2)	 //按k2数据加
		{
			switch(wei_change)  //选中的位选++
			{
				case 0:  datnum1++;
						if(datnum1>9)datnum1=0;
						break;
				case 1:  datnum2++;
						if(datnum2>9)datnum2=0;
						break;
				case 2:  datnum3++;
						if(datnum3>9)datnum3=0;
						break;
				case 3:  datnum4++;
						if(datnum4>9)datnum4=0;
						break;

			}	
		}
		else if(key==KEY3)	 //按k3数据减
		{
			switch(wei_change)	//选中的位选--
			{
				case 0:  datnum1--;
						if(datnum1<=0)datnum1=9;		
						break;
				case 1:  datnum2--;
						if(datnum2<=0)datnum2=9;
						break;
				case 2:  datnum3--;
						if(datnum3<=0)datnum3=9;
						break;
				case 3:  datnum4--;
						if(datnum4<=0)datnum4=9;
						break;

			}	
		}
			
	}
	
}

void xssmg()	  
{
	static uint i;
	 i++;
	if(i==50)	  //50ms
	{
		switch(wei_change)	   //选中的位选
		{
			case 0: DisplayData[3]=0x00;break;	//数码管先不显示
			case 1: DisplayData[2]=0x00;break;
			case 2: DisplayData[1]=0x00;break;
			case 3: DisplayData[0]=0x00;break;
		}	
	}
	if(i==100)	   //100ms
	{
		i=0;
		switch(wei_change)	 //选中的位选
		{
			case 0: DisplayData[3]=smgduan[datnum1];break; //数码管再显示 就可以看到闪烁的效果
			case 1: DisplayData[2]=smgduan[datnum2];break;
			case 2: DisplayData[1]=smgduan[datnum3];break;
			case 3: DisplayData[0]=smgduan[datnum4];break;
		}			
	}
}

system.c

#include "system.h"
 
uchar flag_1ms=0;

void	Timer0_Init(void)
{
	TH0 = T1MS>>8; //赋初值
	TL0 = T1MS;	   //赋初值
	TMOD = 0x01;  //设置定时器0用十六位定时器方式
    EA = 1;			 //打开总中断
  	ET0 = 1;		 //打开定时器0中断
  	TR0 = 1;		 //启动定时器0		
}

void Timer0() interrupt 1		 //中断号1
{	
	TH0 = T1MS>>8; //赋初值
	TL0 = T1MS;	   //赋初值
	flag_1ms=1;
}

/*void	Delay_us(uint xus)
{
	for(;xus>0;xus--);
}

void	Delay_ms(uint xms)
{
	for(;xms>0;xms--)
	{
		Delay_us(1000);
	}
}
 */





system

#include "reg51.h"


#define	uchar unsigned char	//定义无符号字符
#define	uint  unsigned int	//定义无符号整形

#define	FOSC	12000000L	//定义晶振频率		   
#define	T1MS	(65536-FOSC/12/1000)  //定时10毫秒的时候,计数器要写入的值

//void	Delay_us(uint xus);	//us级延时
//void	Delay_ms(uint xms);	//ms级延时
void	Timer0_Init(void);  	//定时器初始化

main.c

#include "system.h"
#include "key.h"

extern	uchar flag_1ms;	   //在其他模块中寻找其定义。另外,extern也可用来进行链接指定。
void main(void)			//程序的主函数
{
	Timer0_Init(); ////定时器0函数调用
	   		
	while(1)  			//大括号里面的东西,被不停的循环执行
	{
	    datapros();
		DigDisplay();
	
		//1ms进入一次
		if(flag_1ms==1)	//加了我之后,我的大括号里面的东西,被定期的1ms执行一次,反复执行	 	
		{
		  	flag_1ms=0;
			 xssmg();	  
			 }
		 }
	 }
			 

你可能感兴趣的:(玩转按键+数码管多文件例程)