Code:
	
/* Definiert die Frequenz */
    #define F_CPU 16000000UL
/* Umbennung der Eingabe ( Taster ) */
    #define TASTER_1    (!(PIND & (1<<PD5))
    #define TASTER_2    (!(PIND & (1<<PD6))
    #define TASTER_3    (!(PIND & (1<<PD3))
    #define TASTER_4    (!(PIND & (1<<PD4))
    
/* USB Ladeerkennung */
    #define USB_CONNECTED PINB & (1<<PINB4)
/* Akku muss geladen werden */    
    #define ACCU_MUST_LOADING (!(PIND & (1<<PIND7)))
/* Summer */
    #define SUMMER_AUS      PORTC |=  (1<<PC2)
    #define SUMMER_AN     PORTC &= ~(1<<PC2)
    #define SUMMER_TOGGLE PORTC ^=  (1<<PC2)
    
/* Richtung zum schieben der Anzeige */
    #define RIGHT 1
    #define LEFT  0
    
/* Schwelle für AutoOFF ( 6000 = 1 min. ) */
    #define AUTO_OFF 6000
    
/* Verhindert ein drücken während des Betriebes */
    #define INTERRUPT_INT0_DISABLE GICR &= ~(1<<INT0)
    #define INTERRUPT_INT0_ENABLE  GICR |=  (1<<INT0)
    
/* Benötigte Bibliotheken */                                    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <avr/sleep.h>
    #include "avr/pgmspace.h"
    #include "avr/sleep.h"
    #include <string.h>
    
/* Grafiken */
const char charMap[71][8] PROGMEM ={
     {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // an
     {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, // aus
     {0xC3,0x99,0x99,0x99,0x99,0x99,0xC3,0xFF}, // null
     {0xE7,0xC7,0xE7,0xE7,0xE7,0xE7,0xE7,0xFF}, // eins
     {0xC3,0x99,0xF9,0xF3,0xE7,0xCF,0x81,0xFF}, // zwei
     {0xC3,0x99,0xF9,0xE3,0xF9,0x99,0xC3,0xFF}, // drei
     {0xF3,0xE3,0xC3,0x93,0x81,0xF3,0xF3,0xFF}, // vier
     {0x81,0x9F,0x83,0xF9,0xF9,0x99,0xC3,0xFF}, // fünf
     {0xE3,0xCF,0x9F,0x83,0x99,0x99,0xC3,0xFF}, // sechs
     {0x81,0xF9,0xF9,0xF3,0xE7,0xE7,0xE7,0xFF}, // sieben
     {0xC3,0x99,0x99,0xC3,0x99,0x99,0xC3,0xFF}, // acht
     {0xC3,0x99,0x99,0xC1,0xF9,0xF3,0xC7,0xFF}, // neun
     {0xe7,0xdb,0xdb,0xdb,0xdb,0xc3,0xdb,0xdb}, // A
     {0x87,0xbb,0xbb,0xbb,0x87,0xbb,0xbb,0x87}, // B
     {0xC3,0x99,0x3F,0x3F,0x3F,0x99,0xC3,0xFF}, // C
     {0x87,0x93,0x99,0x99,0x99,0x93,0x87,0xFF}, // D
     {0x81,0x9F,0x9F,0x87,0x9F,0x9F,0x81,0xFF}, // E
     {0x81,0x9F,0x9F,0x87,0x9F,0x9F,0x9F,0xFF}, // F
     {0xC3,0x99,0x3F,0x3F,0x31,0x99,0xC1,0xFF}, // G
     {0x99,0x99,0x99,0x81,0x99,0x99,0x99,0xFF}, // H
     {0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xFF}, // I
     {0xF9,0xF9,0xF9,0xF9,0x99,0x99,0xC3,0xFF}, // J
     {0x99,0x99,0x93,0x87,0x93,0x99,0x99,0xFF}, // K
     {0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x81,0x81}, // L
     {0x39,0x11,0x01,0x01,0x29,0x39,0x39,0xFF}, // M
     {0x39,0x19,0x09,0x21,0x31,0x39,0x39,0xFF}, // N
     {0xC3,0x99,0x99,0x99,0x99,0x99,0xC3,0xFF}, // O
     {0x83,0x99,0x99,0x83,0x9F,0x9F,0x9F,0xFF}, // P
     {0xC3,0x99,0x99,0x99,0x91,0xC3,0xF1,0xFF}, // Q
     {0x83,0x99,0x99,0x83,0x93,0x99,0x99,0xFF}, // R
     {0xC3,0x99,0x8F,0xC7,0xF1,0x99,0xC3,0xFF}, // S
     {0x81,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xFF}, // T
     {0x99,0x99,0x99,0x99,0x99,0x99,0xC1,0xFF}, // U
     {0x99,0x99,0x99,0x99,0x99,0xC3,0xE7,0xFF}, // V
     {0x39,0x39,0x39,0x29,0x01,0x11,0x39,0xFF}, // W
     {0x99,0x99,0xC3,0xE7,0xC3,0x99,0x99,0xFF}, // X
     {0x99,0x99,0x99,0xC3,0xE7,0xE7,0xE7,0xFF}, // Y
     {0x01,0xF9,0xF3,0xE7,0xCF,0x9F,0x01,0xFF}, // Z     
     {0xFF,0xFF,0xC3,0xF9,0xC1,0x99,0xC5,0xFF}, // a
     {0x9F,0x9F,0x9F,0x83,0x99,0x99,0xA3,0xFF}, // b
     {0xFF,0xFF,0xC3,0x99,0x9F,0x99,0xC3,0xFF}, // c
     {0xF9,0xF9,0xF9,0xC1,0x99,0x99,0xC5,0xFF}, // d
     {0xFF,0xFF,0xC3,0x99,0x81,0x9F,0xC3,0xFF}, // e
     {0xE3,0xC9,0xCF,0x87,0xCF,0xCF,0xCF,0xFF}, // f
     {0xFF,0xFF,0xC5,0x99,0x99,0xC1,0xF9,0xC3}, // g
     {0x9F,0x9F,0x93,0x89,0x99,0x99,0x99,0xFF}, // h
     {0xE7,0xFF,0xE7,0xE7,0xE7,0xE7,0xE7,0xFF}, // i
     {0xF3,0xFF,0xF3,0xF3,0xF3,0x33,0x33,0x87}, // j
     {0x9F,0x9F,0x99,0x93,0x87,0x93,0x99,0xFF}, // k
     {0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xFF}, // l
     {0xFF,0xFF,0x39,0x11,0x01,0x29,0x39,0xFF}, // m
     {0xFF,0xFF,0x83,0x99,0x99,0x99,0x99,0xFF}, // n
     {0xFF,0xFF,0xC3,0x99,0x99,0x99,0xC3,0xFF}, // o
     {0xFF,0xFF,0xA3,0x99,0x99,0x83,0x9F,0x9F}, // p
     {0xFF,0xFF,0xC5,0x99,0x99,0xC1,0xF9,0xF9}, // q
     {0xFF,0xFF,0xA3,0x89,0x9F,0x9F,0x9F,0xFF}, // r
     {0xFF,0xFF,0xC1,0x9F,0xC3,0xF9,0x83,0xFF}, // s
     {0xCF,0xCF,0x83,0xCF,0xCF,0xCB,0xE7,0xFF}, // t
     {0xFF,0xFF,0x99,0x99,0x99,0x99,0xC5,0xFF}, // u
     {0xFF,0xFF,0x99,0x99,0x99,0xC3,0xE7,0xFF}, // v
     {0xFF,0xFF,0x39,0x29,0x01,0x01,0x93,0xFF}, // w
     {0xFF,0xFF,0x39,0x93,0xC7,0x93,0x39,0xFF}, // x
     {0xFF,0xFF,0x99,0x99,0x99,0xC1,0xF9,0xC3}, // y
     {0xFF,0xFF,0x81,0xF3,0xE7,0xCF,0x81,0xFF}, // z         
     {0x81,0x7E,0x5A,0x7E,0x42,0x66,0x7E,0x81}, // Smiley
     {0xFF,0xE7,0xC3,0xDB,0xDB,0xDB,0xDB,0xC3}, // Battery (leer)
     {0xFF,0xE7,0xC3,0xDB,0xDB,0xDB,0xC3,0xC3}, // Battery ( mit einem Strich  )
     {0xFF,0xE7,0xC3,0xDB,0xDB,0xC3,0xC3,0xC3}, // Battery ( mit zwei Strichen )
     {0xFF,0xE7,0xC3,0xDB,0xC3,0xC3,0xC3,0xC3}, // Battery ( mit drei Strichen )
     {0xFF,0xE7,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3}, // Battery ( mit vier Strichen )
     {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF}  // Punkt für´s www(.)
     };
const char Spieler_links[7][8] PROGMEM ={
    {0xFF,0xFF,0xFD,0x80,0x80,0xFF,0xFF,0xFF}, // eins
    {0xFF,0xBD,0x9C,0x8E,0xA6,0xB0,0xB9,0xFF}, // zwei
    {0xFF,0xDD,0x9C,0xB6,0xB6,0x80,0xC9,0xFF}, // drei
    {0xFF,0xE7,0xE3,0xE9,0x80,0x80,0xEF,0xFF}, // vier
    {0xFF,0xD8,0x98,0xBA,0xBA,0x82,0xC6,0xFF}, // füns
    {0xFF,0xC3,0x81,0xB4,0xB6,0x86,0xCF,0xFF} // sechs
    };
const char Spieler_rechts[7][8] PROGMEM ={
    {0xFF,0xE7,0xE7,0xE7,0xE7,0xE7,0xE3,0xE7},
    {0xFF,0x81,0xF3,0xE7,0xCF,0x9F,0x99,0xC3},
    {0xFF,0xC3,0x99,0x9F,0xC7,0x9F,0x99,0xC3},
    {0xFF,0xCF,0xCF,0x81,0xC9,0xC3,0xC7,0xCF},
    {0xFF,0xC3,0x99,0x9F,0x9F,0xC1,0xF9,0x81},
    {0xFF,0xC3,0x99,0x99,0xC1,0xF9,0xF3,0xC7}
    };
const char Spieler_gegenueber[7][8] PROGMEM ={
    {0xFF,0xFF,0xFF,0x01,0x01,0xBF,0xFF,0xFF},
    {0xFF,0x9D,0x0D,0x65,0x71,0x39,0xBD,0xFF},
    {0xFF,0x93,0x01,0x6D,0x6D,0x39,0xBB,0xFF},
    {0xFF,0xF7,0x01,0x01,0x97,0xC7,0xE7,0xFF},
    {0xFF,0x63,0x41,0x5D,0x5D,0x19,0x1B,0xFF},
    {0xFF,0xF3,0x61,0x6D,0x2D,0x81,0xC3,0xFF}
    };
    uint8_t VRAM[50] = { };
    uint8_t USB_STATE = 0;
    uint16_t AUTO_OFF_Counter = 0;
    uint16_t CharacterIndexValue = 0;
    
    void clear_screen();
    void fill_screen();
    void check_usb();
    void Display_all_Symbols();
    uint8_t GetCharacterIndex(char a);
    void ShiftVRAM(uint8_t direction, uint16_t ms);
    void StringtoCharacter(const char *s);
    void check_ACCU();
    void check_AUTO_OFF();
    void DisplayString(uint16_t x, const char *s);
int main(void)
{
    DDRA |= ((1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3) | (1<<PA4) | (1<<PA5) | (1<<PA6) | (1<<PA7));
    DDRB |= ((1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB5) | (1<<PB6) | (1<<PB7));
    DDRC |= ((1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5) | (1<<PC6) | (1<<PC7));
    
/* TIMER0 CompareMatch (Multiplexen der Anzeige) */
    TCCR0 |= (1<<WGM01) | (1<<WGM00) | (1<<CS01) | (1<<CS00);
    TIMSK |= (1<<OCIE0);
    
    
/* Timer 1 Initalisieren */
    TCCR1B |= ((1<<CS12) | (1<<CS10)); // Teiler auf 1028
    TCCR1B |= (1<<WGM12); // CTC = ClearTimerCompare
    OCR1A   = 77; // ca. jede 10 ms. ein Überlauf
    TIMSK  |= (1<<OCIE1A); 
    
/* Interrupt "0" aktivieren */
    GICR |= (1<<INT0);
    
/* Muss ausgeschaltet werden, weil der Summer sonst dauernd an ist */
    SUMMER_AUS;
    
/* Interrupts global erlauben */
    sei(); 
    while(1)
    {    
        INTERRUPT_INT0_DISABLE;        
        check_usb();
        check_ACCU();
        check_AUTO_OFF();
    
    
        if (USB_STATE == 0)
        {        
            Display_all_Symbols();
        }
        
    
    }// Ende While 
}// Ende Main
/* Multiplexen der Anzeige */
ISR(TIMER0_COMP_vect)
{
    static volatile uint8_t spalte = 0;
    PORTC &= ~((1<<PC7) | (1<<PC6) | (1<<PC5) | (1<<PC4) | (1<<PC3));
    PORTB &= ~((1<<PB2) | (1<<PB1) | (1<<PB0));
    
    // neue Zeilendaten ausgeben
    
    PORTA = VRAM[spalte];
    // Spalte aktivieren    
    switch (spalte) {
        case 0: PORTC |= (1<<PC3);
        break;
        case 1: PORTC |= (1<<PC4);
        break;
        case 2: PORTC |= (1<<PC5);
        break;
        case 3: PORTC |= (1<<PC6);
        break;
        case 4: PORTC |= (1<<PC7);
        break;
        case 5: PORTB |= (1<<PB2);
        break;
        case 6: PORTB |= (1<<PB1);
        break;
        case 7: PORTB |= (1<<PB0);
        break;
        default: break;
    }
    spalte++; // nächste Spalte
    if (spalte >= 8) spalte = 0; // Spalten 0..7        
}
/* Jede 10 ms wird hier die Variable "Save_Value_Counter" um + 1 erhöht */
ISR (TIMER1_COMPA_vect)
{
    AUTO_OFF_Counter = AUTO_OFF_Counter + 1;        
}
/* Aufwecken des Gerätes */
ISR (INT0_vect)
{
    SUMMER_AN;
    _delay_ms(1);
    SUMMER_AUS;
}
/* Löschen des aktuellen Displays */
void clear_screen(void) 
{
    for(uint8_t i = 0 ; i < 8 ; i++)
    {
        VRAM[i] = 0xFF;
    }    
}
/* Display komplett anschalten */
void fill_screen(void)
{
    for (uint8_t i = 0 ; i < 8 ; i++)
    {
        VRAM[i] = 0x00;
    }
}
/* Checkt ob Maxi Dice mit USB Verbunden ist */
void check_usb(void)
{
    if (USB_CONNECTED)
    {
        USB_STATE = 1;
        
        for (uint8_t i = 65 ; i < 70 ; i++)
        {
            for (uint8_t d= 0 ; d < 8 ; d++)
            {
                    VRAM[d] = pgm_read_byte(&charMap[i][d]);            
            }
             _delay_ms(500);
        }
       
     }
        else
    {
        USB_STATE = 0;
    }
        
        
}
/* Routine um das gesamte Grafikaray da zu stellen */
void Display_all_Symbols()
{
    if (USB_STATE == 0)
    {
        for (uint8_t i = 0 ; i < 70 ; i++)
        {
            for (uint8_t d= 0 ; d < 8 ; d++)
            {
                VRAM[d] = pgm_read_byte(&charMap[i][d]);
            }
            check_usb();
            _delay_ms(500);
        }// Ende for
    }
}
/* Errechnet den Index des aktuellen Zeichens */
uint8_t GetCharacterIndex(char a)
{
        uint8_t index = 1;    // alles aus
        if ((a >= '0') && (a <= '9'))
        index = a+2-48;  // erste Zahl ist Index in der Tabelle des ersten Zeichens, zweite Zahl ist Index in Ascii Code des ersten Zeichens
        else if ((a >= 'A') && (a <= 'Z'))
        index = a+12-65;
        else if ((a >= 'a') && (a <= 'z'))
        index = a+38-97;
        else if ((a == '.'))
        index = a+70-46;
                
        return index;
}
/* Schiebt den gesamten Zwischenspeicher (VRAM) des Zeichens */
void ShiftVRAM(uint8_t direction, uint16_t ms)
{
    if (direction == 1)
    {
                for (uint8_t d= 0 ; d < 8 ; d++)
                {
                    VRAM[0] = VRAM[0] >> 1 | 0x80;
                    VRAM[1] = VRAM[1] >> 1 | 0x80;
                    VRAM[2] = VRAM[2] >> 1 | 0x80;
                    VRAM[3] = VRAM[3] >> 1 | 0x80;
                    VRAM[4] = VRAM[4] >> 1 | 0x80;
                    VRAM[5] = VRAM[5] >> 1 | 0x80;
                    VRAM[6] = VRAM[6] >> 1 | 0x80;
                    VRAM[7] = VRAM[7] >> 1 | 0x80;
                    
                    for (uint16_t i = 0; i < ms ; i++ )
                    {
                        _delay_ms(1);
                    }
                }
    }
        else if (direction == 0)
        {
                    for (uint8_t d= 0 ; d < 8 ; d++)
                    {
                        VRAM[0] = VRAM[0] << 1 | 0x01;
                        VRAM[1] = VRAM[1] << 1 | 0x01;
                        VRAM[2] = VRAM[2] << 1 | 0x01;
                        VRAM[3] = VRAM[3] << 1 | 0x01;
                        VRAM[4] = VRAM[4] << 1 | 0x01;
                        VRAM[5] = VRAM[5] << 1 | 0x01;
                        VRAM[6] = VRAM[6] << 1 | 0x01;
                        VRAM[7] = VRAM[7] << 1 | 0x01;
                        
                        
                        for (uint16_t i = 0; i < ms ; i++ )
                        {
                            _delay_ms(1);
                        }
                    }
                    
                    
        }
    
}
/* Übergibt den String der Routine "GetCharacterIndex" */
void StringtoCharacter(const char *s)
{
        while (*s)
        
    CharacterIndexValue = GetCharacterIndex(*s++);
}
/* Überprüft ob Akku leer ist */
void check_ACCU(void)
{
    clear_screen();
    
    if ((ACCU_MUST_LOADING))
    {
        for (uint8_t i = 65 ; i < 66 ; i++)
        {
            for (uint8_t d= 0 ; d < 8 ; d++)
            {
                VRAM[d] = pgm_read_byte(&charMap[i][d]);
            }
            check_usb();
            _delay_ms(500);
                    
        }// Ende for
        
        clear_screen();
        _delay_ms(500);
                
    }
}
/* Funktion für AutoOff */
void check_AUTO_OFF(void)
{
            set_sleep_mode(SLEEP_MODE_PWR_DOWN);
            cli();
    
            if (AUTO_OFF_Counter >= AUTO_OFF)
            {
                INTERRUPT_INT0_ENABLE;
                
                AUTO_OFF_Counter = 0;
                
                SUMMER_AN;
                _delay_ms(4);
                SUMMER_AUS;
                
                sleep_enable();
                sei();
                clear_screen();
                sleep_cpu();
                sleep_disable();
                
                INTERRUPT_INT0_DISABLE;
                
            }
                sei();
}
 
Lesezeichen