51单片机-第十节-独立按键及数码管优化

一、优化独立按键:

独立按键的实现中,为了解决抖动问题(在按下和抬起时,按键会在高低电平之间抖动10ms),我们在按下后Delay(20),随后进入循环,直到检测到按键抬起,再Delay(20),跳出循环。

(1)问题

如果按住按键不抬,程序会停止在独立按键的函数中。

unsigned char Key()
{
	unsigned char KeyNumber = 0;

	if (P3_1 == 0) { Delay(20); while (P3_1 == 0); Delay(20); KeyNumber = 1; }
	if (P3_0 == 0) { Delay(20); while (P3_0 == 0); Delay(20); KeyNumber = 2; }
	if (P3_2 == 0) { Delay(20); while (P3_2 == 0); Delay(20); KeyNumber = 3; }
	if (P3_3 == 0) { Delay(20); while (P3_3 == 0); Delay(20); KeyNumber = 4; }
	//这里顺序是乱的,是单片机型号决定的

	return KeyNumber;
}

(2)优化

利用定时器,每隔20ms(跳过抖动)检测一次独立按键情况,当按键抬起再执行操作。 

//获取独立按键键码,无按下时返回0
unsigned char Key()
{
	unsigned char Temp;
	Temp = Key_KeyNumber;
	Key_KeyNumber = 0;
	return Temp;
}
unsigned char Key_GetState()
{
	unsigned char KeyNumber = 0;

	if (P3_1 == 0) { KeyNumber = 1; }
	if (P3_0 == 0) { KeyNumber = 2; }
	if (P3_2 == 0) { KeyNumber = 3; }
	if (P3_3 == 0) { KeyNumber = 4; }
	//这里顺序是乱的,是单片机型号决定的

	return KeyNumber;
}
unsigned char Key_KeyNumber;
//独立按键中断,必须将此函数放入main的中断函数中,且中断时长20ms
void Key_Loop()
{
	static unsigned char NowState, LastState;
	LastState = NowState;
	NowState = Key_GetState();
	if (LastState == 1 && NowState == 0) { Key_KeyNumber = 1; }
	if (LastState == 2 && NowState == 0) { Key_KeyNumber = 2; }
	if (LastState == 3 && NowState == 0) { Key_KeyNumber = 3; }
	if (LastState == 4 && NowState == 0) { Key_KeyNumber = 4; }
}

中断函数:

void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count1, T0Count2 = 0;
	T0Count1++; 
	TH0 = 64535 / 256;
	TL0 = 64535 % 256 + 1;
	if (T0Count1 >= 20)
	{
		T0Count1 = 0;
		//需执行的操作
		Key_Loop();
	}
}

二、优化数码管:

在实现数码管时, 我们实现了在指定位置显示指定数字,并在显示一下后清零。

(1)问题:

由于每次数码管显示只显示一下,因此当一次while循环的时间过长,会导致数码管帧率过低,发生闪烁现象。

//数码管,在指定位置(1-8)显示指定数字
void Nixie(unsigned char Location, int Number)
{
	switch (Location)
	{
	case 1:P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
	case 2:P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
	case 3:P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
	case 4:P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
	case 5:P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
	case 6:P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
	case 7:P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
	case 8:P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
	}

	unsigned char NixieTable[10] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F };
	P0 = NixieTable[Number];

	Delay(1);
	P0 = 0x00;//显示一下后清零
}

(2)优化:

unsigned char Nixie_Buf[9] = { 0,10,10, 10, 10, 10, 10, 10, 10, };
void Nixie_SetBuf(unsigned char Location, unsigned char Number)
{
	Nixie_Buf[Location] = Number;
}
//数码管,在指定位置(1-8)显示指定数字
void Nixie_Scan(unsigned char Location, int Number)
{
	P0 = 0x00;//显示一下后清零
	switch (Location)
	{
	case 1:P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
	case 2:P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
	case 3:P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
	case 4:P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
	case 5:P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
	case 6:P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
	case 7:P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
	case 8:P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
	}

	unsigned char NixieTable[11] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00 };
	P0 = NixieTable[Number];
}
void Nixie_Loop()
{
	static unsigned char i = 1;
	Nixie_Scan(i,Nixie_Buf[i]);
	i++;
	if (i >= 9) i = 1;
}

你可能感兴趣的:(51单片机,嵌入式硬件,单片机)