51单片机-计时器-倒计时闹钟

51单片机-计时器-倒计时闹钟


1. 视频

bilibili视频地址:

https://www.bilibili.com/video/av91943244

51单片机-计时器-倒计时闹钟

2. 文件

文件下载地址:

https://download.csdn.net/download/weixin_43130546/12194355

3. 说明

注意KeyScan()函数if语句!
蜂鸣器频率问题;
想到再补充。

4. 代码


#include 

sbit BUZZER = P2^3;

sbit DULA = P2^6;
sbit WELA = P2^7;

sbit KEYOUT1 = P3^0;
sbit KEYOUT2 = P3^1;
sbit KEYOUT3 = P3^2;
sbit KEYOUT4 = P3^3;
sbit KEYIN1 = P3^4;
sbit KEYIN2 = P3^5;
sbit KEYIN3 = P3^6;
sbit KEYIN4 = P3^7;

unsigned char code DUTable[16] = 
{
	0x3F,0x06,0x5B,0x4F,
	0x66,0x6D,0x7D,0x07,
	0x7F,0x6F,0x77,0x7C,
	0x39,0x5E,0x79,0x71
};

unsigned char code WETable[8] = 
{
	~0x80,~0x40,~0x20,~0x10,
	~0x08,~0x04,~0x02,~0x01
};

unsigned char LedBuff[8] = 
{
	0x3F,0x00,0x00,0X00,
	0X00,0X00,0X00,0X00
};

unsigned char code KeyCode[4][4] = 
{
	{0x31,0x32,0x33,0x26},		   //	1		2		3		up
	{0x34,0x35,0x36,0x25},		   //	4		5		6		left
	{0x37,0x38,0x39,0x28},		   //	7		8		9		down
	{0x30,0x1B,0x0D,0x27}		   //	0		ESC		enter	right
};

