0
/*Use C51 to write the program for STC89C52 single-chip microcomputer, the clock frequency is 11.0592MHZ*/

#include <reg52.h>
#define unchar unsigned char
#define unint unsigned int
#define unlint unsigned long int
#define fosc 11059200ul
#define N 500//tick=2ms

sbit led1=P1^0;
sbit dula=P2^6;
sbit wela=P2^7;

unchar code display_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
                          //  0  , 1 ,  2 , 3  ,  4 ,  5 ,  6 ,  7 ,  8 ,  9 , 
unchar display_buf[6] = {0};// 显示缓冲区,初始值为0
unchar led_cnt=0;

unchar count_hour=0,count_minute=0,count_second=0;
unint num=0;
unlint count_sum=0;
unchar key_value=0x00,last_key=0x00,key_time=0;

unchar flag_adjust=0x01;
unchar count_adjust=0;
unint second_flash=0,minute_flash=0,hour_flash=0;
bit flag_1000ms=0,flag_100ms=0,flag_2ms=0,flag_run_stop=0;


void todisplay_buf(unchar,unchar,
                                     unchar,unchar,
                                     unchar,unchar);
void led_display(void);
void timer_init(void);
void led_flash(void);

unint key_scan(void);               //key point1
void deal_key(void);                //key point2
void timer_plus_init(void);
void timer_minus_init(void);
void timer_clear_init(void);
void turn_sum_to_hms(void);

void timer_init(void){
    TMOD &=0x7F;
    TMOD |= 0x01; // 定时器0工作在模式1(16位自动重装载)
    TH0=(65536-fosc/N/12)/256;
    TL0=(65536-fosc/N/12)%256;
  EA = 1; // 开启总中断
  ET0 = 1; // 开启定时器0中断
  TR0 = 1; // 启动定时器0
}

void timer_plus_init(void){
                    switch(flag_adjust){
                        case 0x02:
                            if(count_sum==86399){
                                count_sum=0;
                            }
                            else{
                                count_sum++;
                            }
                            break;
                        case 0x04:
                            if(count_sum>=86340){
                                count_sum=count_sum+60-86400;
                            }
                            else{
                                count_sum+=60;
                            }   
                            break;
                        case 0x08:
                            if(count_sum>=82800){
                                count_sum=count_sum+3600-86400;
                            }
                            else{
                                count_sum+=3600;
                            }
                            break;
                    }       
        }

void timer_clear_init(void){
                    switch(flag_adjust){
                        case 0x02:
                            count_sum=count_sum-count_sum%60;
                            break;
                        case 0x04:
                            count_sum=count_sum-count_sum%3600+count_sum%60;                            
                            break;
                        case 0x08:
                            count_sum=count_sum-count_sum/3600*3600;
                            break;
                    }       
}

void timer_minus_init(void){
                    switch(flag_adjust){
                        case 0x02:
                            if(count_sum==0){
                                count_sum=86399;
                            }
                            else{
                                count_sum--;
                            }
                            break;
                        case 0x04:
                            if(count_sum<=60){
                                count_sum=86400-(60-count_sum);
                            }
                            else{
                                count_sum-=60;
                            }
                            break;
                        case 0x08:
                            if(count_sum<=3600){
                                count_sum=86400-(3600-count_sum);
                            }
                            else{
                                count_sum-=3600;
                            }
                            break;
                    }
        }

void turn_sum_to_hms(void){
                count_hour=count_sum/3600;
                count_minute=count_sum%3600/60;
                count_second=count_sum%3600%60;
}
        
void todisplay_buf(unchar hour_ten,unchar hour_unit,
                                    unchar minute_ten,unchar minute_unit,
                                    unchar second_ten, unchar second_unit){
  display_buf[0] = hour_ten;
    display_buf[1]=hour_unit;
    display_buf[2]=minute_ten;
    display_buf[3]=minute_unit;
    display_buf[4] = second_ten;
    display_buf[5] = second_unit;
}


