// 貯金箱 2006.2.28 小山智史(弘前大学) #include #include #include #include #define coin() bit_is_set(PINB,3) #define coin100() bit_is_clear(PINB,4) #define resetsw() bit_is_clear(PINB,5) uint8_t LED[]={0x40, 0x79, 0x24, 0x30, 0x99, 0x92, 0x02, 0x58, 0x00, 0x18}; uint8_t S=0, cntr=0, d=0, D0,D1,D2, DIGIT[]={0,0,0}, SEL[]={0x39, 0x3A, 0x3C}; SIGNAL(SIG_TIMER0_OVF){ // 2.048ms int cntr++; if(resetsw()) S=9, D2=D1=D0=0, DIGIT[2]=DIGIT[1]=DIGIT[0]=8; // リセット else if(S==0){ // 初期状態 if(coin()) S=1,cntr=0; }else if(S==1){ // コイン投入状態 if(!coin()){ if(cntr<8) S=2; else S=3,cntr=0; } }else if(S==2){ // 短パルス...50円またはノイズ if(cntr>=15) S=0; // ノイズ確定 else if(coin()){ D0+=5;S=9;} // 50円確定 }else if(S==3){ // 長パルス...10円または100円 if(cntr>=30){ D0++; S=9;} // 10円確定 else if(coin100()){ D1++; S=9;} // 100円確定 }else if(S==9){ if(!coin()&&!coin100()&&!resetsw()) S=0; // 信号オフを待つ } if(D0>=10) D0-=10, D1++; if(D1>=10) D1-=10, D2++; if(D2>=10) D2-=10; if(D2>0) d=3; else if(DIGIT[1]>0) d=2; else if(DIGIT[0]>0) d=1; else d=0,PORTB=0xf8; if(d>0){ PORTD=LED[DIGIT[(cntr)%d]]; PORTB=SEL[cntr%d]; } } int main(void){ PORTB=0xf8; DDRB=0x07; // xxrrrooo PORTD=0x7f; DDRD=0x7f; // xooooooo TCCR0A=0; TCCR0B=3; // Timer0: CK/64...8us TIMSK=0x02; // TOIE0 enable eeprom_busy_wait(); DIGIT[0]=D0=eeprom_read_byte((uint8_t *)0); eeprom_busy_wait(); DIGIT[1]=D1=eeprom_read_byte((uint8_t *)1); eeprom_busy_wait(); DIGIT[2]=D2=eeprom_read_byte((uint8_t *)2); sei(); for(;;) if(D0!=DIGIT[0]){ DIGIT[0]=D0; eeprom_busy_wait(); eeprom_write_byte((uint8_t *)0,D0); }else if(D1!=DIGIT[1]){ DIGIT[1]=D1; eeprom_busy_wait(); eeprom_write_byte((uint8_t *)1,D1); }else if(D2!=DIGIT[2]){ DIGIT[2]=D2; eeprom_busy_wait(); eeprom_write_byte((uint8_t *)2,D2); } }