Skip to content

Instantly share code, notes, and snippets.

@theresalu
Last active August 29, 2015 14:21
Show Gist options
  • Save theresalu/2506fbbc9ce3c5bbcc4d to your computer and use it in GitHub Desktop.
Save theresalu/2506fbbc9ce3c5bbcc4d to your computer and use it in GitHub Desktop.
Pong
#define F_CPU 8000000UL // Taktfrequenz
#include <avr/io.h> // Input/Output
#include <inttypes.h> // Datentypen
#include <util/delay.h> // Verzögerung
#include <avr/interrupt.h> // ISR
#include <avr/sleep.h> // Sleep Modus
int16_t arr[12][10]={0},
// Array aus LED-Spalten und -Zeilenvon unten nach oben; Zahlendarstellung von links unten beginnend
a0[5][3]={{1,1,1},{1,0,1},{1,0,1},{1,0,1},{1,1,1}}, // Zahl 0
a1[5][3]={{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,0,1}}, // Zahl 1
a2[5][3]={{1,1,1},{1,0,0},{1,1,1},{0,0,1},{1,1,1}}, // Zahl 2
a3[5][3]={{1,1,1},{0,0,1},{0,1,1},{0,0,1},{1,1,1}}, // Zahl 3
a4[5][3]={{0,0,1},{0,0,1},{1,1,1},{1,0,1},{1,0,1}}, // Zahl 4
a5[5][3]={{1,1,1},{0,0,1},{1,1,1},{1,0,0},{1,1,1}}, // Zahl 5
a6[5][3]={{1,1,1},{1,0,1},{1,1,1},{1,0,0},{1,1,1}}, // Zahl 6
a7[5][3]={{0,0,1},{0,0,1},{0,0,1},{0,0,1},{1,1,1}}, // Zahl 7
a8[5][3]={{1,1,1},{1,0,1},{1,1,1},{1,0,1},{1,1,1}}, // Zahl 8
a9[5][3]={{1,1,1},{0,0,1},{1,1,1},{1,0,1},{1,1,1}}; // Zahl 9
uint8_t j, k;
// Variablendeklaration; unsigned 8 bit type (fest definierter Datentyp)
// Initialisierung Startzeit von Stunde, Minute, Sekunde
volatile uint8_t sekunde=0; // volatile: compiler optimiert Variable nicht (keine Konstante)
volatile uint8_t minute=59;
volatile uint8_t stunde=23;
volatile uint8_t timeout; // Zählvariable für sleepmode
void SchreibeZeile(uint16_t Zeile) // Ausgabe Zeile
{
PORTB = (uint8_t)((Zeile >> 8) & 0x03);
PORTD = (uint8_t)(Zeile & 0xF0);
PORTC = (uint8_t)(Zeile & 0x0F);
}
void SchreibeSpaltenNr(uint8_t SpaltenNr) // Ausgabe Spalte
{
for (int8_t i = 0; i<=11; i++)
{
if (SpaltenNr == i)
PORTB &= ~(1 << 4);
else
PORTB |= (1 << 4);
PORTB |= (1 << 3); // CLK
PORTB &= ~(1 << 3); // Flankenwechsel
PORTB |= (1 << 2); // Strobe
PORTB &= ~(1 << 2); // Flankenwechsel
}
}
void Anzeige() // Funktion, die jede einzelne LED anspricht
{
for (j=0; j<12; j++) // Spalten
for (k=0; k<10; k++) // Zeilen
{
SchreibeZeile(0); // Funktionsaufrufe
SchreibeSpaltenNr(j);
if (arr[j][k]==1) // Array aus Spalte und Zeile
{
switch(k){
case 0: SchreibeZeile(1);break; // SchreibeZeile("binäre Schreibweise")
case 1: SchreibeZeile(2);break;
case 2: SchreibeZeile(4);break;
case 3: SchreibeZeile(8);break;
case 4: SchreibeZeile(16);break;
case 5: SchreibeZeile(32);break;
case 6: SchreibeZeile(64);break;
case 7: SchreibeZeile(128);break;
case 8: SchreibeZeile(256);break;
case 9: SchreibeZeile(512);break;
default:break;
}
_delay_us(300); // Delay, damit alle LEDs deutlich sichtbar sind (kleiner -> schwach; größer -> flackern)
}
}
}
void ZeigeZahl(int8_t n, int8_t pos) // n: Zahl zwischen 0-9, pos: Position (0-3)
{
int8_t x=0,y=0,l,m; // Stelle x,y -> untere linke Ecke von Zahl
switch(pos){
case 0: x=0; y=5; // Definition der Position der Zahlenblöcke
break;
case 1: x=4; y=5;
break;
case 2: x=5; y=0;
break;
case 3: x=9; y=0;
default:break;}
for (l=0; l<3; l++) // tasten Array von Zahl ab; L: Breite der Zahl; m: Höhe der Zahl
for (m=0; m<5; m++)
{
switch(n){
case 0: arr[x+l][y+m]=a0[m][l]; break; // Kombination aus Position und anzuzeigender Zahl
case 1: arr[x+l][y+m]=a1[m][l]; break;
case 2: arr[x+l][y+m]=a2[m][l]; break;
case 3: arr[x+l][y+m]=a3[m][l]; break;
case 4: arr[x+l][y+m]=a4[m][l]; break;
case 5: arr[x+l][y+m]=a5[m][l]; break;
case 6: arr[x+l][y+m]=a6[m][l]; break;
case 7: arr[x+l][y+m]=a7[m][l]; break;
case 8: arr[x+l][y+m]=a8[m][l]; break;
case 9: arr[x+l][y+m]=a9[m][l]; break;
default: break;
}
}
}
int main(void)
{
// Definition der Ports (Ausgabe)
DDRC = 0x0f; // 0000 1111
DDRB = 0xff; // 1111 1111
DDRD = 0xf0; // 1111 0000
PORTD = 0;
PORTB = 0;
PORTC = 0;
// Timer2
TCCR2|=(1<<CS22)|(1<<CS20);
TIMSK|=(1<<TOIE2); // andere Schreibweise: TIMSK|=_BV(TOIE2);
ASSR|=(1<<AS2);
sei(); // global Interrupts erlauben; alle Interrupts ausschalten:cli()
// Taster
DDRD &= ~(1 << 2); // PORTD PIN2 als Eingang
PORTD = 0x04; //
MCUCR |= ((1 << ISC01) | (0 << ISC00)); // Fallende Flanke am INT0 Pin löst Interrupt aus
GICR |= (1 << INT0); // Externen Interupt 0 freigegeben -> int0 weckt alle sleep modi auf
while (1)
{
if (timeout<30) // Bedingung für sleep modus
{
Anzeige();
}
else // wenn 30sek abgelaufen
{
set_sleep_mode (SLEEP_MODE_PWR_SAVE); // power save mode
sleep_mode(); // sleep mode starten
}
}
}
ISR(INT0_vect) // External Interrupt 0; Beschäftigung für Prozessor
{
timeout=0; // timeout Variable zurücksetzen
}
ISR(TIMER2_OVF_vect) // interrupt service routine; avr-libc S.241
{
sekunde++;
// Definition Zeiten
if (sekunde>=60)
{
sekunde=0;
minute++;
}
if (minute>=60)
{
minute=0;
stunde++;
}
if (stunde>=24)
{
stunde=0;
}
ZeigeZahl((stunde/10),0); // (n, pos)
ZeigeZahl((stunde%10),1);
ZeigeZahl((minute/10),2);
ZeigeZahl((minute%10),3);
if (timeout<31)
{
timeout++; // Hochzählen timeout bis 30sek
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment