// シンプルな時計(AT90S2313版 CLK:12.8MHz) 2003.9.18-2009.6.26 #include #include #include volatile uint8_t d,i,j,k,hh,mm,ss,DIGIT[4]; volatile uint16_t cntr; uint8_t LED[]={0x40, 0x79, 0x24, 0x30, 0x99, 0x92, 0x02, 0x58, 0x00, 0x18}; uint8_t SEL[]={0x11, 0x12, 0x14, 0x18}; void countup(){ // 分のカウントアップ cntr=0; ss=0; if(++mm>=60){ mm=0; if(++hh>=12) hh=0; } } void wait(uint8_t n){for(i=0;i=1000){ cntr=0; if(++ss>=60) countup(); } DIGIT[0]=mm%10; DIGIT[1]=mm/10; DIGIT[2]=hh%10; DIGIT[3]=hh/10; d=((DIGIT[3]==0)?3:4); PORTB=0x10; // 一旦消す PORTD=LED[DIGIT[cntr%d]]; PORTB=SEL[cntr%d]; } int main(void){ cntr=hh=mm=ss=0; PORTB=0x10; DDRB=0x0f; // xxxroooo PORTD=0x00; DDRD=0x7f; // xooooooo TCCR0=0x05; // Timer0: CK/1024 TCCR1B=0x0c; // Timer1: CK/256...50kHz OCR1=50; // 1ms(AT90S2313 datasheet p.32) TCNT1=0; TIMSK=_BV(OCIE1A); sei(); for(;;) if(bit_is_clear(PINB,4)){ // SW onでプリセット countup(); // まずは1分カウントアップ wait(10); // 100ms待つ for(j=0;bit_is_clear(PINB,4);j++){ // SW onの間繰り返し wait(10); // 100ms待つ if(j>=60){ // 6秒後に高速カウントアップ for(k=0;k<10;k++) countup(); j--; }else if(j>10) countup(); // 1秒後に自動カウントアップ } } }