Forum: Mikrocontroller und Digitale Elektronik PIC Matrix 30 x 160 Abfragen / Einfache Rechenoperationen ?


von Karl D. (karlmonster)


Lesenswert?

Hallo Zusammen,

ich bräuchte mal gute ideen =). ich habe ein LED Matrix mit insgesamt 30 
Modulen zu je 16 x 16 LEDs.

(Die Informationen werdem per Interface in die Module geschrieben ergo 
ich muss die Daten nur einmal senden und sie bleiben bis zur änderung im 
modul und werden angezeigt.)

Nun ist nur die Sache, dass ich insgesamt 16x16x30 = 7680 Zellen zu 
berechnen habe und dazu immer alle umliegenden Zellen der zu 
bestimmenden Zelle zu betrachten habe.

Grafisch sieht das dann so aus (Auszug)

Y = unbeteiligte Zelle
X = auszulesende Zelle
A = Zielzelle die aus den Werten von allen X entweder 1/0 hat

...............
...Y Y Y Y Y...
...Y X X X Y...
...Y X A X Y...
...Y X X X Y...
...Y Y Y Y Y...
...............

Ziel ist das hier:

http://de.wikipedia.org/wiki/Conways_Spiel_des_Lebens


nun suche ich natürlich eine möglichst effiziente programmierung, da ich 
nicht vorhabe für 7680 Zellen je die berechnung einzeln vorzunehmen.

Ich dachte an for ... next schleifen nur leider kenne ich die nur in 
Visual Basic / Quick Basic.

Ich kann für PIC Assembler bzw. Flowcode "programmieren".

Hat denn jemand eine idee wie man das am geschicktesten lösen könnte und 
habt ihr einen guten tipp welchen Typ von PIC ich verwenden sollte?

Von der Geschwindigkeit müsste man da schon schaun - ich dachte 
ursprünglich schon noch an einen 16F @ 20 MHz ; bin mir aber nicht 
sicher, ob das noch reicht ....

Vielen Dank

Karl

von Michael H. (morph1)


Lesenswert?

18er aufwärts, dann gibts gratis c-compiler von microchip

von Bernd R. (Firma: Promaxx.net) (bigwumpus)


Lesenswert?

Ja, nimm einer 18er !

Aber die Adressierung ist doch nicht so schwer !

Du nutzt einen Index (da gibt es passende Register für), den Du dann 
passend durch die Masse schiebst.

Angenommen, es sind 5x6 Module, dann gehe ich von 5x16 LEDs pro Zeile 
aus.
Die erste Zeile hat die Adresse 0 bis 79,
die zweite Zeile 80 bis 159...

Die Zelle soll in der zweiten Zeile die zweite Zelle sein, dann hat sie 
die Adresse: 81
Die Zelle darunter hat die Adresse 1, links daneben 80 ...

Und jetzt packst Du einen Index hinzu !

Adresse: 81+X
Die Zelle darunter hat die Adresse 1+X, links daneben 80+X ...

Begriffen ?

Kannst Du quasi für alle Zellen verwenden, aber die Kanten sollten 
gesondert behandelt werden! Ein "Überlauf" (besser "Rübersehen") von 
Links nach Rechts ist meine bevorzugte Methode...
Du mußt also für die Kanten evtl. andere Adressierungen in die 
Subroutine packen, abhängig vom Index...

Verstanden ?

von Karl D. (karlmonster)


Lesenswert?

Servus,

okay hab ich soweit verstanden - aber wie mache ich das mit dem index ?

Ich mach halt ne routine zum abfragen der Zellen nebenan ... aber wie 
mache das, dass der Assembler danach sozusagen zur nächsten Zelle 
"springt" ? vll wenn du mir ca. ein ablaufdiagramm im assembler-style 
oder so hättest =)
Also ich hab schon verstanden mit dem prinzip suche aber noch die 
umsetzung in assembler.

verstehtse wo ich hänge ?

das was du meintest ist natürlich gut mit entsprechen zeile +/- 1 bzw. 
spalte +/- 1. das werde ich auch so in ner sub machen     !DANKE DAFÜR 
=)

Das passt dann gut - die werte zähl ich dann zusammen dann hab ich was 
ich brauch für mein game of life.


Mit nem 18F komm ich bis 40 MHz hoch richtig ?


xD

von Master S. (snowman)


Lesenswert?

> verstehtse wo ich hänge ?
ja, und zwar du willst ideen für assembler code für etwas wofür du 
nichtmal in C hilfe willst. ein bisschen viel, nicht? C ist echt nicht 
schwer und ist sehr viel übersichtlicher als assembler. warum scheust du 
dich so sehr davor? lade doch erstmal MPLAB und C18 runter (beides 
gratis), schreib ein blink-programm und dann siehste auch, wie du dein 
spiel am besten implementierst.

