// 白黒オーバレイ時計(ATtiny45, Fck=12.8MHz) // 2007.7.6 koyama@cc.hirosaki-u.ac.jp #include #include #include #include #define Fck 12.8 #define VS 136 #define HS 10 #define SYN 0x10 #define BLK 0x11 #define WHT 0x13 #define SCREEN_W 80 #define SCREEN_H 22 #define LINEtop 56 #define LINEdup 8 #define LINEext (LINEtop+SCREEN_H*LINEdup) #define FONT_W 16 #define FONT_H 16 #define T1S 64 #define T6S 384 #define nop() asm volatile("nop"::) #define pxl(x) {if(x){PORTB=WHT;}else{PORTB=BLK;nop();}} #define pxl8(x) {pxl(x&0x80); pxl(x&0x40); pxl(x&0x20); pxl(x&0x10); pxl(x&0x08); pxl(x&0x04); pxl(x&0x02); pxl(x&0x01);} uint8_t overlay; // overlay=0...SGEN , 1...Overlay // (SCREEN_W+8)×SCREEN_Hドットvramとポインタ(ただしTV表示はSCREEN_W×SCREEN_H) uint8_t vram[SCREEN_W/8*SCREEN_H]; // (SCREEN_W+16)×SCREEN_Hドット uint8_t cntr; // 40msまたは62.5us×250毎にカウントアップ uint8_t hh=0, mm=0, ss=0; // 現在の時と分と秒の値 #include "vlibnum.c" // 4×6と16×16の数字フォント void countup(){ // 分のカウントアップ cntr=0; ss=0; if(++mm>=60){ mm=0; if(++hh>=24) hh=0; } } ISR(TIM1_COMPA_vect){ // Overlay...2.5ms CSyncなし , SGEN...62.5us if(overlay){ // OverlayならばSGENにする overlay=0; OCR1A=OCR1C=62.5*Fck/8-1; TCCR1=0x84; // 99(62.5us) } } ISR(INT0_vect){} // Csyncで wake up int main (void){ uint8_t b0,b1,b2,b3,b4,b5,b6,b7,b8, i; uint8_t *p; // vram[]のポインタ uint8_t line=0; // 走査線カウンタで64us毎にカウントアップ uint8_t S=0; // スイッチ操作に伴う状態 uint16_t SWcntr=0; // スイッチがOFFで0、ONでカウントアップ PORTB=0x10; DDRB=0x03; // xxxriioo OCR0A=124; TCCR0A=0x02; TCCR0B=0x05; // TCNT0=0..124, CK/1024 overlay=1; OCR1A=OCR1C=254; TCCR1=0x88; //254(2.5ms) // overlay=0; OCR1A=OCR1C=62.5*Fck/8-1; TCCR1=0x84; //99(62.5us) MCUCR=0x02; // Ext Int ↓ TIMSK=(1<=100){ // 10ms×100=1sec cntr=0; if(++ss>=60) countup(); } } if(overlay) GIMSK=(1<=LINEtop && line0) S=10; }else if(S==10) S=1; // SWon else if(S==1){ // 〜1秒 if(SWcntr==0) S=0; else if(SWcntr>T1S) S=2; }else if(S==2){ // 1〜6秒 if(SWcntr==0) S=0; else if(SWcntr>T6S) S=12; else if(SWcntr%6==0)S=11; }else if(S==11) S=2; // 93.75ms毎 else if(S==12){ // 10秒〜 if(SWcntr==0) S=0; } PORTB&=0xfb; }else if(line==LINEext+15){ // カウントアップ if(S>=10) countup(); } } }