PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mutliplxing Code kürzen



8mm
13.01.2008, 13:27
Hi,

ich bin neu hier und will mich erstmal kurz vorstellen.
Ich bin Phil, 20 und bin Neueinsteiger im Thema Elektronik.
Ich habe zwischen den Jahren ein Programmiergerät für einen ATmega32 mit Programmierkabel gelötet. Das war das erstemal, dass ich mit einem Lötkolben gearbeitet habe und mich mit Spannungen und Strom beschäftigt habe. Bin von daher von meinem ergebnis um so überraschter.

Antrieb für mein neues Hobby war ein Video auf YouTube von einer LED-Matrix und da dachte ich mir "das will ich auch"! Ja und nun bin ich hier angelangt mit meinen Fragen, denn hier auf dieser Seite habe ich sehr viel über BASCOM-avr erfahren.

Hatte vorher auch noch nie was mit basic zu tun (nur php, mySQL und etwas Pascal) und habe nun mein eigenes Programm für mutliplexing geschrieben:


$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 1600000
$baud = 9600

Config Portc = Output
Config Portb = Output
Portc.0 = 0
Portc.1 = 0
Portc.2 = 0
Portc.3 = 0
Portc.4 = 0
Portc.5 = 0
Portc.6 = 0
Portc.7 = 0
Portb.7 = 0

Dim Col As Integer
Dim Row As Integer
Dim Time As Integer
Time = 1


Do

For Col = 0 To 8

Config Porta = Input
Portc.0 = 0
Portc.1 = 0
Portc.2 = 0
Portc.3 = 0
Portc.4 = 0
Portc.5 = 0
Portc.6 = 0
Portc.7 = 0
Portb.7 = 0
If Col = 0 Then
Portc.0 = 1
Waitms Time
Elseif Col = 1 Then
Portc.1 = 1
Waitms Time
Elseif Col = 2 Then
Portc.2 = 1
Waitms Time
Elseif Col = 3 Then
Portc.3 = 1
Waitms Time
Elseif Col = 3 Then
Portc.3 = 1
Waitms Time
Elseif Col = 4 Then
Portc.4 = 1
Waitms Time
Elseif Col = 5 Then
Portc.5 = 1
Waitms Time
Elseif Col = 6 Then
Portc.6 = 1
Waitms Time
Elseif Col = 7 Then
Portc.7 = 1
Waitms Time
Elseif Col = 8 Then
Portb.7 = 1
Waitms Time
End If

For Row = 0 To 3
Config Porta = Input
If Row = 0 Then
Config Porta.0 = Output
Waitms Time
Elseif Row = 1 Then
Config Porta.1 = Output
Waitms Time
Elseif Row = 2 Then
Config Porta.2 = Output
Waitms Time
End If

Next

Next

Loop

Meine Frage ist nun: Wie kann ich diesen Code etwas kürzen?

in php wüsste ich das, denn ich würde dieses ganzen if - ellseif dinger kürzen in dem ich einfach mache:

portc.Col (dass das halt da durchläuft) aber das geht nicht.

Ich hoffe, mir kannn jmd helfen!

______
was ich vllt noch erwähnen müsste: An PA0-2 sind die Ebenen der 3x3x3 Matrix. an PC0-7 und PB7 sind die Spalten der Matrix.

PicNick
13.01.2008, 14:12
..portc.Col (dass das halt da durchläuft) aber das geht nicht.

?? Wieso nicht, wer sagt das ??

8mm
13.01.2008, 14:14
Bascom sagt das!

PORTC. ist fest definiert - Col ist eine Variable.

PicNick
13.01.2008, 14:19
*grmpf*

..PORTC. ist fest definiert - Col ist eine Variable..

richtig. und ?

probier mal


for n = 0 to 7
portc.n = 1
next

8mm
13.01.2008, 14:19
Hey,

geht wohl doch - aber mit nur col!


$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 1600000
$baud = 9600

Config Portc = Output
Config Portb = Output
Portc = 0
Portb = 0

Dim Col As Integer
Dim Row As Integer
Dim Time As Integer
Time = 1000


Do

For Col = 0 To 8

Config Porta = Input
Portc = 0
Portb = 0

Portc.col = 1
Waitms Time
Portc.col = 1
Waitms Time

For Row = 0 To 3
Config Porta = Input
Config Porta.row = Output
Waitms Time
Elseif Row = 1 Then
Config Porta.1 = Output
Waitms Time
Elseif Row = 2 Then
Config Porta.2 = Output
Waitms Time
End If

Next

Next

Loop

Wenn ich das unten bei den rows mache kommt:

