Dies ist eine alte Version des Dokuments!
/* Snake demo eHaJo Blinkenlights Bausatz www.eHaJo.de */ /* * snake.c * * Created: 14.09.2012 * Authors: CalM -> calm@calm-solutuions.de * /joggl -> info@ehajo.de */ #define F_CPU 8000000UL #include <inttypes.h> #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <stdlib.h> //Es sind 16 defines noetig //Zeile 1 #define ZEILE1_PORT PORTB #define ZEILE1_PIN PB4 //Zeile 2 #define ZEILE2_PORT PORTB #define ZEILE2_PIN PB5 //Zeile 3 #define ZEILE3_PORT PORTB #define ZEILE3_PIN PB6 //Zeile 4 #define ZEILE4_PORT PORTB #define ZEILE4_PIN PB7 //Zeile 5 #define ZEILE5_PORT PORTC #define ZEILE5_PIN PC7 //Zeile 6 #define ZEILE6_PORT PORTC #define ZEILE6_PIN PC6 //Zeile 7 #define ZEILE7_PORT PORTC #define ZEILE7_PIN PC5 //Zeile 8 #define ZEILE8_PORT PORTC #define ZEILE8_PIN PC4 //Spalte 1 #define SPALTE1_PORT PORTD #define SPALTE1_PIN PD4 //Spalte 2 #define SPALTE2_PORT PORTD #define SPALTE2_PIN PD5 //Spalte 3 #define SPALTE3_PORT PORTD #define SPALTE3_PIN PD6 //Spalte 4 #define SPALTE4_PORT PORTD #define SPALTE4_PIN PD7 //Spalte 5 #define SPALTE5_PORT PORTB #define SPALTE5_PIN PB0 //Spalte 6 #define SPALTE6_PORT PORTB #define SPALTE6_PIN PB1 //Spalte 7 #define SPALTE7_PORT PORTB #define SPALTE7_PIN PB2 //Spalte 8 #define SPALTE8_PORT PORTB #define SPALTE8_PIN PB3 #define SPALTE1_AN SPALTE1_PORT &= ~(1<<SPALTE1_PIN) #define SPALTE2_AN SPALTE2_PORT &= ~(1<<SPALTE2_PIN) #define SPALTE3_AN SPALTE3_PORT &= ~(1<<SPALTE3_PIN) #define SPALTE4_AN SPALTE4_PORT &= ~(1<<SPALTE4_PIN) #define SPALTE5_AN SPALTE5_PORT &= ~(1<<SPALTE5_PIN) #define SPALTE6_AN SPALTE6_PORT &= ~(1<<SPALTE6_PIN) #define SPALTE7_AN SPALTE7_PORT &= ~(1<<SPALTE7_PIN) #define SPALTE8_AN SPALTE8_PORT &= ~(1<<SPALTE8_PIN) #define SPALTE1_AUS SPALTE1_PORT |= (1<<SPALTE1_PIN) #define SPALTE2_AUS SPALTE2_PORT |= (1<<SPALTE2_PIN) #define SPALTE3_AUS SPALTE3_PORT |= (1<<SPALTE3_PIN) #define SPALTE4_AUS SPALTE4_PORT |= (1<<SPALTE4_PIN) #define SPALTE5_AUS SPALTE5_PORT |= (1<<SPALTE5_PIN) #define SPALTE6_AUS SPALTE6_PORT |= (1<<SPALTE6_PIN) #define SPALTE7_AUS SPALTE7_PORT |= (1<<SPALTE7_PIN) #define SPALTE8_AUS SPALTE8_PORT |= (1<<SPALTE8_PIN) #define ZEILE1_AN ZEILE1_PORT |= (1<<ZEILE1_PIN) #define ZEILE2_AN ZEILE2_PORT |= (1<<ZEILE2_PIN) #define ZEILE3_AN ZEILE3_PORT |= (1<<ZEILE3_PIN) #define ZEILE4_AN ZEILE4_PORT |= (1<<ZEILE4_PIN) #define ZEILE5_AN ZEILE5_PORT |= (1<<ZEILE5_PIN) #define ZEILE6_AN ZEILE6_PORT |= (1<<ZEILE6_PIN) #define ZEILE7_AN ZEILE7_PORT |= (1<<ZEILE7_PIN) #define ZEILE8_AN ZEILE8_PORT |= (1<<ZEILE8_PIN) #define ZEILE1_AUS ZEILE1_PORT &= ~(1<<ZEILE1_PIN) #define ZEILE2_AUS ZEILE2_PORT &= ~(1<<ZEILE2_PIN) #define ZEILE3_AUS ZEILE3_PORT &= ~(1<<ZEILE3_PIN) #define ZEILE4_AUS ZEILE4_PORT &= ~(1<<ZEILE4_PIN) #define ZEILE5_AUS ZEILE5_PORT &= ~(1<<ZEILE5_PIN) #define ZEILE6_AUS ZEILE6_PORT &= ~(1<<ZEILE6_PIN) #define ZEILE7_AUS ZEILE7_PORT &= ~(1<<ZEILE7_PIN) #define ZEILE8_AUS ZEILE8_PORT &= ~(1<<ZEILE8_PIN) #define ALLE_ZEILEN_AN {ZEILE1_AN; ZEILE2_AN; ZEILE3_AN; ZEILE4_AN;ZEILE5_AN; ZEILE6_AN; ZEILE7_AN; ZEILE8_AN;} #define ALLE_ZEILEN_AUS {ZEILE1_AUS; ZEILE2_AUS; ZEILE3_AUS; ZEILE4_AUS;ZEILE5_AUS; ZEILE6_AUS; ZEILE7_AUS; ZEILE8_AUS;} #define ALLE_SPALTEN_AN {SPALTE1_AN; SPALTE2_AN; SPALTE3_AN; SPALTE4_AN;SPALTE5_AN; SPALTE6_AN; SPALTE7_AN; SPALTE8_AN;} #define ALLE_SPALTEN_AUS {SPALTE1_AUS; SPALTE2_AUS; SPALTE3_AUS;SPALTE4_AUS; SPALTE5_AUS; SPALTE6_AUS; SPALTE7_AUS; SPALTE8_AUS;} //Nicht schön tut aber seinen dienst #define ZEILE_AUS(zeile) { switch(zeile){case 0: ZEILE1_AUS; break; case 1: ZEILE2_AUS; break; case 2: ZEILE3_AUS; break; case 3: ZEILE4_AUS; break; case 4: ZEILE5_AUS; break; case 5: ZEILE6_AUS; break; case 6: ZEILE7_AUS; break; case 7: ZEILE8_AUS; break; default: break; }} #define ZEILE_AN(zeile) {switch(zeile) { case 0: ZEILE1_AN; break; case 1: ZEILE2_AN; break; case 2: ZEILE3_AN; break; case 3: ZEILE4_AN; break; case 4: ZEILE5_AN; break; case 5: ZEILE6_AN; break; case 6: ZEILE7_AN; break; case 7: ZEILE8_AN; break; default: break;}} #define SPALTE_AUS(zeile) { switch(zeile){case 0: SPALTE1_AUS; break; case 1: SPALTE2_AUS; break; case 2: SPALTE3_AUS; break; case 3: SPALTE4_AUS; break; case 4: SPALTE5_AUS; break; case 5: SPALTE6_AUS; break; case 6: SPALTE7_AUS; break; case 7: SPALTE8_AUS; break; default: break; }} #define SPALTE_AN(zeile) {switch(zeile) { case 0: SPALTE1_AN; break; case 1: SPALTE2_AN; break; case 2: SPALTE3_AN; break; case 3: SPALTE4_AN; break; case 4: SPALTE5_AN; break; case 5: SPALTE6_AN; break; case 6: SPALTE7_AN; break; case 7: SPALTE8_AN; break; default: break;}} volatile uint8_t Bildspeicher[8][8] = { {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,1,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0} };//Der Bildspeicher des Systems als 2D-Array void snake(); void bild_clear(); volatile uint8_t x = 0, y = 0; // aktuelle koordinaten der "schlange" volatile int8_t xvec = 1; yvec = 0; // vectoren fuer die bewegung volatile uint8_t apple_x = 4, apple_y = 4; // position vom apfel volatile uint8_t erstmals = 1; volatile uint8_t akt_zeile=0; ISR(INT0_vect) { // links if(erstmals) { srand(TCNT0); erstmals = 0; } xvec = -1; yvec = 0; } ISR(INT1_vect) { // oben if(erstmals) { srand(TCNT0); erstmals = 0; } xvec = 0; yvec = 1; } ISR(INT2_vect) { // rechts if(erstmals) { srand(TCNT0); erstmals = 0; } xvec = 1; yvec = 0; } ISR(INT3_vect) { // unten if(erstmals) { srand(TCNT0); erstmals = 0; } xvec = 0; yvec = -1; } ISR(TIMER0_COMPA_vect) { cli(); ALLE_SPALTEN_AUS; ZEILE_AUS(akt_zeile); akt_zeile++; akt_zeile &= 0x07; // maximal 8 zeilen //Zeile 1 if(Bildspeicher[akt_zeile][0]) SPALTE1_AN; //Zeile 2 if(Bildspeicher[akt_zeile][1]) SPALTE2_AN; //Zeile 3 if(Bildspeicher[akt_zeile][2]) SPALTE3_AN; //Zeile 4 if(Bildspeicher[akt_zeile][3]) SPALTE4_AN; //Zeile 5 if(Bildspeicher[akt_zeile][4]) SPALTE5_AN; //Zeile 6 if(Bildspeicher[akt_zeile][5]) SPALTE6_AN; //Zeile 7 if(Bildspeicher[akt_zeile][6]) SPALTE7_AN; //Zeile 8 if(Bildspeicher[akt_zeile][7]) SPALTE8_AN; ZEILE_AN(akt_zeile); sei(); } int main(void) { //Setup der IO PORTB=0; PORTC=0; PORTD=0b00001111; // die vier Tasten sind Eingänge DDRB=0xFF; //Alles auf Ausgang, alles low DDRC=0xFF; //Alles auf Ausgang, alles low DDRD=0b11110000; // Pullups der Eingänge einschalten PORTD |= (1<<PD3) | (1<<PD2) | (1<<PD1) | (1<<PD0); MCUCR &= ~(1<<PUD); //Direkt aus dem Takt der CPU den Timer versorgen CLKSEL0 = (1<<EXTE); // externe Taktquelle einschalten CLKPR = (1<<CLKPCE); // Prescaler-Change aktivieren CLKPR = 0; // Prescaler Teilefaktor 1 TCCR0A |= (1<<WGM01); // Timer im CTC-Mode TCCR0B |= (1<<FOC0A) | (1<<CS01) | (1<<CS00); // Compare output A aktivieren, 64er Teiler OCR0A = 200; // Hier gibts nen Compare-Match Interrupt TIMSK0 |= (1<<OCIE0A); // Capture Interrupt enable Timer 0 Capture A SREG |= (0b10000000); // Global Interrupt enable EICRA |= (1<<ISC01) | (1<<ISC11) | (1<<ISC21) | (1<<ISC31); // Externe Interrupts, fallende Flanke EIMSK |= (1<<INT0) | (1<<INT1) | (1<<INT2) | (1<<INT3); // Externe Interrupts aktivieren sei(); // Globales Interrupt enable snake(); } void snake() { uint8_t zaehler = 0; while(1) { x += xvec; x %= 8; //&= 0b00000111; // Bei ueberlauf wieder von vorne anfangen y += yvec; y %= 7; // Bei ueberlauf wieder von vorne anfangen if(Bildspeicher[x][y]) // Apfel an der Stelle { apple_x = rand() % 8; apple_y = rand() % 7; zaehler++; } bild_clear(); // Letzte Schlange loeschen // Den Punktestand als binaer in der obersten Zeile anzeigen if(zaehler & 0b00000001) Bildspeicher[7][7] = 1; if(zaehler & 0b00000010) Bildspeicher[6][7] = 1; if(zaehler & 0b00000100) Bildspeicher[5][7] = 1; if(zaehler & 0b00001000) Bildspeicher[4][7] = 1; if(zaehler & 0b00010000) Bildspeicher[3][7] = 1; if(zaehler & 0b00100000) Bildspeicher[2][7] = 1; if(zaehler & 0b01000000) Bildspeicher[1][7] = 1; if(zaehler & 0b10000000) Bildspeicher[0][7] = 1; Bildspeicher[x][y] = 1; Bildspeicher[apple_x][apple_y] = 1; _delay_ms(400); } } void bild_clear() { // das array leeren for(uint8_t n = 0; n < 8; n++) { for(uint8_t m = 0; m<8; m++) { Bildspeicher[n][m] = 0; } } }