Janiiix3
12.08.2014, 17:39
Hallo liebe Gemeinde :-P
Ich habe ein wirklich "klitze kleines" Problemchen... Am besten stelle ich auch mal direkt mein Anliegen (Projekt) vor!
Undzwar...
Bin ich dabei die Software für einen fertig entwickelten "Würfel" zu programmieren (Hardware steht schon).
Dieser soll in erster Linie, Zahlen von 1-6 darstellen. Die "gewürfelten" soll jeder Spieler zu gunsten seines Sitzplatzes sehen können ( man stelle sich ein Tisch vor an jeder Seite sitzt ein Spieler, es gibt 4 Tasten... Aufgrund der gedrückten Taste, weiß der Würfel zu welcher Seite er die Zahl darstellen muss) Das klappt soweit auch alles.
Sprich meine "CharMap" ( enthält die ganzen Zeichen ) steht auch schon. Diese kann ich auch schon wie gewünscht aufrufen und ausgeben.
Nun möchte ich noch am Anfang oder mitten drinn eine Laufschrift über das Display jagen. Diese soll von : rechts nach links "scrollen".
Imoment habe ich meine an zu zeigende Grafik in einem "VRAM" (Videospeicher) Dort steht mein Zeichen drinn was ich wie gesagt anzeigen will.
Das Multiplexen funktioniert via. Interrupt ganz gut.
Mein Problem ist jetzt, dass ich nicht weiß wie ich das mit der Laufschrift hin bekommen soll...
Stand jemand von euch schon mal vor einem ähnlichen Problem und kann mir helfen ?
Anbei der 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();
}
28890
Ich habe ein wirklich "klitze kleines" Problemchen... Am besten stelle ich auch mal direkt mein Anliegen (Projekt) vor!
Undzwar...
Bin ich dabei die Software für einen fertig entwickelten "Würfel" zu programmieren (Hardware steht schon).
Dieser soll in erster Linie, Zahlen von 1-6 darstellen. Die "gewürfelten" soll jeder Spieler zu gunsten seines Sitzplatzes sehen können ( man stelle sich ein Tisch vor an jeder Seite sitzt ein Spieler, es gibt 4 Tasten... Aufgrund der gedrückten Taste, weiß der Würfel zu welcher Seite er die Zahl darstellen muss) Das klappt soweit auch alles.
Sprich meine "CharMap" ( enthält die ganzen Zeichen ) steht auch schon. Diese kann ich auch schon wie gewünscht aufrufen und ausgeben.
Nun möchte ich noch am Anfang oder mitten drinn eine Laufschrift über das Display jagen. Diese soll von : rechts nach links "scrollen".
Imoment habe ich meine an zu zeigende Grafik in einem "VRAM" (Videospeicher) Dort steht mein Zeichen drinn was ich wie gesagt anzeigen will.
Das Multiplexen funktioniert via. Interrupt ganz gut.
Mein Problem ist jetzt, dass ich nicht weiß wie ich das mit der Laufschrift hin bekommen soll...
Stand jemand von euch schon mal vor einem ähnlichen Problem und kann mir helfen ?
Anbei der 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();
}
28890