/*
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 <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
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);
}
}
Comments