// タイムエイド(Fck=14.32MHz) // 4/14.32 * 228 * 249 * 63 =0.999s...1000秒に1秒程度進む // 2008.4.10 koyama@cc.hirosaki-u.ac.jp #include #include #include #include #include #define Fck 14.32 #define VS 156 #define HS 10 #define SYN 0x04 #define BLK 0x05 #define GRY 0x06 #define WHT 0x07 #define SCl 0x04 #define SCh 0x06 #define nop() asm volatile("nop"::) #define sc(a,b) {PORTB=a;PORTB=a; PORTB=b;PORTB=b;} #define sc8(a,b) {sc(a,b);sc(a,b);sc(a,b);sc(a,b);sc(a,b);sc(a,b);sc(a,b);sc(a,b);} #define pxl(x,r1,r2) asm volatile("rol %0\n\t" \ "out 0x18,%1\n\t"\ "brcc L1_%=\n\t" \ "out 0x18,%2\n\t"\ "L1_%=: nop\n\t" \ "out 0x18,%1\n\t"\ "brcc L2_%=\n\t" \ "out 0x18,%2\n\t"\ "L2_%=:" \ : \ : "a" (x), "r" (r1), "r" (r2) ) #define pxl8(x) {pxl(x,blk,wht);pxl(x,blk,wht);pxl(x,blk,wht);pxl(x,blk,wht);pxl(x,blk,wht);pxl(x,blk,wht);pxl(x,blk,wht);pxl(x,blk,wht);} #define SCREEN_W 64 #define SCREEN_H 16 #define LINEdup 8 #define LINEtop (5*LINEdup) #define LINEext (LINEtop+SCREEN_H*LINEdup) #define FONT_W 16 #define FONT_H 16 #define T_10 51 #define T_7 42 #define T_5 25 #define T_1 6 uint8_t vram[SCREEN_W/8*SCREEN_H]; // SCREEN_W×SCREEN_Hドットvram uint8_t BZtimer=0; // ブザー音長用カウンタ(正の間ブザーが鳴る) uint8_t bz=0xff; // 64us×35毎にbit2を反転 uint8_t S=0; // スイッチ操作に伴う状態 uint8_t SWcntr=0; // スイッチがOFFで0、ONでカウントアップ int8_t ss=0, mm, mm1; // 現在の秒と分、設定値(分) uint8_t SS=60, MM; #include "vlibnum.c" // 4×6と16×16の数字フォント prog_uint8_t bar[]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; void Hbar(uint8_t x){ uint8_t *p; // vram[]のポインタ for(p=vram;p=8){ *p=*(p+8)=*(p+16)=*(p+24)=0xff; x-=8; } else{ *p=*(p+8)=*(p+16)=*(p+24)=pgm_read_byte(&bar[x]);x=0;} } } void Strans(){ // スイッチ操作による状態遷移 DDRB=0x03; PORTB|=0x04; if(bit_is_clear(PINB,2)){ if(SWcntr<255) SWcntr++;} // SWon else SWcntr=0; DDRB=0x07; if(S==0 && SWcntr>0){ S=1;BZtimer=T_1;} // 0→1 ブッ else if(S==1){ if(SWcntr==0) S=2; // 1→2 スタート else if(SWcntr>T_10){ S=4;BZtimer=T_1;SWcntr=0;} // 1→4 ブッ(1秒後) }else if(S==2 && SWcntr>0){ S=3;BZtimer=T_1;} // 2→3 else if(S==3){ if(SWcntr==0) S=0; // 3→0 else if(SWcntr>T_10){ S=4;BZtimer=T_1;SWcntr=0;} // 3→4 ブッ(1秒後) }else if(S==4){ if(SWcntr==0){ // 4→0 リセット S=0;ss=0; MM=mm=mm1; SS=60; }else if(SWcntr>T_10){ // 4→5 ブッ S=5; BZtimer=T_1; SWcntr=0; ss=0; MM=mm=mm1=1; SS=60; } }else if(S==5){ if(SWcntr==0){ // 5→0 S=0; eeprom_busy_wait(); eeprom_write_byte((uint8_t *)0,mm1); }else if(SWcntr>T_10 || SWcntr>T_5 && mm1>0){ // 高速カウントアップ if(++mm1>99) mm1=1; MM=mm=mm1; SS=60; BZtimer=T_1; SWcntr=0; // ブッ(3,4...秒後) } } } ISR(TIM1_COMPA_vect){} // 63.687us int main (void){ uint16_t xxx; uint8_t b0,b1,b2,b3,b4,b5,b6, blk, wht, i; uint8_t line=0; // 走査線カウンタで63.687us毎にカウントアップ uint8_t BZcntr=0; // ブザー音用カウンタで63.687us毎にカウントアップ uint8_t *p; // vram[]のポインタ uint8_t sscntr=0; // 1秒作成用カウンタ PORTB=0x04; DDRB=0x07; // xxxxxooo OCR1A=OCR1C=227; // CTC on OCR1C=228(4/14.32*228=63.687us) TCCR1=0x83; // CK/4 eeprom_busy_wait(); MM=mm=mm1=eeprom_read_byte((uint8_t *)0); TIMSK=(1<=LINEtop && line0){ nop(); nop(); } // RED else{ nop(); nop(); nop(); nop(); } // GREEN }else{nop();nop();nop();nop();nop();nop();nop();nop();} // GREEN }else{ nop(); } // CYAN blk=BLK&bz; wht=WHT&bz; pxl8(b0);pxl8(b1);pxl8(b2);pxl8(b3); pxl8(b4);pxl8(b5);pxl8(b6);pxl8(i); PORTB=BLK&bz; if(line%LINEdup==LINEdup-1) p+=(SCREEN_W/8); // ライン重複 }else if(line==LINEext && PORTB&0x04) Strans();// 64*256=16.384ms else if(line==LINEext+1){ if(mm/10==0) Vputc4x6(SCREEN_W-20,SCREEN_H-6,' '); else Vputc4x6(SCREEN_W-20,SCREEN_H-6,'0'+mm/10);// mmの表示 }else if(line==LINEext+2)Vputc4x6(SCREEN_W-16,SCREEN_H-6,'0'+mm%10); else if(line==LINEext+3)Vputc4x6(SCREEN_W-8,SCREEN_H-6,'0'+ss/10); else if(line==LINEext+4)Vputc4x6(SCREEN_W-4,SCREEN_H-6,'0'+ss%10); else if(line==LINEext+5) Hbar(SS); else if(line==LINEext+6&&S==2&&(++sscntr==63)){// 15.86*63=0.999s sscntr=0; if(--MM==0){ MM=mm1; if(--SS==0) SS=60; } if(ss>0) ss--; else if(mm>0){ mm--; ss=59;} else{ S=0; MM=mm=mm1; SS=60; } if(mm==0){ if(ss==0) BZtimer=T_7; else if(ss<=2) BZtimer=T_1; } }else if(line==LINEext+14 && BZtimer>0) BZtimer--; } bz=0xff; if(BZtimer && ++BZcntr&0x20) bz=0xfb; // 63.687 * 64=4.076ms(481.7Hz) if(line==249) line=0; // 63.687 * 249 = 15.86ms } }