51 microcontroller - stopwatch (timer scans independent buttons and digital tube)

1. Write in front

        This experiment mainly uses a timer to regularly scan independent buttons and digital tubes, replacing the delay functions in the two module functions. The advantage of using a timer for scheduled scanning is that the delay in the main function will not affect the detection of the buttons and the scanning of the digital tube, but will only affect the response speed. Because the timer overflows, the interrupt program will be executed, which is a scheduled scan.

2. Main module improvements

The general idea for improvement is:

  1. Just use a timer to replace the delay function to ensure that the original function remains unchanged.
  2. Define a Loop function called by the scheduled interrupt function.
  3. Define a new function that is called by the main function. This function has the same parameters and return value as the original function.

2.1 Independent button module

        The function of the previous independent button module is: when the release signal is detected, the button value is returned, and if no button is pressed, 0 is returned. There is a delay function in the middle to eliminate key jitter.

#include <REGX52.H>
unsigned char Keynum;
unsigned char key()
{
	unsigned char temp=0;
	temp=Keynum;
	Keynum=0;
	return temp;
}
unsigned char Independentkey()
{
	unsigned char keynum=0;
	if(P3_1==0){keynum=1;}
	if(P3_0==0){keynum=2;}
	if(P3_2==0){keynum=3;}
	if(P3_3==0){keynum=4;}

	return keynum;
}
void Key_Loop()
{
	static unsigned char Last_state,Now_state;
	Last_state=Now_state;
	Now_state=Independentkey();
	if(Last_state==1&&Now_state==0)//松手检测
	{
		Keynum=1;
	}
	if(Last_state==2&&Now_state==0)//松手检测
	{
		Keynum=2;
	}
	if(Last_state==3&&Now_state==0)//松手检测
	{
		Keynum=3;
	}
	if(Last_state==4&&Now_state==0)//松手检测
	{
		Keynum=4;
	}
}

2.2 Digital tube display module

        Previously, the function of the digital tube was to specify which digit to display. The digital tube shows that there is a short delay before performing segment selection clearing or bit selection clearing, which is completed through the delay function.

#include"Displaytube.h"
unsigned char Nixie_segs[9]={0,10,10,10,10,10,10,10,10};
void Set_Nixiesegs(unsigned char bits,number)//设置数组
{
	 Nixie_segs[bits]=number;
}
void Displaytube(unsigned char bits,segs)//bits:位选	segs:段选
{	
	static unsigned char tube[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40}; //0~9,不显示,-
	 //位选
	 P0=0x00;
	switch(bits)
	{
		case 1:P2_4=0;P2_3=0;P2_2=0;
			break;
		case 2:P2_4=0;P2_3=0;P2_2=1;
			break;
		case 3:P2_4=0;P2_3=1;P2_2=0;
			break;
		case 4:P2_4=0;P2_3=1;P2_2=1;
			break;
		case 5:P2_4=1;P2_3=0;P2_2=0;
			break;
		case 6:P2_4=1;P2_3=0;P2_2=1;
			break;
		case 7:P2_4=1;P2_3=1;P2_2=0;
			break;
		case 8:P2_4=1;P2_3=1;P2_2=1;
			break;
		default:
			break;
	}
	//段选
	P0=tube[segs];	
}
void Nixie_Loop()
{
	static unsigned char i=1;
	Displaytube(i,Nixie_segs[i]);
	i++;
	if(i>8)i=1;
}

3. Test file test.c

#include <REGX52.H>
#include"IndependentKey.h"
#include"Displaytube.h"
#include"Timer0_Init.h"
#include"AT24C02.h"
#include"Delay.h"
unsigned char millsec,sec,min;
unsigned char Stopmode=1;
void watch_show()
{
		Set_Nixiesegs(8,min/10);
		Set_Nixiesegs(7,min%10);
		Set_Nixiesegs(6,11);
		Set_Nixiesegs(5,sec/10);
		Set_Nixiesegs(4,sec%10);
		Set_Nixiesegs(3,11);
		Set_Nixiesegs(2,millsec/10);
		Set_Nixiesegs(1,millsec%10);
		if(millsec>99)
		{
			sec++;
			if(sec>59)
			{
				min++;
				sec=0;
			}
			millsec=0;	
		}
}
int main()
{
	unsigned char keynum=0; 
	Timer0_Init();
	while(1)
	{
		keynum=key();
		if(keynum!=0)
		{
			if(keynum==1)  //暂停
			{
				Stopmode=!Stopmode;	
			}
			if(keynum==2)  //复位
			{
				millsec=0;
				min=0;
				sec=0;
			}
			if(keynum==3) //保存到AT24C02
			{
				AT24C02_Writebyte(0x01,min);
				Delay(5);//写周期
				AT24C02_Writebyte(0x02,sec);
				Delay(5);
				AT24C02_Writebyte(0x03,millsec);
				Delay(5);	
			}
			if(keynum==4) //读出数据
			{
				min=AT24C02_Readbyte(0x01);
				sec=AT24C02_Readbyte(0x02);
				millsec=AT24C02_Readbyte(0x03);
			}	
		}
		watch_show();
	}
}
void Timer0_ISR() interrupt 1
{	
	static int count1,count2,count3=0;
	count1++;
	count2++;
	count3++;
	TH0=0xfc;
	TL0=0x18;
	if(count1==20) //20ms
	{
		count1=0;
		Key_Loop();
	}
	if(count2==2) //2ms
	{
		count2=0;
		Nixie_Loop();
	}
	if(count3==10) //10ms
	{
		count3=0;
		if(Stopmode==0)
			millsec++;
	} 
}

4. Brief description of effects

  • When starting, the digital tube displays "00-00-00".
  • Press the key1 button and the stopwatch starts timing.
  • Press key1 again to pause the stopwatch.
  • Press key2 to clear the stopwatch.
  • Press the key3 key to save the data to AT24C02.
  • Press the key4 key to read the data stored in AT24C02 (it will not be lost after power failure).

 

 

 

Guess you like

Origin blog.csdn.net/ssssshhbh/article/details/129229740