#define F_CPU 8000000L #include #include #include #include #include //for attiny2313 /* FUSE SETTINGS: lfuse=0xe2 (default) hfuse=0xdf (default) efuse=0xff (default) I/O PORTS PA2: reset PA1: (o) x PA0: (o) x PB7: (i) (sck) PB6: (o) x (miso) PB5: (o) x (mosi) PB4: (o) x PB3: (o) x PB2: (o) x PB1: (o) x PB0: (o) x PD6: (o) x PD5: (o) x PD4: (o) x PD3: (o) x PD2: (i) input (INT0) PD1: (o) x PD0: (o) x MISC */ #define A_ 0 #define B_ 1 #define C_ 2 #define D_ 3 #define E_ 4 #define F_ 5 #define G_ 6 #define TIMER0_OVERFLOW (TIFR & (1<64) j -= j>>6; else j=18750; _delay_ms(20); } /*if(PIND & (1<<2)) setnumber(1); else setnumber(0);*/ /*setnumber(i); if(i<139) i++; else i=0; _delay_ms(100);*/ } return 0; } uint8_t digit_to_value[10] = { (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5), //0 (1<<1) | (1<<2), //1 (1<<0) | (1<<1) | (1<<3) | (1<<4) | (1<<6), //2 (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<6), //3 (1<<1) | (1<<2) | (1<<5) | (1<<6), //4 (1<<0) | (1<<2) | (1<<3) | (1<<5) | (1<<6), //5 (1<<0) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6), //6 (1<<0) | (1<<1) | (1<<2), //7 (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6), //8 (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | (1<<6), //9 }; inline void setdigitvalue(uint8_t n, uint8_t v) { bits[n] = digit_to_value[v]; } void cleardigit1(void) { A1_DDR &= ~(1< 0){ if(!update_min_interval_counted) return; update_min_interval_counted = 0; if(num_rising && num >= oldnum - HYSTERESIS && num < oldnum && num != 0) return; if(!num_rising && num <= oldnum + HYSTERESIS && num > oldnum) return; } update_max_interval_counter = 2000; num_rising = (num >= oldnum); uint8_t t; if(num>=100){ t = num / 100; setdigitvalue(0, t); num -= t*100; setdigitvalue(1, num/10); dot = 0; } else{ t = num / 10; setdigitvalue(0, t); num -= t*10; setdigitvalue(1, num); dot = 1; } oldnum = num; } ISR(TIMER0_COMPA_vect, ISR_NOBLOCK) { static uint8_t draw_counter = 0; static uint8_t counter2 = 0; TCNT0 = 0; if(draw_counter==0){ cleardot(); setdigit1(); draw_counter = 1; } else if(draw_counter==1){ cleardigit1(); setdigit2(); draw_counter = 2; } else if(draw_counter==2){ cleardigit2(); setdot(); draw_counter = 0; } if(counter2 >= 100){ counter2 = 0; update_min_interval_counted = 1; } else counter2++; if(update_max_interval_counter > 0){ update_max_interval_counter--; } } #define PULSE_MIN_TIME 37 uint8_t calc_rpm100_from_time(uint16_t t) { if(t <= PULSE_MIN_TIME) return 255; uint16_t r = 37500 / t; if(r > 400){ return (r+20)/4; } else{ return (r+2)/4; } } #define AVGBITS 2 #define AVGLEN (1<> AVGBITS); } ISR(TIMER1_COMPA_vect) { wdt_reset(); setnumber_avg(0); TCNT1 = 0; //clear flag so no new interrupt will be run instantly (from false signals) EIFR |= (1< PULSE_MIN_TIME/2){ wdt_reset(); setnumber_avg(calc_rpm100_from_time(TCNT1)); TCNT1 = 0; } //clear flag so no new interrupt will be run instantly (from false signals) EIFR |= (1<