Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.


Vorhergehende Überarbeitung
bausaetze:blinkenlights_spielwiese [2024/02/06 09:43] (aktuell) – Externe Bearbeitung 127.0.0.1
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>