TX-1C microcontroller realizes multi-functional electronic clock

1. Experimental requirements:

Using a timer counter, design an electronic clock and use the display subroutine used previously. Hours, minutes and seconds are displayed from left to right. There are two ways to achieve this. One is to count in the interrupt program, count the hours, minutes and seconds when it is generated, and send it to the display buffer. The other is that the interrupt program clears a bit variable every second, and the main program knows the time every second by monitoring the changes in the bit variable.
Further requirements:
① Add the time adjustment program and use two or three buttons to adjust the current time. Similar to a commonly used electronic watch. The bit being adjusted can be flashed.
② You can add an alarm clock setting, which will produce intermittent beeps when the set time is up. Can be added to the calendar function.

2. Experimental results

The digital tube displays a 24-hour electronic clock;
matrix buttons S11 clock interface, S15 countdown interface, S12 time setting interface;
press S12 to adjust hours, minutes and seconds in a cycle, L8 flashes when in the time setting interface;
L1 lights up when adjusting, L2 lights up Adjust minutes, L3 lights up to adjust seconds;
press S13 to increase the value by 1, press S17 to decrease the value by 1;
after the countdown ends, the buzzer beeps at intervals;
press S16 to clear the hours, minutes and seconds.

3. Experimental ideas

(1) Module arrangement

Insert image description here
Insert image description here
Insert image description here
Insert image description here
Insert image description here

(2) Flow chart drawing

Insert image description here

(3) C51 programming

#include <reg51.h>

sbit L8 = P1^7;
sbit LED = P2^5;
sbit BUZZ = P2^3;
sbit DULA =	P2^6;	
sbit WELA =	P2^7;	

unsigned char num[10]={
    
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,
					0x7D,0x07,0x7F,0x6F,};
 
unsigned char second,minute,hour = 0;	


void delay(unsigned int t) 
{
    
     
	while(t--);
}

void Init_Timer()	
{
    
    
	TMOD = 0x21; 	
	
	TH0 = 0x3C;  	//50ms=0.05s
	TL0 = 0xB0;  	
	TR0 = 1;  		
	ET0 = 1;  		
	
	TH1 = 0x00; 
	TL1 = 0x38;
	TR1 = 0;
	ET1 = 1;
	
	EA = 1;  		
}


unsigned char flag = 0;
unsigned char count = 0;	
void Service_Timer0() interrupt 1		//T0中断服务函数
{
    
    
	TH0 = 0x3C; 	
	TL0 = 0xB0;  	
		
	
	count++;
	if(count == 20)			//20 * 50ms = 1s
	{
    
    
		count = 0;
		if(flag == 0)		//正计时状态
		{
    
    
			second++;
			if(second == 60)
			{
    
    
				second = 0;
				minute++;
				if(minute == 60)
				{
    
    
					minute = 0;
					hour++;
					if(hour == 24)
					{
    
    
						hour = 0;		
					}
				}
			}
		}
		if(flag == 1)		//倒计时状态
		{
    
    
			if(second == 0)
			{
    
    
				if(minute == 0)
				{
    
    
					if(hour == 0)
					{
    
    
						TR0 = 0;		//终止倒计时
						TR1 = 1;
						flag = 3;		//蜂鸣器标志位
					}
					else{
    
    
						hour--;
						minute = 59;
					}
				}
				else{
    
    
					minute--;
					second = 59;
				}
			}
				else
				second--;
			
		}
	}
}


unsigned int count2 = 0;
void Service_Timer1() interrupt 3		//T1中断服务函数
{
    
    
	count2++;
	if(count2 == 1500)		//0.2ms * 1500 = 0.2s
	{
    
    
		L8 = ~L8;
		count2 = 0;
		if(flag == 3)
		{
    
    
			BUZZ = ~BUZZ;
		}
	}
}


void s_Display(unsigned char sec)
{
    
    
	DULA=1;			
	P0=num[sec%10];	
	DULA=0;			
	WELA=1;			
	P0=0XDF;		//POS_6
	WELA=0;			
	delay(150);		

	DULA=1;
	P0=num[sec/10];
	DULA=0;
	WELA=1;
	
	P0=0XEF;		//POS_5
	WELA=0;
	delay(150);
}
	
void m_Display(unsigned char min)
{
    
    
	DULA=1;
	P0=num[min%10];
	DULA=0;
	WELA=1;
	P0=0XF7;		//POS_4		
	WELA=0;
	delay(150);
	
	DULA=1;
	P0=num[min/10];	
	DULA=0;
	WELA=1;
	P0=0XFB;		//POS_3	
	WELA=0;
	delay(150);
}
	
void h_Display(unsigned char hor)
{
    
    
	DULA=1;
	P0=num[hor%10];
	DULA=0;
	WELA=1;
	P0=0XFD;		//POS_2		
	WELA=0;
	delay(150);
	
	DULA=1;
	P0=num[hor/10];	
	DULA=0;
	WELA=1;
	P0=0XFE;		//POS_1		
	WELA=0;
	delay(150);
}

void SMG_Display()
{
    
    
	s_Display(second);
	m_Display(minute);
	h_Display(hour);
}


sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;

sbit C1 = P3^4;		
sbit C2 = P3^5;
sbit C3 = P3^6;
sbit C4 = P3^7;