void led_display(void) {
    
        P0 = 0xff;
            wela = 1;
      P0 = ~(0x01<< led_cnt); 
            wela = 0;
            
            P0 = 0x00;
            dula = 1;
            switch(flag_adjust){
                case 0x01:
                    P0 = display_code[display_buf[led_cnt]];
                    break;
                case 0x02://second flash
                    if((led_cnt==4)||(led_cnt==5)){
                        second_flash=(second_flash+1)%101;
                        if(second_flash<=50){
                            P0=0x00;
                        }
                        else{
                            P0 = display_code[display_buf[led_cnt]];
                        }
                    }
                    else{
                        P0 = display_code[display_buf[led_cnt]];
                    }
                    break;
                case 0x04://minute flash
                    if((led_cnt==2)||(led_cnt==3)){
                        minute_flash=(minute_flash+1)%101;
                        if(minute_flash<=50){
                            P0=0x00;
                        }
                        else{
                            P0 = display_code[display_buf[led_cnt]];
                        }
                    }
                    else{
                        P0 = display_code[display_buf[led_cnt]];
                    }
                    break;
                case 0x08:////hour flash
                    if((led_cnt==0)||(led_cnt==1)){
                        hour_flash=(hour_flash+1)%101;
                        if(hour_flash<=50){
                            P0=0x00;
                        }
                        else{
                            P0 = display_code[display_buf[led_cnt]];
                        }
                    }
                    else{
                        P0 = display_code[display_buf[led_cnt]];
                    }
                    break;
            }
            dula = 0;
            led_cnt = (led_cnt + 1) % 6;
            
}

void led_flash(void){//flash per second
    led1=~led1;
}

unint key_scan(void){
    if((P3&0xf0)!=0xf0){
        return P3&0xf0;
    }
    else{
        return 0;
    }
        
}

void deal_key(void){
        switch(key_value){
            case 0xe0:
                timer_plus_init();
                break;
            case 0xd0:
                timer_minus_init();
                break;
            case 0xb0:
                timer_clear_init();
                break;
            case 0x70:
                flag_run_stop=(!flag_run_stop);
                break;
            }

}

void main(void){
        timer_init();
        while(1){

            if(flag_100ms){
                flag_100ms=0;
                if(key_scan()){
                    if(++key_time>=20){
                        if(last_key==0x70){
                            count_adjust=(count_adjust+1)%4;
                            flag_adjust=0x01<<count_adjust;
                        }
                        key_value=key_scan();
                        deal_key();
                    }
                    if(++key_time>=2){
                        key_value=key_scan();
                        if(key_value!=last_key){
                            deal_key();
                        }
                        last_key=key_value;
                    }
                    else{
                        key_time=0;
                        last_key=0;
                    }
                    
                    turn_sum_to_hms();  
                }
            }
            
            if(flag_1000ms){
                flag_1000ms=0;
                led_flash();
                if(count_sum==86399){
                    count_sum=0;
                }
                else{
                    count_sum++;
                }
                turn_sum_to_hms();
            }
            
            if(flag_2ms){
                flag_2ms=0;
                todisplay_buf(count_hour/10,count_hour%10,
                                            count_minute/10,count_minute%10,
                                            count_second/10,count_second%10);
                led_display();
            }
        }

    }

void timer0(void) interrupt 1 {
    TH0=(65536-fosc/N/12)/256;
    TL0=(65536-fosc/N/12)%256;
    num++;
    if(num==50){
        flag_100ms=1;
    }
    if (num == 500) { 
        num = 0;
        if(flag_run_stop){  
            flag_1000ms=1;
        }
    }
    
    flag_2ms=1;
}

The purpose is to realize the clock program (6 seven-segment digital tubes) that adjusts the hours, minutes and seconds respectively, s2, s3 is to increase and decrease the time, s4 is to clear, s5 is short press to stop or start timing, long press is to change the part to be adjusted, cycle switching between hours, minutes, seconds (the corresponding position is flashing) and non-flickering state, but s4 cannot clear the number of the corresponding position but All are cleared, and long press s2, s3 will change the flashing position (unexpectedly, the design should only change the flashing position by long pressing s5).

Ouroborus
  • 16,237
  • 4
  • 39
  • 62

0 Answers0