#include <STC15F2K60S2.h>
#include <intrins.h>

void delay_ms(unsigned int ms);
void delay_us(unsigned char us);

void display_student_id(unsigned long num);
unsigned char read_switch_debounced(void);

#define STUDENT_ID 4089

unsigned char code SEGMENT_CODE[17] = {
    0x3F,  // 0
    0x06,  // 1
    0x5B,  // 2
    0x4F,  // 3
    0x66,  // 4
    0x6D,  // 5
    0x7D,  // 6
    0x07,  // 7
    0x7F,  // 8
    0x6F,  // 9
    0x77,  // A
    0x7C,  // b
    0x39,  // C
    0x5E,  // d
    0x79,  // E
    0x71,  // F
    0x00   // ??
};

unsigned char code DIGIT_SELECT[4] = {0xFE, 0xFD, 0xFB, 0xF7}; // P3.0~P3.3

unsigned char display_digits[4] = {0, 0, 0, 0};

void main(void)
{
    unsigned char i;
    unsigned char switch_state, led_state;
    

    P0 = 0x00;    
    P2 = 0xFF;    
    P3 = 0xFF;    
    
    display_digits[0] = (STUDENT_ID / 1000) % 10;    
    display_digits[1] = (STUDENT_ID / 100) % 10;     
    display_digits[2] = (STUDENT_ID / 10) % 10;     
    display_digits[3] = STUDENT_ID % 10;            
    
    for(i = 0; i < 3; i++)
    {
        P2 = 0xF0;     
        delay_ms(500);  
        P2 = 0xFF;      
        delay_ms(500);  
        

        P2 = 0x0F;      
        delay_ms(500);  
        P2 = 0xFF;      
        delay_ms(500);  
    }
    
    while(1)
    {
        switch_state = read_switch_debounced();  // ??????????
        led_state = ~switch_state;               // ????
        P2 = led_state;                          // ??LED
        
        // ??2:??????(????)
        // ???????????
        for(i = 0; i < 4; i++)
        {
            P0 = 0x00;                    // ?????,????
            P3 = DIGIT_SELECT[i];         // ???i????
            
            delay_us(50);                 // ????,??????
            
            P0 = SEGMENT_CODE[display_digits[i]];  // ??????
            
            delay_ms(2);                  // ????,?????????
            
            P0 = 0x00;                    // ????,???????
            delay_us(20);                 // ????
        }
    }
}

// ??????????
unsigned char read_switch_debounced(void)
{
    static unsigned char last_state = 0xFF;
    static unsigned char stable_count = 0;
    unsigned char current_state;
    unsigned char i;
    
    current_state = P1;  // ????????
    
    // ?????????,??????????
    if(current_state == last_state)
    {
        stable_count = 0;
        return current_state;
    }
    else
    {
        // ????,??????
        stable_count++;
        
        // ????????????????
        if(stable_count > 3)
        {
            stable_count = 0;
            last_state = current_state;
        }
    }
    
    return last_state;  // ???????
}

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

// ???????(12MHz??)
void delay_us(unsigned char us)
{
    while(us--)
    {
        _nop_();  // ???,???1us
        _nop_();
        _nop_();
        _nop_();
    }
}