UNOWN Config PARAMETER [PORTA.ROW]

PicNick
13.01.2008, 14:25
.. Config Porta.row = Output ..

Das ist natürlich ein Brimsen.

das wär dann DDRA.row = 1

Unterschied ist : Compile-time versus Run-Time

8mm
13.01.2008, 14:31
also anstatt:
Config Porta.row = Output
mach ich
DDRA.row = 1

eh net, oder?

PicNick
13.01.2008, 14:47
richtig.

DDRA ist das In/out controll register
PINA ist Input
PORTA ist Output

und, unabhängig davon,
kannst du bei einem beliebigen Byte feste Werte (PORTB.3 = ) oder eben auch variable verwenden (PORTB.var = )

Schau aber nochmal in dein Programm :
"for col = 0 to 8" wären 9 Bits, soviele gibt's nicht

8mm
13.01.2008, 14:58
okay mein code sieht jetzt so aus:



$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 1600000
$baud = 9600

Config Portc = Output
Config Portb = Output

Dim Col As Integer
Dim Row As Integer

Do

For Col = 0 To 8

Config Porta = Input
Portc = 0
Portb = 0
Portc.col = 1
If Col = 8 Then
Portb.7 = 1
End If

For Row = 0 To 3
Config Porta = Input
DDRA.row = 1

Next

Next

Loop

Was kann ich jetzt noch machen?

stefan_Z
13.01.2008, 16:27
DIM COL AS BYTE
DIM ROW AS BYTE
spart schonmal RAM und ist eleganter... mehr als 255 Zeilen/Spalten wirste kaum haben, oder?
Und wieso setzt du PortA ständig als Input?
Das brauchste nur einmal ganz oben vor dem Loop für beide Ports als Output machen.
FOR COL = 0 TO 8
ist immer noch falsch, der Port hat nur 8 Pins, angefangen bei 0. 0 bis 8 sind aber 9 Zustände ;-)

Der nächste Schritt wäre jetzt ein Shadow-RAM in dem der µC den "Bildschirminhalt" ablegt und dann immer wieder abspielt.
Das geht prima mit nem Array, der M32 hat ja auch ausreichend RAM für sowas:
DIM SHADOW_RAM(3) AS BYTE
wäre dann ein Byte-Array mit 3 Einträgen.
Bitte beachten: in Bascom ist das erste Element immer 1, nicht 0 (beim EEP ists dann wieder 0, also aufpassen!)...
Zugreifen kannst du so:

FOR X = 1 TO 3
PRINT SHADOW_RAM(X)
NEXT X

8mm
13.01.2008, 17:33
ich habe doch aber 9 spalten - also 9 zustände. der eine bezieht sich ja auch auf einen andern pin.

die ebenen sind GND leitungen - wenn ich sie auf input (high-z) stelle, ist die ebene aus - wenn ich sie auf output - 0v - stelle, is sie an.
um sie wieder auszuschalten, muss ich sie auf input stellen.
und weil ich ja immer nur 1 led pro durchlauf anhaben will, muss ich sie ja auch wieder aus machen!

for_ro
13.01.2008, 17:38
Was kann ich jetzt noch machen?

Ich würde es so machen:



$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 1600000
$baud = 9600

Config Porta = Input
Config Portb = Output
Config Portc = Output

Dim Col As Byte
Dim Row As Byte
Dim Time as Byte

Porta=0
Portb=0
Portc=0
Time=1
Do
For Row = 0 To 2
DDRA.Row = 1
For Col = 0 To 7
Portc.Col = 1
Waitms Time
Portc.Col = 0
Next Col
Portb.7 = 1
Waitms Time
Portb.7 = 0
DDRA.Row=0
Next Row
Loop

Annahme ist, dass immer nur eine LED an sein soll, nicht mehrere gleichzeitig.
Die LEDs sind praktisch zwischen den PINs angeschlossen, d.h. 5V an Portc (und Portb.7), dann die LED, dann ein Vorwiderstand, dann in Porta.
An jedem Pin von Portc sind 3 LEDs angeschlossen, an jedem Vorwiderstand 9.

Gruß

Rolf

8mm
18.01.2008, 17:26
Ich brauch nochmal eure Hilfe, weil ich bekomms einfach nicht gebacken...:

Mein Code lässt ja jetzt jede LED einmal kurz aufleuchten und das ganze geschieht so schnell, dass das träge Auge es als ein Aufleuchten aller LEDs wahrnimmt.

Wie muss ich meinen Code nun erweitern, dass ein paar Animationen für meine 3x3x3 Matrix schreieben kann?

