/* ATmega8, 48, 88, 168, 328 /Reset PC6|1 28|PC5 row_1 PD0|2 27|PC4 row_2 PD1|3 26|PC3 row_3 PD2|4 25|PC2 row_4 PD3|5 24|PC1 row_5 PD4|6 23|PC0 Vcc|7 22|Gnd Gnd|8 21|Aref PB6|9 20|AVcc PB7|10 19|PB5 SCK Anode_1 row_6 PD5|11 18|PB4 MISO Anode_2 row_7 PD6|12 17|PB3 MOSI Anode_3 row_8 PD7|13 16|PB2 Anode_4 PB0|14 15|PB1 Anode_4 */ #define F_CPU 1000000UL #include #include #include uint8_t font[10][6]= { {0x3E, 0x41, 0x49, 0x41, 0x3E, 0x00}, // 0x30 0 {0x00, 0x42, 0x7F, 0x40, 0x00, 0x00}, // 0x31 1 {0x42, 0x61, 0x51, 0x49, 0x46, 0x00}, // 0x32 2 {0x21, 0x41, 0x45, 0x4B, 0x31, 0x00}, // 0x33 3 {0x18, 0x14, 0x12, 0x7F, 0x10, 0x00}, // 0x34 4 {0x27, 0x45, 0x45, 0x45, 0x39, 0x00}, // 0x35 5 {0x3C, 0x4A, 0x49, 0x49, 0x30, 0x00}, // 0x36 6 {0x01, 0x71, 0x09, 0x05, 0x03, 0x00}, // 0x37 7 {0x36, 0x49, 0x49, 0x49, 0x36, 0x00}, // 0x38 8 {0x06, 0x49, 0x49, 0x29, 0x1E, 0x00}, // 0x39 9 }; volatile uint8_t framebuffer[5]; ISR(TIMER0_OVF_vect) { static uint8_t digit; PORTB &= 0b11000001; // clear all columns PORTB |= (0b00000010 << digit); // set current column PORTD = framebuffer[digit]; // update rows digit++; digit = digit % 5; } void init(void) { DDRD = ?; // rows DDRB = ?; // columns // 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; uint8_t i; init(); while(1) { for (i=0; i<5; i++) { framebuffer[i] = ~font[count][i]; } count++; if (count >= 10) { count = 0; } _delay_ms(1000); } }