/* ATmega8, 48, 88, 168, 328 /Reset PC6|1 28|PC5 seg_A PD0|2 27|PC4 seg_B PD1|3 26|PC3 seg_C PD2|4 25|PC2 seg_D PD3|5 24|PC1 seg_E PD4|6 23|PC0 Vcc|7 22|Gnd Gnd|8 21|Aref PB6|9 20|AVcc PB7|10 19|PB5 SCK Anode_1 seg_F PD5|11 18|PB4 MISO Anode_2 seg_G PD6|12 17|PB3 MOSI Anode_3 dot PD7|13 16|PB2 Anode_4 PB0|14 15|PB1 */ #define F_CPU 1000000UL #include #include #include /* _ _ | A | F B |- G -| E C |_ D _| .H */ uint8_t font[] = {// HGFEDCBA 0b11000000, // 0 0b11111001, // 1 0b10100100, // 2 0b10110000, // 3 0b10011001, // 4 0b10010010, // 5 0b10000010, // 6 0b11111000, // 7 0b10000000, // 8 0b10010000, // 9 }; volatile uint8_t framebuffer[4]; ISR(TIMER0_OVF_vect) { static uint8_t digit; PORTB &= 0b11000011; // clear all digits PORTB |= (0b00000100 << digit); // set current digit PORTD = framebuffer[digit]; // update segments digit++; digit = digit % 4; // keep digit in [0:3] } void init(void) { DDRD = 0b?; // segments DDRB = 0b?; // digits // we start with // normal operation // clk/1024 prescaler (about 1kHz) // interrupt on Timer 0 overflow TCCR0A = (0 << COM0A1) | (0 << COM0A0) | (0 << COM0B1) | (0 << COM0B0) | (? << WGM01) | (? << WGM00); TCCR0B = (0 << WGM02) | (? << CS02) | (? << CS01) | (? << CS00); TIMSK0 = (0 << OCIE0B) | (0 << OCIE0A) | (? << TOIE0); // allow interrupts globally sei(); } int main(void) { uint16_t count=0; uint16_t dummy; uint8_t i; init(); while(1) { dummy = count; for (i=0; i<4; i++) { framebuffer[i] = font[dummy % 10]; dummy = dummy / 10; } count++; if (count >= 10000) { count = 0; } _delay_ms(70); } }