Ich habe zwar schon ein paar gemacht:
http://youtube.com/watch?v=zqiS05Tdc5A

jedoch werden da noch alle LEDs einzeln angesprochen und bei vielen Animationen wäre das schon ein Haufen Programmcode.
Und ich glaube kaum, dass bei den LED Matritzen, die man noch so auf YouTube findet, dass bei den schönen Animationen alle LEDs einzeln angeschaltet werden, um die Modi abzulaufen.

Könnt ihr mir da vllt helfen?

stefan_Z
18.01.2008, 20:06
Wie gesagt: Den Zustand aller LEDs mit einer 32-Bit Variable festhalten und dann viele dieser Variablen nutzen.
Oder eine weitere Ebene der Abstraktion schaffen und das Shadow-RAM direkt manipulieren. Das wäre z.B. wie wenn man in Bascom auf nem Grafikdisplay nen Kreis per Mittelpunkt und Radius zeichnet. Das eigentliche Zeichnen macht der AVR mit ner Routine für dich.

8mm
18.01.2008, 20:52
wie sieht eine 32 bit variable aus, und wie sähe dann eine animation z.b. alle leds nacheinacner sichbar anschalten, so dass man dann erst ein standbild hat?

stefan_Z
19.01.2008, 00:04
na ne 32Bit Variable is z.B. ne LONG.
Die hat anstelle von 8 Bit (Byte) einfach 32 Bit (also 4x Word).
Somit kann sie den gesamten Inhalt des Würfels festhalten.

Das Programm wäre so aufgebaut:
eine Timer-Interrupt-Routine geht alle paar Millisekunden hin und liest den Inhalt der nächsten Spalte ein und stellt ihn in dieser da, dann macht er das mit der übernächsten usw...
Wenn alle Spalten geschrieben sind macht er den Gesamtvorgang nochmal so 100x oder so, je nachdem wie lange das Bild stehen soll.
Dann wird einen neue Variable mit neuen Spalteninhalten geladen, wieder 100x angezeigt und so weiter und sofort.
eine LONG Variable ist laut Handbuch:
Long (four bytes). Longs are stored as signed 32-bit binary numbers ranging in value from -2147483648 to 2147483647.
Aber dich interessiert die binäre Abbildung, also das Bitmuster.

8mm
19.01.2008, 07:07
gut - nur hab ich noch keine ahnung von timer und von interrupt ^^
und wenn ich den inhalt der nähcsten spalte in dieser da stelle, is das bild doch verschoben oder?
und würde ein bild dann so ausehen:

bild = 001011001001101001001101001

wenn ja, wie sage ich dann dem Code, dass er daraus immer durchschaltet? dann müsste ich die code ja auseinander fuseln?!

8mm
20.01.2008, 22:24
kannst du vllt mal ein beispiel code schnipsel schreiben?
wär echt super

8mm
23.01.2008, 10:34
nicht?
ich verstehe nicht, wie das gehen soll?!

8mm
24.01.2008, 15:31
habs hinbekommen!


$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 1600000
$baud = 9600

Config Portc = Output
Config Portb = Output

Dim Col As Byte
Dim Row As Byte
Dim Count As Byte
Dim Bild As Long
Bild = &B00000100100100010010010001001001
Count = 0
Do

For Col = 0 To 8

Config Porta = Input
Portc = 0
Portb = 0
Portc.col = 1
If Col = 8 Then
Portb.7 = 1
End If
For Row = 0 To 2
Config Porta = Input
Ddra.row = Bild.count
waitms 7
Incr Count
Next

Next
Count = 0
Loop

jetzt muss ich das nur noch als funktion definieren - also den mutliplexing teil.

mach ich das mit:
decalare function multiplexing() as long

fuction multiplexing()
'code
end function

und dann mit function() aufrufen?

finde hier nix brauchbares!

8mm
25.01.2008, 13:37
in php definiere ich so eine funktion:

function foo($ba)
{
/* code */
}

foo(); /* zum aufrufen */

und wie ist das in bascom?

declare function foo(ba as byte) as long

foo(ba as byte) as long
'code
end function

foo(ba) 'zum aufrufen

oder wie geht das genau?
was ich so ergoogelt habe war immer recht umfangreich.

will die funktion dann einfach nur mit bild as long aufrufen!

stefan_Z
25.01.2008, 14:10
http://avrhelp.mcselec.com/bascom-avr.html
da mal DECLARE FUNCTION ansehen!

8mm
29.01.2008, 16:42
hier mein fertiges programm:

http://youtube.com/watch?v=_6jXX-91vs0