unsigned char KeyStay[4][4] = 
{
	{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
};

unsigned long pdata KeyTime[4][4] = 
{
	{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}
};

unsigned char T0RH,T0RL;
bit enBuzz = 0;
bit flagCount = 0;
bit flag1s = 0;
unsigned long CountNum = 0;

void ConfigTimer0(unsigned char ms);
void KeyDriver(void);
void ShowNumber(void);

void main(void)
{
	ConfigTimer0(1);
	while(1)
	{
		KeyDriver();
		if(flagCount && flag1s)
		{
			flag1s = 0;
			if(CountNum > 0)
			{
				CountNum--;
				ShowNumber();
				if(0 == CountNum)
				{
					enBuzz = 1;
					P1 = 0x00;
					flagCount = 0;
				}
			}
		}
	}
}

void ConfigTimer0(unsigned char ms)
{
	unsigned long tmp;

	tmp = 11059200 / 12;
	tmp = tmp * ms / 1000;
	tmp = 65536 - tmp;
	tmp += 18;

	T0RH = (unsigned char)(tmp>>8);
	T0RL = (unsigned char)tmp;

	TH0 = T0RH;
	TL0 = T0RL;
	TMOD &= 0xF0;
	TMOD |= 0x01;
	EA = 1;
	ET0 = 1;
	TF0 = 0;
	TR0 = 1;
}

void ShowNumber(void)
{
	char i;
	unsigned long num = CountNum;
	unsigned char buff[8];

	for(i=0; i<8; i++)
	{
		buff[i] = num % 10;
		num /= 10;
	}
	for(i=7; i>=1; i--)
	{
		if(0 == buff[i])
		{
			LedBuff[i] = 0x00;
		}
		else
		{
			break;
		}
	}
	for(; i>=0; i--)
	{
		LedBuff[i] = DUTable[buff[i]];
	}
}

void KeyAction(unsigned char KeyCoder)
{
	if((0x26 == KeyCoder) || (0x25 == KeyCoder))
	{
		if(CountNum < 99999999)
		{
			CountNum++;
			ShowNumber();
		}
	}
	else if((0x28 == KeyCoder) || (0x27 == KeyCoder))
	{
		if(CountNum > 0)
		{
			CountNum--;
			ShowNumber();
		}
	}
	else if(0x0D == KeyCoder)
	{
		flagCount = 1;
	}
	else if(0x1B == KeyCoder)
	{
		enBuzz = 0;
		//P1 = 0xFF;
		flagCount = 0;
		CountNum = 0;
		ShowNumber();
	}
}

void KeyDriver(void)
{
	unsigned char i,j;
	static unsigned char KeyBack[4][4] = 
	{
		{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
	};
	static unsigned long pdata KeyTimer[4][4] = 
	{
		{1000,1000,1000,1000},{1000,1000,1000,1000},
		{1000,1000,1000,1000},{1000,1000,1000,1000}
	};

	for(i=0; i<4; i++)
	{
		for(j=0; j<4; j++)
		{
			if(KeyStay[i][j] != KeyBack[i][j])
			{
				if(1 == KeyBack[i][j])
				{
					P1 = 0x00;
					KeyAction(KeyCode[i][j]);
				}
				else
				{
					P1 = 0xFF;
				}
				KeyBack[i][j] = KeyStay[i][j];
			}

			if(KeyTime[i][j] > 0)
			{
				if(KeyTime[i][j] >= KeyTimer[i][j])
				{
					KeyTimer[i][j] += 200;
					if((KeyCode[i][j] == 0x26) || (KeyCode[i][j] == 0x28))
					{
						enBuzz = 1;
						KeyAction(KeyCode[i][j]);
						enBuzz = 0;
					}
				}
			}
			else
			{
				KeyTimer[i][j] = 1000;
			}
		}
	}
}

void LedScan(void)
{
	static unsigned char i = 0;

	P0 = 0x00;
	DULA = 1;
	DULA = 0;
	P0 = WETable[i];
	WELA = 1;
	WELA = 0;
	P0 = LedBuff[i];
	DULA = 1;
	DULA = 0;

	i++;
	if(i>=8)
	{
		i = 0;
	}
}

void KeyScan(void)
{
	unsigned char i;
	static unsigned char KeyOut = 0;
	static unsigned char KeyBuff[4][4] = 
	{
		{0xF,0xF,0xF,0xF},{0xF,0xF,0xF,0xF},
		{0xF,0xF,0xF,0xF},{0xF,0xF,0xF,0xF}
	};

	KeyBuff[KeyOut][0] = (KeyBuff[KeyOut][0] << 1) | KEYIN1;
	KeyBuff[KeyOut][1] = (KeyBuff[KeyOut][1] << 1) | KEYIN2;
	KeyBuff[KeyOut][2] = (KeyBuff[KeyOut][2] << 1) | KEYIN3;
	KeyBuff[KeyOut][3] = (KeyBuff[KeyOut][3] << 1) | KEYIN4;

	for(i=0; i<4; i++)
	{
		if(0x00 == (KeyBuff[KeyOut][i] & 0x0F))
		{
			KeyStay[KeyOut][i] = 0;
			KeyTime[KeyOut][i] += 4;
		}
		else if(0x0F == (KeyBuff[KeyOut][i] & 0x0F))
		{
			KeyStay[KeyOut][i] = 1;
			KeyTime[KeyOut][i] = 0;
		}
	}

	KeyOut++;
	KeyOut &= 0x3;

	switch(KeyOut)
	{
		case 0 : KEYOUT4 = 1; KEYOUT1 = 0; break;
		case 1 : KEYOUT1 = 1; KEYOUT2 = 0; break;
		case 2 : KEYOUT2 = 1; KEYOUT3 = 0; break;
		case 3 : KEYOUT3 = 1; KEYOUT4 = 0; break;
		default : break;
	}
}

void BuzzScan(void)
{
	if(enBuzz)
	{
		BUZZER = ~BUZZER;
	}
	else
	{
		BUZZER = 1;
	}
}

void InterruptTimer0(void) interrupt 1
{
	static unsigned int tmr1s = 0;

	TH0 = T0RH;
	TL0 = T0RL;

	LedScan();
	KeyScan();
	BuzzScan();

	if(flagCount)
	{
		tmr1s++;
		if(tmr1s>=1000)
		{
			tmr1s = 0;
			flag1s = 1;
		}
	}
	else
	{
		tmr1s = 0;
	}
}

你可能感兴趣的:(51单片机-计时器-倒计时闹钟)