Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

bausaetze:blinkenlights_spielwiese [2016/05/19 09:57] (aktuell)
Zeile 1: Zeile 1:
 +<code c>
 +/*
 +Game of Life demo
 +eHaJo Blinkenlights Bausatz
 +www.eHaJo.de
 +*/
  
 +/*
 + * Led_Matrix_mega8.c
 + *
 + * Created: 16.06.2012 10:54:30
 + ​* ​ 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 SPALTE8_PORT PORTD
 + #define SPALTE8_PIN PD4
 + //Spalte 2
 + #define SPALTE7_PORT PORTD
 + #define SPALTE7_PIN PD5
 + //Spalte 3
 + #define SPALTE6_PORT PORTD
 + #define SPALTE6_PIN PD6
 + //Spalte 4
 + #define SPALTE5_PORT PORTD
 + #define SPALTE5_PIN PD7
 + //Spalte 5
 + #define SPALTE4_PORT PORTB
 + #define SPALTE4_PIN PB0
 + //Spalte 6
 + #define SPALTE3_PORT PORTB
 + #define SPALTE3_PIN PB1
 + //Spalte 7
 + #define SPALTE2_PORT PORTB
 + #define SPALTE2_PIN PB2
 + //Spalte 8
 + #define SPALTE1_PORT PORTB
 + #define SPALTE1_PIN PB3
 +
 + //Defines fuer Spalten/​Zeilen an/aus
 +
 + #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 schoen 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] = {0xaa,​0xbb,​0xcc,​0xdd,​0xee,​0xff,​0xaf,​0xfe};​ //​Der Bildspeicher des Systems als 1D-Array
 +volatile uint8_t akt_zeile=0,​ akt_spalte=0,​ zaehler = 0, orientation = 0;
 +
 +void led_check(void);​
 +void zeile_an(uint8_t);​
 +void spalte_an(uint8_t);​
 +void update_Array(void);​
 +void rand_array(void);​
 +unsigned short get_seed(void);​
 +void bild_copy(void);​
 +uint8_t bild_check(void);​
 +
 +
 +void rand_array() ​
 + ​{ ​
 +     ​for(uint8_t i = 0; i < 8; i++) 
 +         ​for(uint8_t j = 0; j < 8; j++) 
 +             ​Bildspeicher[i] = rand(); ​
 + }
 +/*
 +void update_Array() ​
 +
 + uint8_t i, j;
 + uint8_t temp[8][8]; ​
 + uint8_t mask[8][8]; ​
 +
 + for(i = 0; i < 8; i++) 
 +
 + for(j = 0; j < 8; j++) 
 +
 +    ​temp[i][j] = Bildspeicher[i][j]; ​
 +
 +
 +
 + for(i = 0; i < 8; i++) 
 +
 + for(j = 0; j < 8; j++) 
 +
 +    ​mask[i][j] = 0; 
 +
 +
 +
 + for(i = 0; i < 8; i++) 
 +
 + for(j = 0; j < 8; j++) 
 +
 + //​Angrenzende lebende Zellen zählen ​
 + if(temp[i-1][j-1] == 1 && i     > 0 && j     > 0) ++mask[i][j]; ​
 + if(temp[i ​ ][j-1] == 1              && j     > 0) ++mask[i][j]; ​
 + if(temp[i-1][j ​ ] == 1 && i     > 0             ) ++mask[i][j]; ​
 + if(temp[i-1][j+1] == 1 && i     > 0 && j + 1 < 8) ++mask[i][j]; ​
 + if(temp[i ​ ][j+1] == 1              && j + 1 < 8) ++mask[i][j]; ​
 + if(temp[i+1][j ​ ] == 1 && i + 1 < 8             ) ++mask[i][j]; ​
 + if(temp[i+1][j-1] == 1 && i + 1 < 8 && j     > 0) ++mask[i][j]; ​
 + if(temp[i+1][j+1] == 1 && i + 1 < 8 && j + 1 < 8) ++mask[i][j]; ​
 +
 + if(mask[i][j] < 2 || mask[i][j] > 3) 
 + {
 + Bildspeicher[i][j] = 0; //Sterben durch Vereinsamung/​Überbevölkerung ​
 + }
 + else if(mask[i][j] == 3) 
 + {
 + Bildspeicher[i][j] = 1; //Neues Leben schaffen ​
 + }
 +
 +
 +}*/
 +
 +ISR(TIMER0_COMPA_vect)
 +{ // Timer-Compare interrupt, dieser zeigt die Matrix an
 + cli();
 + ALLE_ZEILEN_AUS;​
 + SPALTE_AUS(akt_spalte);​
 + akt_spalte++;​
 + akt_spalte &= 0x07; // maximal 8 zeilen
 +
 +
 + //Zeile 1
 + if(Bildspeicher[akt_spalte] & 0x01)
 + ZEILE1_AN;​
 + //Zeile 2
 + if(Bildspeicher[akt_spalte] & 0x02)
 + ZEILE2_AN;​
 + //Zeile 3
 + if(Bildspeicher[akt_spalte] & 0x04)
 + ZEILE3_AN;​
 + //Zeile 4
 + if(Bildspeicher[akt_spalte] & 0x08)
 + ZEILE4_AN;​
 + //Zeile 5
 + if(Bildspeicher[akt_spalte] & 0x10)
 + ZEILE5_AN;​
 + //Zeile 6
 + if(Bildspeicher[akt_spalte] & 0x20)
 + ZEILE6_AN;​
 + //Zeile 7
 + if(Bildspeicher[akt_spalte] & 0x40)
 + ZEILE7_AN;​
 + //Zeile 8
 + if(Bildspeicher[akt_spalte] & 0x80)
 + ZEILE8_AN;​
 +
 + SPALTE_AN(akt_spalte);​
 + sei();
 +}
 +
 +unsigned short get_seed()
 +{ // Aus dem RAM zufallswert holen fuer random-seed
 + unsigned short seed = 0;
 + unsigned short *p = (unsigned short*) (RAMEND+1);
 + extern unsigned short __heap_start;​
 +
 + while (p >= &​__heap_start + 1)
 + seed ^= * (--p);
 +
 + return seed;
 +}
 +
 +int main(void)
 +{
 + uint8_t lifetimer = 0;
 + uint8_t i = 0;
 + //Setup der IO
 + PORTB=0;
 + PORTC=0;
 + PORTD=0;
 + DDRB=0xFF; //Alles auf Ausgang, alles low
 + DDRC=0xFF; //Alles auf Ausgang, alles low
 + DDRD=0xFF;
 +
 + DDRD &= ~(1<<​PD0);​
 + PORTD |= (1<<​PD0);​
 +
 + MCUSR = 0;
 + //MCUCR &= ~(1<<​PUD);​
 + 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);​ // Compare output A aktivieren, 64er Teiler
 + OCR0A = 50; // Hier gibts nen Compare-Match Interrupt
 + TIMSK0 |= (1<<​OCIE0A);​ // Capture Interrupt enable Timer 0 Capture A
 + SREG |= (0b10000000);​ // Global Interrupt enable
 +
 + //​srand(get_seed());​ //​ Seed fuer den zufallsgenerator holen
 + //​rand_array();​ //​ Array mit zufallszahlen betanken
 + //​bild_copy();​ //​ temp-array mit array betanken
 + while(1)
 + {
 +
 + if(!(PIND & (1<<​PD0)))
 + { // Zum Bootloader springen
 + for(i = 0; i<8; i++)
 + {
 + Bildspeicher[i] = 0;
 + }
 + DDRB = 0;
 + DDRC = 0;
 + DDRD = 0;
 + PORTB=0;
 + PORTC=0;
 + PORTD=0;
 + cli();
 + ((void (*)(void))0x1000)();​ // Achtung, das hier ist eine Word-Adresse!
 + }
 + }
 +{
 +
 + //​update_Array();​ // game of life algorythmus ueber das array schicken
 +
 + //​if((bild_check() == 0))
 + //{ // wenn array gleich wie davor dann zaehler erhoehen
 + // i++;
 + //}
 + if (i >4)
 + { // wenn array 5 mal gleich dann neu berechnen
 + //​rand_array();​
 + i = 0;
 + lifetimer = 0;
 + }
 +
 + if(lifetimer++ == 255)
 + { // Wenn lifetimer abgelaufen dann neu berechnen -> oszillator kann mit
 + // temp-array vergleich nicht erkannt werden...
 + //​rand_array();​
 + }
 +
 + bild_copy();​ // aktuelles array in das temp array kopieren
 +
 + }
 +}
 +
 +void bild_copy()
 +{ // array in temp speicher kopieren
 + for(uint8_t n = 0; n < 8; n++)
 + {
 + //​Bildspeicher_temp[n] = Bildspeicher[n];​
 + }
 +}
 +
 +uint8_t bild_check()
 +{ // temp array mit bildspeicher vergleichen
 + for(uint8_t n = 0; n < 8; n++)
 + {
 + for(uint8_t m = 0; m<8; m++)
 + {
 + //​if(Bildspeicher_temp[n][m] != Bildspeicher[n][m])
 + return 1;
 + }
 + }
 + return 0;
 +}
 +
 +
 +void zeile_an(uint8_t 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;
 + }
 +}
 +
 +void spalte_an(uint8_t spalte)
 +{
 + switch(spalte)
 + {
 + 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;
 + }
 +}
 +
 +</​code>​