> Mit nem 18F komm ich bis 40 MHz hoch richtig ?
ja, einige sogar bis 48MHz -> 12MIPS. er wird genügen solange er nur die 
matrix berechnen muss, sollte er aber noch mehr machen, müsstest du uns 
ein bischen mehr sagen ;-)

von Reinhard Kern (Gast)


Lesenswert?

Bernd Rüter schrieb:
> Angenommen, es sind 5x6 Module, dann gehe ich von 5x16 LEDs pro Zeile
> aus.
> Die erste Zeile hat die Adresse 0 bis 79,
> die zweite Zeile 80 bis 159...

Hallo,

würde ich nicht so machen, mit 2er Potenzen rechnet sichs einfacher. 
Also hätte die erste Zeile Nummern von 0..127, oder besser gleich bis 
255 gleich ein Byte. Erleichtert erheblich die Indexberechnung, und dass 
die tatsächlich angeschlossene Matrix nicht so gross ist ist ja egal, 
man bricht die Berechnung halt bei 79 ab.

Eine solche Optimierung ist allerdings bloss in Assembler sinnvoll. 
Entgegen anderslautenden Gerüchten kann man in Assembler durchaus eine 
Schleife programmieren.

Gruss Reinhard

von Bernd R. (Firma: Promaxx.net) (bigwumpus)


Lesenswert?

Karl Dietmann schrieb:

> okay hab ich soweit verstanden - aber wie mache ich das mit dem index ?

Mal so ins grobe:

Sieh Dir mal das Regsiter PLUSW an !!!!

    mowlw 0    ;damit setze ich den Index auf das 2. Element der 2. 
Zeile
    movwf hIndex
    movlw 17
    movwf lIndex

Loop1:
    Gosub Zähle_Nachbarn
    If Nachbarn>=x then blabla
    Index=Index+1
    Until genug

Zähle_Nachbarn:
Zähle_Nachbarn_normal:
    CLRF Anzahl ;Zähler der Nachbarn löschen
    movff lIndex,FSR0L ;index übertragen
    movff hIndex,FSR0H
    movlw 17           ;Auf linken unteren Nachbarn springen = -17
    subwf FSR0L,f
    btfss STATUS,C     ;Überlauf ?
    decf FSR0H,f       ;ja
    clrf wreg          ;Offset: links unten
    tstfsz plusw0      ;Feld besetzt ?
    incf Anzahl,f      ;ja
    incf wreg,f        ;Offset ein Feld weiter: unten
    tstfsz plusw0      ;Feld besetzt ?
    incf Anzahl,f      ;ja
    incf wreg,f        ;Offset ein Feld weiter: rechts unten
    tstfsz plusw0      ;Feld besetzt ?
    incf Anzahl,f      ;ja
    movlw 16           ;Offset nächste Zeile: links
    tstfsz plusw0      ;Feld besetzt ?
    incf Anzahl,f      ;ja
    incf wreg,f        ;Offset ein Feld weiter
    incf wreg,f        ;Offset ein Feld weiter: rechts
    tstfsz plusw0      ;Feld besetzt ?
    incf Anzahl,f      ;ja
    movlw 32           ;Offset nächste Zeile: links oben
    tstfsz plusw0      ;Feld besetzt ?
    incf Anzahl,f      ;ja
    incf wreg,f        ;Offset ein Feld weiter: oben
    tstfsz plusw0      ;Feld besetzt ?
    incf Anzahl,f      ;ja
    incf wreg,f        ;Offset ein Feld weiter: rechts oben
    tstfsz plusw0      ;Feld besetzt ?
    incf Anzahl,f      ;ja
    ret


Den Einsprung "Zähle_Nachbarn" kann man abändern, um die 
"Randbedingungen" zu erkennen und dann passende geänderte Routinen 
aufzurufen.

Wahrscheinlich wirsd Du 2 komplette Tabellen anlegen müssen, alt und 
neu.
Ich bin jetzt verschwenderisch mit den Bits umgegangen, da geht noch was 
- da kann man auch beide Felder in ein Array packen.

>
> Ich mach halt ne routine zum abfragen der Zellen nebenan ... aber wie
> mache das, dass der Assembler danach sozusagen zur nächsten Zelle
> "springt" ? vll wenn du mir ca. ein ablaufdiagramm im assembler-style
> oder so hättest =)
> Also ich hab schon verstanden mit dem prinzip suche aber noch die
> umsetzung in assembler.


> Mit nem 18F komm ich bis 40 MHz hoch richtig ?

Ja,
mach Dir keinen Kopp wegen der Speed !
Wenn es nicht reicht, nimmst Du mal bessere Prozessoren oder lernst zu 
programmieren ;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.