unsigned char stat = 0; 
void Key_Scan()
{
    
    
	C2 = 0;
	C1 = C3 = C4 = 1;
	if(R2 == 0)			//S11按下,暂停/启动正计时界面
	{
    
    
		flag = 0;
		SMG_Display();
		TR1 = 0;		//不属于调整时间状态
		
		LED = 1;
		P1 = 0xff;
		LED = 0;
		
		if(R2 == 0)
		{
    
    
			TR0 = ~TR0;		
		}
		while(R2 == 0)
		{
    
    
			SMG_Display();
		}
	}
	if(R3 == 0)			//S16按下,暂停/启动倒计时界面
	{
    
    
		flag = 1;
		SMG_Display();
		TR1 = 0;		//不属于调整时间状态
		
		LED = 1;
		P1 = 0xff;
		LED = 0;
		
		if(R3 == 0)
		{
    
    
			TR0 = ~TR0;		
		}
		while(R3 == 0)
		{
    
    
			SMG_Display();
		}
	}
	
	
	C3 = 0;
	C1 = C2 = C4 = 1;
	if(R2 == 0)			//S12按下,调整时间界面按键
	{
    
    
		LED = 1;
		SMG_Display();
		if(R2 == 0)
		{
    
    
			if(TR0 == 0)		//必须在停止界面下调整时间
			{
    
    
				TR1 = 1;
				switch(stat)
				{
    
    
					case 0: stat = 1; P1 = 0xFE; break;		//s位调整
					case 1: stat = 2; P1 = 0xFD; break;		//m位调整
					case 2: stat = 0; P1 = 0xFB; break;		//h位调整
				}
			}
			
		}
		while(R2 == 0)
		{
    
    
			SMG_Display();
		}
	}
	if(R3 == 0)			//S15按下,复位按键
	{
    
    
		SMG_Display();
		
		LED = 1;
		P1 = 0xff;
		LED = 0;
		
		if(R3 == 0)
		{
    
    
			TR0 = 0;		
			TR1 = 0;
			LED = 0;
			second = minute = hour = 0;	
			
		}
		while(R3 == 0)
		{
    
    
			SMG_Display();
		}
	}
	
	
	C4 = 0;
	C1 = C2 = C3 = 1;
	if(R2 == 0)		//S13按下,加1
	{
    
    
		SMG_Display();
		if(TR1 == 1)
		{
    
    
			if(R2 == 0)
		{
    
    
			switch(stat)
			{
    
    
				case 1 : 
					second++;
					if(second == 60)
					second = 0;
					break;
				case 2 :
					minute++;
					if(minute == 60)
					minute = 0;
					break;
				case 0 : 
					hour++;
					if(hour == 24)
					hour = 0;
					break;
			}
		}
		}
		
		while(R2 == 0)
		{
    
    
			SMG_Display();
		}
	}
	if(R3 == 0)		//S17按下,减1
	{
    
    
		SMG_Display();
		if(TR1 == 1)
		{
    
    
			if(R3 == 0)
			{
    
    
				switch(stat)
				{
    
    
					case 1 : 
						if(second == 0)		//先判断,后减1
						second = 59;
						else
						second--;
						break;
					case 2 :
						if(minute == 0)
						minute = 59;
						else
						minute--;
						break;
					case 0 : 
						if(hour == 0)
						hour = 23;
						else
						hour--;
						break;
				}
			}
		}
		while(R3 == 0)
		{
    
    
			SMG_Display();
		}
	}
		
}

 
void main(){
    
    
	second = 54;		
	minute = 59;
	hour = 23;
	LED = 0;
	Init_Timer();		
	while(1)
	{
    
    	
		SMG_Display();	
		Key_Scan();		
	}
}

4. Experiment summary

(1) Unfinished part

1. Let the digital tube of the bit being adjusted flash and display.
From the schematic diagram of TX-1C, we can see that both its bit selection and segment selection need to be assigned values ​​through the P0 port, so two 74HC573 latches are used to latch the two values ​​separately so that the two do not interfere with each other. Therefore, if you want to realize bit flashing, on the one hand, you should select the corresponding bit selection and implement the flashing function on this bit; on the other hand, use the timer to write a delay program, assign the current value to be displayed for a period of time, and then turn it off. The value displayed by the digital tube lasts for a period of time, cycling between two assignments, and lighting up at intervals to achieve the flashing function.
2. Implement calendar function. In fact, it is also a digital tube display interface, which needs to set the year, month, and day. The first method is to accumulate the date through the timer, but it is a little troublesome, and the interruption requires fast in and fast out, so this method is not ideal; the second method is to accumulate the day through the 24-hour timing of the clock, and then to the month and year. The accumulation of is more feasible to achieve using this method.

(2) Parts to be optimized

1. Further realize that when switching from the countdown interface to the clock interface, the continuous operation of the clock will not be affected. In this experiment, the clock and countdown used the same timer, so it was not possible to achieve functions that did not affect each other. Later, two timers can be used to separate the two functions, and the switch-case state machine can be used to realize the cyclic switching between the key-controlled clock and the countdown without interfering with the continuous operation of the clock.
2. Further implement the temperature display interface. There is a DS18B20 temperature module on the TX-1C experimental board, which can be programmed to realize the function of switching between clock, alarm clock and temperature display.

Guess you like

Origin blog.csdn.net/Taylor_Kurt/article/details/131277949