#include <reg51.h>

// ??????
#define LED_PORT P2      // LED???P2?
#define KEY_PORT P1      // ?????P1?
#define SEG_PORT P0      // ????????P0?
#define BIT_PORT P3      // ????????P3?

// ??????
unsigned int timer_count = 0;      // 10ms?????
unsigned char second_count = 0;    // ????(0-60)
bit led_toggle = 1;                // LED????
bit system_enable = 1;             // ??????
unsigned char display_count = 0;   // ?????
unsigned char key_value = 0xFF;    // ???

// ????????
unsigned char dis_buf[2] = {0, 0}; // ???????

// ????????(0-9)
unsigned char code seg_table[] = {
    0xC0,  // 0
    0xF9,  // 1
    0xA4,  // 2
    0xB0,  // 3
    0x99,  // 4
    0x92,  // 5
    0x82,  // 6
    0xF8,  // 7
    0x80,  // 8
    0x90,  // 9
    0xFF   // ??
};

// ??????(2????)
unsigned char code bit_table[] = {
    0xFE,  // ?1?
    0xFD   // ?2?
};

// ????
void Timer0_Init(void);
void System_Init(void);
void Key_Scan(void);
void Display_Process(void);
void Display_Scan(void);
void Delay_ms(unsigned int ms);
void Delay_us(unsigned int us);

// ???
void main(void)
{
    System_Init();      // ?????
    Timer0_Init();      // ??????
    
    // ????
    EA = 1;     // ?????
    ET0 = 1;    // ?????0??
    
    // ?????
    TR0 = 1;
    
    while(1)
    {
        Key_Scan();         // ????
        Display_Process();  // ????
        Display_Scan();     // ???????
    }
}

// ?????
void System_Init(void)
{
    LED_PORT = 0xFF;    // LED??????
    SEG_PORT = 0xFF;    // ?????
    BIT_PORT = 0xFF;    // ??????
    
    timer_count = 0;
    second_count = 0;
    led_toggle = 1;
    system_enable = 1;
    display_count = 0;
    
    // ????????
    dis_buf[0] = 0;  // ??
    dis_buf[1] = 0;  // ??
}

// ???0???(??1,16????)
void Timer0_Init(void)
{
    TMOD &= 0xF0;       // ??T0????
    TMOD |= 0x01;       // ??T0???1
    
    // 12MHz??,10ms????
    // ???? = 1us
    // 10ms = 10000us
    // ?? = 65536 - 10000 = 55536 = 0xD8F0
    TH0 = (65536 - 10000) / 256;
    TL0 = (65536 - 10000) % 256;
}

// ???0??????
void Timer0_ISR(void) interrupt 1
{
    // ????
    TH0 = (65536 - 10000) / 256;
    TL0 = (65536 - 10000) % 256;
    
    // 10ms????
    timer_count++;
    
    if(timer_count >= 100)  // 1???
    {
        timer_count = 0;
        
        if(system_enable)   // ???????
        {
            if(second_count < 60)
            {
                second_count++;  // ?????1
                
                // ???????
                dis_buf[0] = second_count / 10;    // ??
                dis_buf[1] = second_count % 10;    // ??
                
                // ?60?LED??
                if(led_toggle)
                {
                    LED_PORT = ~LED_PORT;  // P2?LED????
                }
            }
            else if(second_count == 60)
            {
                // 60??LED??
                led_toggle = 0;
                LED_PORT = 0x00;  // P2???LED??
                
                // ?????60
                dis_buf[0] = 6;
                dis_buf[1] = 0;
            }
            // ??60???????
        }
    }
    
    // ???????(??????)
    display_count++;
    if(display_count >= 2)
    {
        display_count = 0;
    }
}

// ??????
void Key_Scan(void)
{
    static unsigned char key_old = 0xFF;  // ?????
    unsigned char key_temp;
    
    key_temp = KEY_PORT;  // ??P1?????
    
    if(key_temp != 0xFF)  // ?????
    {
        Delay_ms(10);     // ????
        
        if(key_temp == KEY_PORT)  // ????
        {
            if(key_temp != key_old)  // ???
            {
                key_old = key_temp;
                key_value = key_temp;
                
                // ????
                switch(key_value)
                {
                    case 0xFE:  // P1.0??:??/??
                        system_enable = ~system_enable;
                        break;
                        
                    case 0xFD:  // P1.1??:??
                        System_Init();
                        break;
                        
                    case 0xFB:  // P1.2??:LED??
                        LED_PORT = 0x00;
                        break;
                        
                    case 0xF7:  // P1.3??:LED??
                        LED_PORT = 0xFF;
                        break;
                        
                    default:
                        break;
                }
            }
        }
    }
    else
    {
        key_old = 0xFF;
    }
}

// ??????
void Display_Process(void)
{
    // ??????,???????
    if(!system_enable)
    {
        static unsigned char flash_count = 0;
        
        flash_count++;
        if(flash_count >= 50)  // 500ms????
        {
            flash_count = 0;
            
            // ???????
            if(SEG_PORT == 0xFF)
            {
                // ??????
                SEG_PORT = seg_table[dis_buf[display_count]];
            }
            else
            {
                SEG_PORT = 0xFF;  // ??
            }
        }
    }
}

// ?????????
void Display_Scan(void)
{
    // ??????,????
    BIT_PORT = 0xFF;
    
    // ????
    if(system_enable)  // ?????????
    {
        SEG_PORT = seg_table[dis_buf[display_count]];
    }
    
    // ??????
    BIT_PORT = bit_table[display_count];
    
    // ????,??????
    Delay_us(500);
}

// ??????
void Delay_ms(unsigned int ms)
{
    unsigned int i, j;
    for(i = 0; i < ms; i++)
        for(j = 0; j < 123; j++);
}

// ??????(???????)
void Delay_us(unsigned int us)
{
    unsigned int i;
    for(i = 0; i < us; i++);
}