a videogame console
using the atmega 328
| Parts | Purpose |
|---|---|
| Atmega328 | main controler |
| 64 leds | display |
| 4 buttons | game input |
| 1 speaker | game sounds |
the device has a small OS which is mainly powered by timer interrupts
this controls the display, rendering all the pixels from a buffer
and the audio which plays a buffer of frequency and duration data.
the game is selected from a list of all the programs.
if you want to add a game, don't touch the operating system but simply add a C function.
and put the corresponding function pointer in the program array.
the display renders from a pixel buffer.
there are 3 different buffers for each individual brightness.
the brighter buffers are brighter because they are on for a longer time
union {
struct {
uint8_t bright[8];
uint8_t medium[8];
uint8_t faint[8];
}array;
uint64_t number[3];
} gfx_buffer;
now the image is rendered to the screen.
this is controlled via timer interrupts.
this way the grafics can be displayed automatically.
it is very efficient and the programmer of the application doesn't have to think about it and only needs to put the data in the buffers.
ISR(TIMER0_OVF_vect){ // gfx
counter++;
PORTB = 0;
PORTD = ~(1 < (counter%8)) ;
PORTB = gfx_buffer.array.faint[(counter % 8) ];
}
ISR(TIMER0_COMPA_vect){ // gfx
PORTB = gfx_buffer.array.medium[(counter % 8) ];
}
ISR(TIMER0_COMPB_vect){ // gfx
PORTB = gfx_buffer.array.bright[(counter % 8) ];
}
the games have to be added into an array, and the name in another array with the same index
the names must be in the range
hex 30-5a (dez 48-90)
the encoding is:
// 0x40 ........................................... 0x5a
// 0123456789! ABCDEFGHIJKLMNOPQRSTUVWXYZ
the corresponding ASCII:
// 0x40 ........................................... 0x5a
// 0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ
the font is defined as 5x4 glyphs with one bit per pixel
and 1 byte per row of the glyph. (4 bits per row are unused)
uint8_t numbers[] = {
// 0
0b0010,
0b0101,
0b0111,
0b0101,
0b0010,
// 1
0b0110,
0b0010,
0b0010,
0b0010,
0b0111,
// ...
// Z
0b0111,
0b0001,
0b0010,
0b0100,
0b0111,
};
void (*games[])() ={ // function pointers to each program
game_snake,
game_paint,
game_alphabet,
game_music,
};
char* game_names[] = {
"==SNAKE==",
"==PAINT==",
"==ABC==",
"==MUSIC==",
// the '=' will be displayed as empty space
};
now the game will be selectable in the startup menu