guten tag liebe gemeinde!
ich bin grad am programmieren einer led-matrix, welche spätestens bis
weihnachten fertig sein muss, da es eben ein weignachtsgeschenk sein
wird. (:
leider, wieso auch nicht, gibt es einige probleme, die eigentlich gelöst
werden können, glaube ich zumindest:
ich arbeite mit dem gosub-befehl. also angeben, was aufgerufen werden
soll und darunter für die variablen, welche aufgerufen werden, die
spezifische tätigkeit zuschreiben.
das habe ich nun hier gemacht:
das problem ist nun, dass das programm nur läuft, wenn portd und portc
alleine arbeiten.
sobald sie, wie in dem oben stehendem code, mit bspw. porta oder portb
arbeiten müssen, geht nichts mehr.
also kein pegel am ausgang. weder low noch high.
nehme ich jetzt die routine "gosub a", "gosub a0" sowie ddra und porta
weg, geht alles wie nach plan.
kann das jemand erklären?
portc und portd spinnen eh etwas auffällig rum. sie blinken in anderen
programmen herum, auch wenn sie nur auf high und als ausgang konfiguiert
werden.
ich weiß nicht, ob das an dem atmega16 liegt - ich bräuchte eh den
atmega2560, da die 16kb nur ein zehntel vom flash sind, den ich da
schreiben muss.
für ratschläge wäre ich herzlichst dankbar!
Deine Gosubs sind ziemlich kontraproduktiv, da sie nur einen Befehl
enthalten. Den Befehl könntest du genauso gut direkt speichern. Das
würde Speicherplatz und viel Rechenzeit sparen.
Auch dein "Beginn: ... Goto Beginn" ist überflüssig, da du ja schon eine
Do-Loop-Schleife geschrieben hast.
Probier das mal so wie ich des dir erklärt habe und dann sehen wir
weiter.
@ samuel C.
danke erstmal für die antwort.
das mit dem speichern hatte ich schon vor, nur weiß ich eben nicht, wie
man einen befehl durch eine variable ersetzt.
könntest du mir das bitte erklären? danke!
@me
alle fuses, darunter auch jtagen, außer spien, sind ausgeschaltet.
Wozu einen Befehl durch eine Variable ersetzen? Schreibe einfach den
Befehl, den du in der Subroutine stehen hast direkt dahin wo jetzt dein
GOSUB steht.
Sven Schmidt schrieb:> W:> Waitms 50
Wenn da nichts beim copy/pasten aus Versehen weggeschnibbelt wurde, dann
fehlt dort ein Return.
Was soll das ?
Sven Schmidt schrieb:> Do> Beginn:> Goto Beginn> Loop
Schau Dir doch mal ein paar Beispiele aus dem Samples Ordner im Bascom
Verzeichnis an. Versteh' nicht, warum jeder Anfänger glaubt, er müsse
die gezielt ignorieren. Da gibt's sogar eine Gosub.bas. Mit sogar
richtig definierten Stacks.
Außerdem, nimm selbsterklärende Labelnamen, ist ja grausam so.
hast du Angst dir klaut jemand dein Programm? Poste doch mal den ganzen
Quelltext als Anhang.
Mit Bascom kenne ich mich nicht aus.
Aber ich kenne das so das man aus einem Subroutine, die mit Gosub
aufgerufen wird wieder mit Return(vielleicht heißt der Befehl auch
anders meine C64 Zeit ist schon lange her) beenden muss sonst läuft dir
irgendwann der Stack über. Hast du das überall gemacht oder hast du in
einer Subroutine wieder ein goto drin und beendest die Subroutine nicht
richtig.
also soll ich in einer zeile nur einmal gosub schreiben und dahinter
alle befehle, die ich brauche? wenn das so ist, werde ich das so
umschreiben.
ich habe bereits einen teil geschrieben. da es aber so lang ist, dachte
ich, dass der code hier den rahmen sprengen würde.
aber ich machs mal. ich denke, dass jeder scrollen kann. (:
ohne probleme compiliert. würde ich diese programm nun auf meinen atmega
schreiben, hätten alle d- und c-ports herumgespinnt und geblinkt. sie
blockieren sogar die a- und b-ports, wenn sie mit DDRx und PORTx auf
high und ausgang gesetzt wurden.
zu bedenken: das programm ist aus platzgründen nicht vollständig. die
hat keinerlei auswirkungen auf die funktionsweise zuvor. selbe fehler
treten auf.
ich weiß nicht, ob fusebits das problem sind, aber wenn gosub mit portd
und c nicht klarkommt, stimmt etwas nicht.
hier der beispielcode von bascom für gosub:
was soll ich jetzt dem code entnehmen?
routine ist bei meinem bascom kein befehl und damit unbekannt. ich
verstehe das nicht. unser informatiklehrer hat uns gosub in freebasic
beigebracht. ich hab dass dann einfach in bascom ausprobiert und es hat
tatsächlich geklappt. allerdings nur mit porta und portb.
Bei dem Code geb' ich auf. Wieviel Speicherplatz hat dich der gekostet?
Das kann man sicher mit einem Zehntel an Zeilen lösen. Was willst du
denn mit dem Code bezwecken?
hier die fusebits
ich möchte mit dem code jede einzelne zelle einzeln ansteuern. keine
lust, mich mit der bitschubserei zu schlagen. ich bekomms nochnichtmal
auf die reihe, einen hc595 zum laufen zu bekommen...
Naja, das ist so eine Sache mit der Bitschubserei. Ich kenne das Prinzip
deines Codes zwar noch immer nicht, aber ich würde mal sagen, mit ASM
kombiniert wäre das in 10 Zeilen erledigt.
Der Code ist fuchtbar. Einfach nur furchtbar.
Tipp: Such dir ein Tutorial und lern die Grundlagen. Dein Code sieht so
aus, als ob Arrays bzw. Variablen nie erfunden worden wäre (wenn ich das
was du da geschrieben hast richtig deute).
Auch macht man muliplexing nicht so.
Für Multiplexing brauchst du einen Timer und eine zugehörige ISR. So hat
das doch alles keinen Sinn.
> Das kann man sicher mit einem Zehntel an Zeilen lösen.
Einem Zehntel?
Einem Hunderstel!
okay leute, ich gebe mich geschlagen. habs nun auch eingesehen, dass ich
mich erstmal ein wenig einlesen und probieren muss.
aber eine frage:
wie zum teufel soll man einen text bestehend aus etwa 2000 daten mit
einem code, der ein paar zeilen enthält, programmieren können?
gerade verstehe ich das garnicht. aber ich denke, dass es einfach nur
mal etwas zeit braucht. ich bin 15 jahre alt, habe bisher nur ganz
primitive dinge programmiert und dementsprechend wenig erfahrung und
wissen.
hier sind auf alle fälle leute, die studiert, bereits 30 jahre mit dem
hobby zu tun und einfach mehr drauf haben.
ich lese mich dann erstmal in die 3 geposteten links ein.
das sind doch unter anderem befehle, die wie schieberegister fungieren,
oder?
danke nochmals für die hilfe. die antikomplimente für den
"fürchterlichen" code mussten wirklich sein! (:
Sven Schmidt schrieb:> wie zum teufel soll man einen text bestehend aus etwa 2000 daten mit> einem code, der ein paar zeilen enthält, programmieren können?>> gerade verstehe ich das garnicht.
Mit Tabellen.
Es ist immer der gleiche Ausgabecode. Ein Ausgabecode der universell
einsetzbar ist. Und der wird dann mit Daten aus einer Tabelle gefüttert.
Wenn du die Zahlen 1 bis 100 ausgeben willst, dann scheibst du ja auch
nicht
lcd 1
lcd 2
lcd 3
....
sondern packst das zb in eine Schleife
for i = 1 to 100
lcd i
next i
3 Zeilen ersetzen deine 100 von oben
> hier sind auf alle fälle leute, die studiert, bereits 30 jahre mit dem> hobby zu tun und einfach mehr drauf haben.
darum gehst nicht.
Es ist der Grundgedanke: Ich brauch kein Tutorial. Ich kann das auch
alleine. Ich komm da schon von selber drauf.
Und da taucht jetzt das Problem auf, dass man dich da auch nicht
durchreden kann. Denn da fehlt dir einfach wahnsinnig viel an
Vorabwissen, so dass man hier im Forum ein halbes Buch schreiben müsste,
bis man dich auf einen Level gebracht hat, an dem es Sinn macht über
Multiplexing zu sprechen.
Da liegt der Hund begraben.
Und in der Unterschätzung des Schwierigkeitsgrades.
Sven Schmidt schrieb:> danke nochmals für die hilfe. die antikomplimente für den> "fürchterlichen" code mussten wirklich sein! (:
Doch. Die fördern das Verständnis, daß das so garantiert nicht klappen
wird.
Es gibt in Bascom Dinge wie Data, Read, Lookup, die nur darauf warten
für so etwas verwendet zu werden :D
Es gibt da aber regelmäßig noch ein weiteres Problem, nämlich die
Resistenz etwas zu verstehen.
Das sieht man einmal darin, daß in diesem wüsten Code immer noch die
Stackdeklarationen fehlen, obwohl sie im unmittelbar darunter geposteten
Beispiel vorhanden sind, und auch der Hinweis darauf kam. Ausreichend
groß definierte Stacks können in Bascom über Funktionieren oder
Nichtfunktionieren entscheiden.
Zweitens steht beim Erstellen einer Nachricht;
> Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
Auch das ist Dir egal, dieser codegewordene Albtraum wird trotzdem
direkt eingefügt. Und solche Resistenzen, also die Langsamkeit etwas zu
verstehen, sind das was beim Programmieren behindert.
MWS schrieb:> Doch. Die fördern das Verständnis, daß das so garantiert nicht klappen> wird.
Hey, er hat's doch eingesehen. Mal sehen was er daraus macht.
Hallo!
MWS schrieb:
> ... also die Langsamkeit etwas zu
verstehen, sind das was beim Programmieren behindert.
Stimmt ... fast! Kann ick ein Lied von singen. War knapp 60, die Birne
schon angekalkt, als ick mit dem Unfug anjefangen habe. Hab`mich
trotzdem durchjebissen, im Alleingang!!!
Meine Programme und Projekte lofen. Nich "Langsamkeit" ist det Problem,
Schlauberger,
sondern Beharrlichkeit ist jefragt und een unbändiger Willen det
hinzukriejen.
Gruß, unikum!
unikum schrieb:> Hallo!> MWS schrieb:>> ... also die Langsamkeit etwas zu> verstehen, sind das was beim Programmieren behindert.>> Meine Programme und Projekte lofen. Nich "Langsamkeit" ist det Problem,> Schlauberger,> sondern Beharrlichkeit ist jefragt und een unbändiger Willen det> hinzukriejen.>> Gruß,
Ah, ein Fremdsprachler :D
Nicht aus dem Kontext reißen, ich sprach von Langsamkeit zu verstehen,
d.h. die Geschwindigkeit seine Fehler zu erkennen und zu korrigieren.
Beharrlichkeit gehört sowieso dazu, ohne bist Du bei MCs verkehrt.
Hallo MWS,
da hat ja mein kleiner Trick wieder geklappt:
> Ah, ein Fremdsprachler :D
Nur so kann jemand seine Überheblichkeit noch besser demonstrieren.
Wenn Du innerhalb von 2 Std. schon nicht mehr weißt, was Du geschrieben
hast,
> Nicht aus dem Kontext reißen,...
bist Du ja bald noch schlimmer dran als ich.
Statt dem 15 jährigen Jungen mal mit konkreten Beispielen zu helfen,
tust Du ihn letztlich nur verhöhnen.
Ich geb`s zu, ich kann`s nicht. Ich habe nicht den Nerv mich da
reinzuknien,
habe viel zu sehr mit meinen eigenen Programmen zu tun.
Du scheinst ja der große Experte zu sein. Dann mach mal.
Nichts für ungut.
Gruß unikum.
unikum schrieb:> Hallo MWS,> da hat ja mein kleiner Trick wieder geklappt:>>> Ah, ein Fremdsprachler :D>> Nur so kann jemand seine Überheblichkeit noch besser demonstrieren.
Wenn Du die Wahrheit als Überheblichkeit betrachtest, will ich Dir das
nicht nehmen.
> Statt dem 15 jährigen Jungen mal mit konkreten Beispielen zu helfen,> tust Du ihn letztlich nur verhöhnen.
Beim derzeitigen Niveau des gezeigten Codes kann ihm in erster Linie das
Durcharbeiten der Bascom Beispiele (im Samples Ordner) helfen, sowie
sich mal ein paar Tutorials durchzuarbeiten. An dem gezeigten Code kann
man nichts verbessern, der gehört einfach in die Tonne.
Aber Du hast recht, ich könnte ihm helfen und ich würde es auch, wenn
ich seh' er strengt sich an.
> Nichts für ungut.
Kein Problem ;-)
An MWS,
Na dann ist ja alles klar, ... Herr Oberlehrer.
Nur, wie soll er sich anstrengen, wenn er keinen besseren Ansatz findet,
wenn ihm keiner mit was Konkretes auf die Sprünge hilft.
Vielleicht hat er sich ja übernommen mit seinem Projekt, wollte für
Mutti mal "schnell" was zu Weihnachten basteln. Und nun steht er da
wie`n begossener Pudel.
Ob ihm das hilft?
Na ja, was soll`s?. Ist schon spät. Ich hau´ mich jetzt hin.
Gute Nacht MWS und alle Manns.
Gruß unikum.
unikum schrieb:> An MWS,> Na dann ist ja alles klar, ... Herr Oberlehrer.> Nur, wie soll er sich anstrengen, wenn er keinen besseren Ansatz findet,> wenn ihm keiner mit was Konkretes auf die Sprünge hilft.
Das Problem ist in diesem spezielle Fall wohl eher, dass der TO keinen
Ansatzpunkt bietet, an dem man einhaken könnte. Das ist, wie wenn du
jemandem der gerade mal unfallfrei im Zahlenraum bis 100 multiplizieren
kann, die Differentialrechnung erklären willst. Im Prinzip nicht
schwierig, nur wird er jedes 3. Wort nicht verstehen.
Sieh dir den Code an. Da ist nichts erkennbar. Keine Idee, kein
Grundgedanke, noch nicht mal eine Überlegung, wie man den Wust in den
Griff kriegen könnte. Wie ich weiter oben schon sagte: Es ist als ob es
keine Variablen gäbe. Es ist wie jemand der Multiplizert indem er
entsprechend oft addiert. Das ist so gesehen nicht weiter schlimm. 3 mal
2 kann man so ausrechnen. Aber 24567 * 98672 kann man so einfach nicht
mehr rechnen. Da müssen andere Techniken her.
In seinem Code gäbe es mit viel Phantasie schon ein paar Ansatzpunkte,
die, wenn er sie verstanden hätte auch hätte nehmen können und von denen
ausgehend man einen vernünftigen Multiplex hätte machen können. Nur aus
der Tatsache, dass er das nicht gemacht hat, schliesse ich eben, dass
hier noch das entsprechende Wissen fehlt. Dadurch hätte man sich nämlich
auch eine Menge Arbeit erspart, wenn man 1 Ausgaberoutine macht, der man
die auszugebenden Spalten (Zeilen?) übergibt, und die für dieses 1
Zeichen eine spaltenweise Abarbeitung durchführt. Dazu muss man aber
Subroutines und Parameterübergabe kennen und einsetzen können. Also
eigentlich etwas sehr elementares. Auch in Bascom.
Um es klar zu sagen: Sven ist daran so erst mal nicht schuld. Wir alle
mussten das irgendwann mal lernen. Nur ist es aber auch so, dass der
Thread an den ich mich erinnere so ca 1 bis 2 Wochen her ist. Und auch
damals schon waren die Lücken mehr als erkennbar.
> Vielleicht hat er sich ja übernommen mit seinem Projekt, wollte für> Mutti mal "schnell" was zu Weihnachten basteln. Und nun steht er da> wie`n begossener Pudel.
Das ist schon klar.
Ich kann mich auch an den Namen erinnern. Nur find ich den Thread nicht
mehr. Ich erinnere mich aber daran, dass auch dort schon das Stichwort
Timer gefallen ist. Er ist das Eintrittstor in Multiplexing.
Also Sven, für ein Weihnachtsgeschenk machen wir fast alles :-)
Nur hab ich deine Schaltung nicht mehr im Kopf. Und auf deinen Code
möchte ich mich lieber nicht verlassen um die Schaltungsdetails da
rauszulesen.
Poste die Schaltung nochmal und die Aufgabenstellung was eigentlich
passieren soll.
unikum schrieb:> An MWS,> Na dann ist ja alles klar, ... Herr Oberlehrer.
Danke dafür...
> Nur, wie soll er sich anstrengen, wenn er keinen besseren Ansatz findet,> wenn ihm keiner mit was Konkretes auf die Sprünge hilft.
Wurde ihm doch schon Unterstützung angeboten.
> Vielleicht hat er sich ja übernommen mit seinem Projekt, wollte für> Mutti mal "schnell" was zu Weihnachten basteln. Und nun steht er da> wie`n begossener Pudel.
Ja klar, sicher hat er das. Ging jedem mal so. In so einer Situation
muss man dann entweder recht fix oder kreativ sein. Wenn man weder das
eine noch das andere ist, scheitert man, und das dann nicht unverdient.
> Ob ihm das hilft?
Böse Wahrheit. Aber er könnte sich hier selber helfen, indem er halt
sein Vorhaben darstellt, 'nen Schaltplan postet, usw., die Klassiker
eben. Muss selbst dann nicht hinhauen, wenn's extrem über seinen
Fähigkeiten liegt und ihm nicht jemand den Code schreibt.
Zumindest würde das aber seine Chancen ungemein erhöhen.
> Na ja, was soll`s?. Ist schon spät. Ich hau´ mich jetzt hin.> Gute Nacht MWS und alle Manns.>
Gleichfalls.
> Gruß unikum.
Sven Schmidt schrieb:> ich bin grad am programmieren einer led-matrix, welche spätestens bis> weihnachten fertig sein muss, da es eben ein weignachtsgeschenk sein> wird. (:
So wie Deine Programmierfähigkeiten herausklingen, ist das utopisch.
Zu Weihnachten 2011 wäre realistisch.
Sven Schmidt schrieb:> leider, wieso auch nicht, gibt es einige probleme, die eigentlich gelöst> werden können, glaube ich zumindest:
Das Hauptproblem ist, daß du Dir keinen Programmablaufplan machst.
Du mußt erstmal die Aufgaben festlegen, z.B.:
- Ansteuerung der Matrix im Timerinterrupt.
- Ausgabe eines Zeichens auf den Matrixbildspeicher
- Ausgabe eines Textes als Laufschrift.
Du schreibst, das Du 160kB brauchst. Keiner möchte aber einen Text von
160000 Buchstaben so lesen müssen.
Sven Schmidt schrieb:> ich arbeite mit dem gosub-befehl.
Ein Unterprogrammaufruf dient der Modularisierung. Das sehe ich aber bei
Dir nicht.
Peter
MWS schrieb:> Sven Schmidt schrieb:>> danke nochmals für die hilfe. die antikomplimente für den>> "fürchterlichen" code mussten wirklich sein! (:>> Doch. Die fördern das Verständnis, daß das so garantiert nicht klappen> wird.
meine ich doch. (: jetzt hab ichs erst begriffen, nach vielen
gefühlsausdrücken, dass der code nicht richtig sein kann.
nein, jetzt einmal im ernst:
ich bin sehr erfreut, dass ihr euch hier alle so viel darum kümmert,
dass ich etwas lerne.
mir kam diese geschenkidee leider etwas spät. am anfang wusste ich
nichteinmal, wie so eine dot-matrix-anzeige funktioniert. das hab ich
jetzt jedoch begriffen, dank diesem thread hier, den ihr wohl nicht
finden konntet:
Beitrag "Allgemeine fragen zum ansteuern von Dot-Matrixanzeigen."
ich möchte unbedingt neue befehle und funktionen von bascom
kennenlernen. deshalb wollte ich auch unbedingt dieses geschenk
fertigbringen, da ich dachte, dabei etwas zu lernen. da aber mit gosub
anzufangen ist ziemlich naiv, das gebe ich zu.
nun zum wesentlichen: ich hab euch jetzt eine schaltung von meinem
aufbau und alle buchstaben, die im text vorkommen, im led-matrix-grafik
aufgezeichnet.
im grunde sollen alle bits der 20 spalten je zeile immer um eine stelle
nach links verschoben werden. zuvor jedoch müssen alle zeilen (1-7) mit
den entsprechenden spalten etwa 7 mal wiederholt werden, damit die
schrift zum einen nicht zu schnell läuft und zum anderen kein flimmern
auftritt.
ich habe mir überlegt, dass jede periode (zeile 1-7) je 14ms in anspruch
nimmt (quasi 7 mal 2ms. jede zeile darf nur 2ms leuchten).
da bereits links zum shiften von bits gepostet wurden, weiß ich jetzt
zumindest, dass man dieses ganze auch nicht nur mit gosub lösen kann.
der text ist:
"L_I_E_B_E L_E_N_A" warten, bis "L_E_N_A" verschwunden ist "F_R_O_H_E
W_E_I_H_N_A_C_H_T_E_N U_N_D E_I_N_E_N G_U_T_E_N R_U_T_S_C_H
I_N_S N_E_U_E J_A_H_R_!
ein unterstrich ist jeweils immer eine leere spalte, also ein
abstandshalter. zwischen den wörtern sind immer 4 spalten frei.
das hauptproblem bei mir war: ich hatte die idee, den wunsch, dass das
programm das und das macht. nun aber? wie soll das gehen, wenn ich keine
befehle kenne? das steht in verbindung wie zutaten und rezept. ohne
rezept keine zutaten, ohne zutaten kein rezept.
am einfachsten lernen könnte ich es, wenn ihr mir ein kurzes programm
vorgibt, bei dem sagen wir mal nur eine vollständig leuchtende spalte
durchgeschoben wird. es reicht, dass es um 2-3 spalten nach links
verschoben wird. und wenn dann noch ganz kurz beschrieben werden könnte,
welcher befehl was genau tut und was sein muss, damit das und das
passiert, würde vollkommen ausreichen. dann werde ich es ganz sicher
begreifen und verstehen.
genauso habe ich es auch im buch von rowalt gelernt. ich habe nur den
code mit den grünen texten angucken müssen und schon wusste ich, worums
geht. danach habe ich erst den text gelesen. ich kann unglaublich
schnell lernen, wenn ich es auch wirklich möchte! und ich will es
lernen, denn das ist mein hobby, nicht so ein "einmalprojekt", bei dem
ihr hier die arbeit leisten müsst.
es bringt mir nichts, wenn ihr mir jetzt den ganzen code hier vor die
nase hält. aber wenn ich einen ansatz mit erklärung erhalte, werde ich
das zuende bringen.
danke!
Sven Schmidt schrieb:> am einfachsten lernen könnte ich es, wenn ihr mir ein kurzes programm> vorgibt, bei dem sagen wir mal nur eine vollständig leuchtende spalte> durchgeschoben wird. es reicht, dass es um 2-3 spalten nach links> verschoben wird.
Das "vorgeben" bedeutet, jemand muss es für Dich programmieren.
Die mir bekannten Foren funktionieren dagegen eher so, daß der
Hilfesuchende eine einigermaßen klare Idee hat, damit beginnt, und dann
wenn's hakt kommen die entsprechenden Ratschläge: Beispielcode wird
vielleicht auch mal geschrieben, wenn's ein kurzer ist.
Dein Projekt sieht mir nicht danach aus, einem Anfänger würde man ganz
sicher NICHT zu so einem Projekt raten.
Sven Schmidt schrieb:> ich möchte unbedingt neue befehle und funktionen von bascom> kennenlernen. deshalb wollte ich auch unbedingt dieses geschenk> fertigbringen
So ein Projekt erfordert es diese Befehle bereits zu kennen, die erst
dafür zu lernen zu müssen, ist für so etwas Kurzfristiges eher schlecht.
Ohne Dich entmutigen zu wollen denke ich daß die Meisten, die das jetzt
auch programmieren könnten, Deine Erfolgsaussichten beim gezeigten
Kenntnisstand als eher schlecht einschätzen.
Ich möchte Dir aber prinzipiell den Aufbau darstellen, dann schau'n wir
mal, was Du draus machst.
Für eine gemultiplexte Anzeige benötigst Du eine Routine die das immer
im Hintergrund für Dich macht. Die darf sich nicht stören lassen,
sondern muss immer schön regelmäßig die Leds ansteuern. Zeilen
multiplexen würde sich hier anbieten.
Diese Routine ist eine Timer Interruptroutine, was ein Timer ist, kann
man in der Bascom Hilfe nachlesen, was eine Interruptroutine ist,
ebenfalls.
Diese Routine gibt jeweils eine Zeile aus einem Bildspeicher aus, dieser
Bildspeicher ist ein Abbild der Led-Matrix im internen Speicher des µCs,
dem SRam.
Gehen wir vom Üblichen Aufbau eines Zeichens aus, dann würde für eine
Spalte ein Byte reserviert, für die komplette Matrix also ein Array von
20 Bytes.
7 der 8 Bits pro Byte entsprechen einer Spalte, also einer Led.
Diese 20 Bytes sind Dein Bildspeicher, aus der die Interruptroutine
laufend die Leds heraus ansteuert. Würde nun spaltenweise gemultiplext,
dann würden einfach die Bytes nacheinander ausgegeben, und gut ist's.
Jedoch würde 20 mal ausgeben länger dauern als 7 mal ausgeben. Um
gleiche Helligkeit und Flimmerfreiheit zu erhalten, müsste man
Widerholrate, als auch Diodenstrom erhöhen.
Für die vorteilhaftere zeilenweise Ausgabe müssen nun die Bits im
Bildspeicherarray auf die Ports der Spalten abgebildet werden.
Eine Zeile besteht z.B. aus allen Bits 0 der Spaltenbytes 1 - 19, das
muss dann bei der Ausgabe entsprechend umgerechnet werden.
Selbstverständlich kannst Du auch am einfacheren Weg, d.i. Multiplexen
der Spalten gehen.
Das mit dem Bildspeicher diente Deinem Verständnis, der kann natürlich
nur statisch etwas anzeigen und zwar genau so viel, wie Leds da sind.
Nun gäb's den Weg diesen Speicher mit einem Zeichengenerator zu
beschreiben, jeder Buchstabe ist in so 'nem Zeichengenerator als Folge
von Bytes abgelegt, für Deine Zeichen sagen wir mal ein Byte für jede
Spalte und 6 Bytes breit.
Das würde aber zu komplex werden, deshalb würde ich Dir folgendes raten:
Leg' Deine zwei Texte als Spaltenbytes im Flash-Speicher des µC ab, der
lange Text hat 104 Zeichen zu je 6 Spaltenbytes = 624 Bytes + der kurze
Text, der ATM16 hat 16k Flash, mehr als ausreichend dafür inkl.
Programm.
Stell Dir nun vor, Du legst das Ausgabefenster für Deine 20 Led Bytes
über diese 624 Bytes, erst einmal beginnst Du mit 1, also wird Spalte 1
- 20 ausgegeben, das sind die Buchstaben F_R und 2 Spalten vom
Leerzeichen.
Dann wartest Du, und erhöhst die Stelle ab der ausgegeben wird um 1,
also von 2 - 21, in der Folge wandert der Text nach links, scrollt also.
Das machst Du bis zur Spalte 624, und damit das auch rausgescrollt wird,
erkennst Du das = 624 und gibst leere Spalten aus, oder Du erweiterst
den Teil einfach um ein paar Bytes.
Genauso kannst Du vorgehen, wenn Du beim Start des Textes reinscrollen
möchtest.
Mit dem kleineren Text gehst Du genauso vor.
Befehle um solche Arrays im Flash abzulegen und zu lesen heißen Data,
Read, Lookup, die Bascom Hilfe sagt Dir Weiteres.
Nach genauerer Überlegung, zumindest bis ich an dieser Stelle meines
Textes ankam, würde ich an Deiner Stelle den Versuch mit spaltenweisem
Multiplexen machen, ich denke das ist einfacher zu machen und einfacher
verständlich, auch wenn der Effekt evtl. weniger perfekt ist.
Dabei könnte direkt aus dem Flash ausgegeben werden.
Da es wahrscheinlich wichtiger ist, daß das Ding fertig wird, würde ich
Perfektion an zweite Stelle setzen. Wenn Du das zeitlich hinbekommst,
kannst Du immer noch einen zweiten Code mit gemultiplexten Zeilen bauen.
Dann mal viel Erfolg. Wenn Du ersten Code hast, poste ihn.
ich sehe hier ein Problem in deiner Hardware angenommen in der ersten
Zeile leuchten einmal 3 LED-Punkte und einmal 15 Stück dann hast du
unterschiedliche Helligkeiten der verschiedenen Zeilen.
Ich würde hier lieber eine niedrige Konstantspannung für den ULN2004
nehmen falls der auch damit arbeitet. Außerdem muss er auch ausreichend
Belastbar sein wenn man mehr LEDs in einer Zeile arbeiten.
ich bin sprachlos. danke für diese sehr ausführliche erklärung!
> Leg' Deine zwei Texte als Spaltenbytes im Flash-Speicher des µC ab, der> lange Text hat 104 Zeichen zu je 6 Spaltenbytes = 624 Bytes + der kurze> Text, der ATM16 hat 16k Flash, mehr als ausreichend dafür inkl.> Programm.
die spaltenbytes sind also die 6 spalten eines zeichens
(buchstabe+leerzeichen)?
ich bin gerade sehr frustriert. ich verstehe zwar, worum es dir geht,
aber ich habe keine ahnung, wie ich das anstellen soll.
damit ihr wisst: ich habe sozusagen garkeine ahnung von bascom. ich
kenne jediglich die befehle gosub, if then end if, do loop end und die
standartkonfigurationen für den µC.
das wars. und ich glaube nicht, dass ich das noch bis weihnachten
fertigbringen werde. ich habe jetzt noch eine ganze menge vor mir und
weiß nicht, wie ich das erlernen soll.
ich habe es mir so vorgestellt, dass ich einfach nach der reihe jede
einzelne spalte und zeile ausgebe in der hoffnung, dass das klappt. ist
wohl nicht danach.
jetzt einige fragen:
1. wie komme in den bildspeicher vom µC? ist es dieses LCD-icon in
bascom, wo man einzelne pixel markieren kann?
2. was soll mein programmtext mit der bildausgabe tun?
3. gibt man im bildspeicher nicht theoretisch jeden einzelnen
ausgabevorgang ein oder nur das zeichenmuster (also buchstabe)?
ich bin ganz verwirrt. ich weiß garnicht, womit und wie ich anfangen
soll.
wie habt ihr das denn erlernt? habt ihr tutorials oder bücher oder
internetseiten zu empfehlen?
ich möchte nicht aufgeben, aber mir ist gerade sehr danach, weil ich
einfach garkein wissen besitze.
Hallo Sven Schmidt!
Mann, Mann, Mann, det jmmert ja hier nen Hund samt de Hütte.
Ich habe Dich ja bis jetzt nur moralisch unterstützt, weil ich selber
von Deinem Weihnachtsprojekt keinen Schimmer habe. Hab`so was auch noch
nie gemacht und auch noch anderes zu tun. Ich habe aber mal in meinem
Sammelsurium rum gewühlt und hoffentlich was gefunden, daß Dir
vielleicht nützt. Mehr hätte ich zum Lernen dieser Materie selbst nicht.
Die Anderen werden Dir und mir dann schon Die Hammelbeene lang ziehen,
wenn das jetzt verkehrt ist.
In der PDF ist die Kopie aus einem Lehrbuch.
Brauch` sich jetzt och ja keener über die Qualität uffrejen!
Und nu hau mal`n Schlach ran, is gleich Weihnachten.
Gruß unikum!
danke für die pdf, unikum!
also ich lag richtig. man muss also seine zeichen in den lcd-designer
eingeben und dann etwas mit den daten anfangen, die dieser ausgibt. das
hat mich nun um einen großen schritt vorangebracht.
jetzt muss ich nur noch wissen, wie das programm fungiert, welches da in
der pdf angeboten wird.
ich muss zugeben: ich verstehe nur, dass da portd und portb auf ausgang
gesetzt werden. das wars auch.
unikum:
kannst du mir bitte sagen, wie das lehrbuch heißt? ich würde es sehr
gerne wissen, danke!
kann mir jemand im groben sagen, woraus so ein programm zum anzeigen
einer laufschrift besteht und wie es funktioniert?
ich bin mir ganz sicher, dass mir das hilft, denn von kilometerlangem
text bekomme ich nur kopfschmerzen und werde letztendlich nicht draus
schlau.
das heißt jedoch nicht, dass ich mws's text nicht verstanden habe. ich
habe ihn verstanden, mir dabei aber etwas ganz anderes vorgestellt, als
es eigentlich war. ich habe mir eine extrafunktion in bascom mit einer
tabelle zum setzen von bits vorgestellt. dabei ists nur ein tool, dass
mir die daten ausgibt, wenn ich ein zeichen hineinmarkiere.
das schlimme ist ja nicht, dass ich hier nichts verstehe von den codes,
sondern, dass ich nichts finde, das mir dies genau erläutert. ich habe
mich krankgegoogelt und nichts gefunden. und wenn, dann war es für c
oder assembler. also nicht für mich....
Hallo Sven,
> kannst du mir bitte sagen, wie das lehrbuch heißt?
Klar kann ich das:
"Programmieren der AVR RISC Mikrocontroller mit BASCOM-AVR"
2. Auflage von Claus Kühnel.
Du scheinst ja das "Walter"- Buch zu haben. Das "Kühnel"-
Buch ist eine gute Ergänzung dazu. Jedes für sich bietet meiner Meinung
nach zu wenig, bzw. ist entsprechend der Vorlieben des Autors zu
einseitig.
Eine gute Ergänzung für Dich wäre dann noch
"BASCOM-AVR Sprachbefehle" in Deutsch von Marius Meissner. - Aber
Vorsicht, dieses Buch beinhaltet wirklich nur die Übersetzung und
manchmal etwas zu knapp geratenen Erklärungen der Bascombefehle. Also
eine Deutschausgabe der Bascom-Hilfe. Ich finde es aber als
Nachschlagewerk auf dem Tisch sehr praktisch. Außerdem muß ich nicht
immer mit dem Bascom-Englisch rumochsen, das mir zu sehr mit
Werkstattjargon durchtränkt ist.
Na dann sieh mal zu.
Gruß, unikum!
Sven Schmidt schrieb:> kann mir jemand im groben sagen, woraus so ein programm zum anzeigen> einer laufschrift besteht und wie es funktioniert?
Wurde doch schon tausendmal:
- Timerinterrupt zur Ausgabe SRAM auf LED-Matrix
- Tabelle mit ASCII-Zeichensatz 5*7 zum Umwandeln der Zeichen in
Bildpunkte
- Irgendein Text, den Du ausgeben willst
- Schleife mit Delay für die Ausgabe um einen Bildpunkt versetzt, bis
Text zuende.
- fertig
Das Schöne daran ist, man kann es Schritt für Schritt programmieren.
Als versuche nicht, gleich das komplette Programm zu schreiben, Du wirst
nur scheitern.
Nen 5*7 Zeichensatz gibts in der Codesammlung schon fertig bei
GLCD-Routinen.
Peter
Sven,
Du erwähntest, daß Du schnell lernst, also schau'n wir mal :D
1
Dim Port_Zeile As Byte
2
Dim Shifts As Byte
3
Dim Spalte As Byte
4
Dim Frame_Pos as Byte
5
6
Spalte = 0
7
Shifts = 0
8
9
Do
10
Incr Shifts
11
Waitms 200
12
If Shifts > 4 Then Shifts = 0
13
Loop
14
15
'###############
16
'Timer ISR Start
17
'###############
18
' hier entsprechend der Spalte einen der Spaltentreiber einschalten
19
20
Frame_Pos = Spalte + Shifts
21
Port_Zeile = Lookup(Frame_Pos , Text1) ' Wert für den Zeilenport holen
22
' auf Zeilenports ausgeben, Bits entsprechend umstellen, da unzusammenhängend verteilt
23
Incr Spalte
24
If Spalte > 19 Then Spalte = 0
25
26
'#############
27
'Timer ISR End
28
'#############
29
30
End
31
32
Text1:
33
Data 127 , 8 , 8 , 8 , 127 , 0 ' H
34
Data 63 , 72 , 72 , 72 , 63 , 0 ' A
35
Data 127 , 2 , 4 , 2 , 127 , 0 ' W
36
Data 127 , 73 , 73 , 73 , 65 , 0 ' E
Das ist natürlich kein fertiger Code, die Spaltentreiber müssen
dekodiert werden, d.h. nur einer der Spaltenpins darf entsprechend der
Spalte eingeschaltet sein, der Zeilenport ist zerstückelt, die Bits
müssen verteilt werden, usw., auch müssen die Leds ausgetastet werden,
wenn man die Ports neu schreibt, das ist alles Arbeit die dazugehört.
Deine Arbeit :-)
Wie jemand richtig erwähnt hat, geht Zeilenmultiplexing mit obiger
Schaltung nicht, da müssten dann die Widerstände in die Spalten, statt
in die Zeilen.
Der normale (universelle Ansatz, wie auch bereits u.A. von Peter
erwähnt) wäre eine Fonttabelle, und die Bitmuster daraus würde man dann
in den Bildspeicher schreiben, den man zyklisch ausgibt.
Aber für Deinen speziellen Einsatzzweck wäre es eben auch möglich,
direkt aus dem Flash zu lesen und darin zu scrollen, so ähnlich wie wenn
man einen Rahmen über die Buchstabenbytes legen würde.
Ist nur 'ne kleine Fleißarbeit die Bitmuster hintereinander zu kopieren,
aber sollte rasch erledigt sein.
Obiger Code würde die Buchstaben HAWE auf das Display bringen und um 4
Stellen scrollen. Das Waitms in der Do/Loop würde nicht sehr exakt sein,
da es immer von der Timer ISR unterbrochen würde. Besser wäre das
Scrollen an den Timer anzubinden und auch mit der vollständigen Ausgabe
aller 20 Spalten zu synchronisieren, aber es sollte hier nicht komplexer
als nötig sein. Den Sinn wird vermittelt, denke ich.
Jetzt hast Du ein Beispiel, mach' was draus ;-)
was heißen diese zahlenwerte genau? man erkennt das muster für ein "H".
die 127 stellt eine volle spalte mit 7 bits. die 3 achten dort sind der
horizontale mittlere strich auf dem 3. bit von oben und dann kommt
wieder die 127 und noch eine 0 für eine leere spalte. okay. aber was
sagen diese zahlen genau? sind diese zahlen spezifisch? die 8 zB gibt
an, dass nur das dritte bit von oben auf high ist, die 127 wiederum,
dass alle 7 bits auf high stehen, bei einem "A" zB das zweite byte, eine
72. diese sagt, dass das erste und das dritte bit von oben eingeschaltet
werden. ist das so?
1
Do
2
IncrShifts
3
Waitms200
4
IfShifts>4ThenShifts=0
5
Loop
das heißt, dass die verschiebungen nach 4 mal wiederholen von 0 an
wieder beginnen, richtig? die 4 shifts stehen für die 4 buchstaben "h;
a; w und e"?
was tut dieses lookup? rechnet es sich die zeilenports für ein
spaltenbyte aus? ich habe jetzt also bei Text1 die 127. müsste er dann
dementsprechend alle zeilenports freigeben?
1
IncrSpalte
2
IfSpalte>19ThenSpalte=0
wenn er alle spaltenports durch hat, vom neuen anfangen?
ist es nicht so, dass er er alle spaltenbytes durchgeschoben haben muss,
also 4 buchstaben mal 6 bytes. (diese 127 ist doch ein byte, oder?)
das jetzt beenden könnte ich garnicht, da ich einfach nicht weiß, welche
befehle dafür gebraucht werden. das ist über meinem wissenstand. also
das kann man garnicht emrh mit meinem gosubcode vergleichen.
um ehrlich zu sein: ich habe es immernoch nicht hundertprozentig
verstanden, was das programm tun muss.
ich fasse zusammen:
mit dem lcd-designer werden spaltenbytes geschrieben.
für diese müssen jeweils immer zeilen eingeschaltet werden, dies
berechnet lookup.
wenn alle spalten durch sind, von vorne beginnen.
so, ich geh mal jetzt zur schule.
Sven Schmidt schrieb:> was heißen diese zahlenwerte genau? man erkennt das muster für ein "H".> die 127 stellt eine volle spalte mit 7 bits. die 3 achten dort sind der> horizontale mittlere strich auf dem 3.
Siehe Anhang. Kann man im Kopf ausrechnen, dafür braucht man keinen
Lcd-Designer.
Man rechnet eine eingeschaltete Led als "Bit ein" und addiert dann den
Wert jeweils auf. Du solltest nocch beachten, daß es in Wirklichkeit
natürlich anders rum sein kann, denn (wenn ich's nicht übersah) noch
wissen wir nicht, wo denn die Anode und wo die Kathode der Leds ist.
Wenn die Anode am Zeilentreiber hängt, dann kann das Bitmuster direkt
auf die Zeilentreiber ausgegeben werden.
Der Spaltentreiber der entsprechenden Spalte muss auf GND gezogen werden
und die entsprechenden Zeilentreiber gehen auf VCC um die entsprechende
Led leuchten zu lassen. Sind die Dioden anders rum, muss dieses Schema
invertiert werden.
Sven Schmidt schrieb:> das heißt, dass die verschiebungen nach 4 mal wiederholen von 0 an> wieder beginnen, richtig? die 4 shifts stehen für die 4 buchstaben "h;> a; w und e"?
Mein kurzes Beispiel gab nur 4 Shifts her, denn ein Buchstabe ist hier 6
Spaltenbytes breit, also 4 x 6 = 24, 20 Leds sind's, also kann ich 4 mal
schieben. In Wirklichkeit würdest Du 600+ mal schieben.
Nein, die 4 Shifts entsprechen 4 Spalten der Buchstabenreihe, die
entsprechen nicht den Buchstaben selber.
Sven Schmidt schrieb:> was tut dieses lookup? rechnet es sich die zeilenports für ein> spaltenbyte aus? ich habe jetzt also bei Text1 die 127. müsste er dann> dementsprechend alle zeilenports freigeben?
Es holt sich jeweils ein Spaltenbyte, um es auf der entsprechenden
Led-Spalte auszugeben. Lookup bezieht sich immer auf das angegebene
Label, hier Text1 und der übergebene Zahlenwert bestimmt den Index ab
diesem Label im Data-Feld, 0 ist eben 127, 1 dann 8, usw.
Indem man noch Shifts dazu addiert, erzeugt man quasi das besprochene
"Fenster" von 20 Spalten über den Spaltenbits. Und dieses Fenster
verschiebt man, dadurch scrollt der Text weich. Und "weich" bedeutet, es
wird immer um eine Spalte verschoben. Das sollte Dein Ziel sein, Du
willst sicher nicht ruckweise um ganze Buchstaben verschieben.
Sven Schmidt schrieb:> das jetzt beenden könnte ich garnicht, da ich einfach nicht weiß, welche> befehle dafür gebraucht werden. das ist über meinem wissenstand. also> das kann man garnicht emrh mit meinem gosubcode vergleichen.
Du wolltest lernen, also lern'.
Wie schon gesagt, war dieser Gosub-Ansatz völlig untauglich.
Lies Dir zum Timer durch, der ist wichtig hier.
Das was ich als Timer ISR bezeichnet hab', muss, sagen wir mal, 400 mal
pro Sekunde aufgerufen werden. Errechnet sich aus 20 Hz
Bildwiederholfrequenz mal 20 Spalten. Auch andere Werte für die
Bildwiederholfrequenz gehen, in erster Linie begrenzt durch die
Rechenleistung des µCs, je schneller ausgegeben wird, desto mehr
Leistung wird verbraucht. Je langsamer, desto mehr flimmert's.
Und tu' mir einen Gefallen, benutze Groß- & Kleinschreibung, ist ja
grausam zu lesen.
Das hier ist kein englischsprachiges Forum, in dem man klein schreiben
würde. Außerdem überleg mal, würdest Du anfangen in einem
englischsprachigen Forum Groß-/Kleinschreibung benutzen ?
Da kämst Du doch auch nicht auf so eine Idee. Im übrigens ist's nicht
cool seine Sprache nicht zu beherrschen.
Ich bin soeben genervt aus der Schule heimgekommen und habe mir Deine
letzte Antwort durchgelesen. Ich merke förmlich, dass es mir immer
leichter fällt, dieses Programm zu verstehen. Je mehr ich frage, desto
weniger Unklarheiten bleiben bestehen.
Das freut mich sehr, dass ihr, vorallem Du, MWS, und unikum, mir so
großzügig helft. Respekt, das kenne ich sonst nicht, dass in anderen
Foren soetwas getan wird.
Nun gut, komm' ich dann mal zum Sachlichen:
Ich weiß jetzt, wofür die Zahlen stehen, wie sie ausgerechnet werden,
was lookup für eine Aufgabe besitzt und was die 4 im shift-Befehl zu
suchen hat. Apropos shift: wenn ich den Text hineinscrollen möchte,
brauche ich ersteinmal soviele leere Spaltenbytes durchschieben, bis das
erste Spaltenbyte für einen Buchstaben zur ersten Spalte ankommt, nicht
wahr?
Im Bildanfang habe ich zum einen die Spalten- und zum anderen die
Zeileschiebung. Bei der Spaltenverschiebung (Skizze mir viel rot(: )
wird also immer das gesamte Spaltenbyte um eine Spalte nach links
verschoben.
Nehmen wir an, ich muss die erste Spalte von dem "L" darstellen. Erst
müssen alle 7 Zeilen durchgeschaltet werden. Dies wird dann mit einer
Schleife 10 mal wiederholt. Ist dies geschehen, wird dieses Spaltenbyte
vom "L" von Spalte O nach P verschoben. Und so geht das immer weiter...
das ist also die leichtere Variante, ja?
Ich habe jetzt schon eine grobe Vorstellung, wie das Programm laufen
könnte:
1. Variablen setzen
2. Schleifenanfang
3. erstes Spaltenbyte A des Textes aufrufen
4. alle Zeilen 10 mal durchschalten
5. Spaltenbyte A um eins nach links verschieben, Spaltenbyte B aufrufen
6. weitermachen, bis alle Spaltenbytes durch sind.
7. Wiederanfang
So habe ich das Programm nun verstanden. Ich hoffe, dass es so im
Prinzip laufen soll. Danach widme ich mich den Befehlen. Mir ist jetzt
nur wichtig, dass ich das Prinzip verstanden habe.
Und ich geb es zu: Das ist tausend mal einfacher, als alle Koordinaten
einzeln zu setzen.
>Und tu' mir einen Gefallen, benutze Groß- & Kleinschreibung, ist ja>grausam zu lesen.>Das hier ist kein englischsprachiges Forum, in dem man klein schreiben>würde. Außerdem überleg mal, würdest Du anfangen in einem>englischsprachigen Forum Groß-/Kleinschreibung benutzen ?>Da kämst Du doch auch nicht auf so eine Idee. Im übrigens ist's nicht>cool seine Sprache nicht zu beherrschen.
Okay, gut, dass du das sagst! Ich kann auch ordentlich und
rechtsschreibfehlerfrei schreiben, nur bin ich sehr faul und
oberflächlich, was das Schreiben mit dem Computer angeht. Das ist aber
nicht fair, denn wenn mir hier jemand helfen möchte, sollte ich dem
anderen auch Respekt und Anstand zukommen lassen.
Sven Schmidt schrieb:> Nehmen wir an, ich muss die erste Spalte von dem "L" darstellen. Erst> müssen alle 7 Zeilen durchgeschaltet werden. Dies wird dann mit einer> Schleife 10 mal wiederholt.
Warum 10 mal ?
Gehen wir vom Szenario aus, daß wir 20 Hz Wiederholrate haben. Also muss
Spalte 1 - 20 in 50ms ausgegeben sein, pro Spalte sind das dann 2.5ms.
Weiter gehe wir davon aus, daß die Anoden an den Zeilentreibern hängen,
die Kathoden an den Spaltentreibern. Es gibt einen <Zeilenport> und es
gibt einen <Spaltenport>, vereinfacht dargestellt.
Und wir nehmen an, daß wir erst einmal noch nicht scrollen.
Folgendes passiert alles in der Timerinterruptroutine:
Zuerst schalten den <Spaltenport> komplett auf High, damit es beim
Umschalten keine Störungen gibt. Dann holen wir das erste Spaltenbyte
aus Text1 und geben dieses Byte auf den <Zeilenport>. Jetzt schalten wir
am <Spaltenport> die erste Spalte auf Low. Damit leuchtet die erste
Spalte mit dem richtigen Bitmuster auf. Wir erhöhen jetzt noch den
Spaltenzähler und sind in der Timer ISR damit fertig.
Diese erste Spalte wird für 2.5ms aufleuchten, denn dann löst der
Timerinterrupt wieder aus und obig beschriebene Routine wird erneut
aufgerufen. Wieder wird der <Spaltenport> kurz abgeschalten, das
Spaltenbyte entsprechend dem Spaltenzähler geholt und auf den
<Spaltenport> gelegt. Dann wird am <Spaltenport> die zweite Spalte
entsprechend des vom vorherigen Aufruf erhöhten Spaltenzählers
eingeschaltet. Nun leuchtet die zweite Spalte für 2.5ms.
So geht das Spiel weiter bis Spalte 20, das wird dann 50ms gedauert
haben. Für das Auge wird es als stehendes Bild erscheinen.
Nun kann man sobald die Spalte 20 erreicht wurde, die Shiifts-Variable
weiter zählen, damit würde man eine synchronisierte Ausgabe erreichen.
Weil das zu schnell scrollen würde, erhöht man Shifts erst wenn z.B. die
5 mal die Spalte 20 erreicht wurde.
Sei auch vorsichtig, die Variable Shifts ist vom Namen her erlaubt,
Shift dagegen ist eine Funktion in Bascom, nicht verwechseln.
Aus meiner Beschreibung geht übrigens auch der Nachteil hervor, der
durch's Multiplexen der Spalten entsteht. Denn jede Spalte blitzt ja nur
für 2.5ms innerhalb von 50ms auf, damit die nun gleich hell erscheint
wie eine Led, die dauernd leuchtet, müsste sie in dieser kurzen Zeit
20mal so hell leuchten, d.h. der Strom müsste 20mal so groß sein.
Leds lassen sich zwar pulsweise mit höherem Strom betreiben, aber nur
bis zu gewissen Grenzen, also wird dieses Display nicht ganz so hell
leuchten können.
Versuch' doch mal auch die Denkweise des "Fensters" zu verinnerlichen,
dann ist's denke ich einfacher zu verstehen.
Mal Dir auf Karopapier mal "LIEBE" in den einzelnen Spalten auf, so
liegen die auch im Speicher des MC. Dann schneid' Dir aus Papier ein
Fenster genau 20 Karos breit aus. Leg' das über Dein Punktmuster und
verschiebe es nach rechts. Du bewegst Dich quasi als Betrachter mit, das
erscheint Dir als Scrollen und genau das bewirkt das Erhöhen der
Variable "Shifts" in meinem Beispielscode.
Ah, seh' gerad' in der roten Zeichnung, daß Du Ähnliches gemacht hast.
Sven Schmidt schrieb:> hier noch meine Spaltenbytes, muss man diese in einem Text anordnen oder> braucht man nur die Zeichen aufschreiben, die für das Programm relevant> sind?
Das sieht ok aus. Was dort drin steht, wird ausgegeben, einfach. Wenn
das Programm soweit läuft und die Ausgabe passt noch nicht, ist das dann
einfach durch Einfügen von weiteren Bytes zu erreichen.
Da Deine Zeichen das 8te Bit nicht verwenden, kannst Du ein "Data 128"
zum Schluss Deines Textes setzen und daran erkennen, daß der Text zu
Ende ist. Dann halt neu beginnen oder was immer Du willst.
MWS schrieb:> das> Spaltenbyte entsprechend dem Spaltenzähler geholt und auf den> <Spaltenport> gelegt.
Sollte natürlich <Zeilenport> heißen, war ein wenig zu schnell
gestrickt, denke der Sinn wird klar.
Guten Morgen!
Ich habe noch ein paar kleine Fragen:
1. Wird also jedes Spaltenbyte immer nur einzeln angezeigt?
2.
>Gehen wir vom Szenario aus, daß wir 20 Hz Wiederholrate haben. Also muss>Spalte 1 - 20 in 50ms ausgegeben sein, pro Spalte sind das dann 2.5ms.
Aber dann sieht man doch das Flimmern sehr stark, oder etwa nicht? 50 Hz
können wir mit unseren Augen noch gerade so als festes Bild wahrnehmen,
also 20mS Periodendauer.
Hier haben wir dann aber 50ms. Das ist mehr als das Doppelte.
Ich geh jetzt mal in die Schule und nehme deinen Beispielcode mit. Werde
dann in den Pausen überlegen, wie das Programm zu meistern ist.
schönen Tag noch!
Sven Schmidt schrieb:> 1. Wird also jedes Spaltenbyte immer nur einzeln angezeigt?
Genau das ist Multiplexing.
Mit einem Zeilentreiber und in der gezeigten Beschaltung kannst Du immer
nur eine Spalte gleichzeitig anzeigen.
Sven Schmidt schrieb:> Aber dann sieht man doch das Flimmern sehr stark, oder etwa nicht? 50 Hz> können wir mit unseren Augen noch gerade so als festes Bild wahrnehmen,> also 20mS Periodendauer.> Hier haben wir dann aber 50ms. Das ist mehr als das Doppelte.
Wenn ich so abschätze wie lange die ISR dauern wird, dann denke ich daß
Du bereits bei Standardclockeinstellung des ATM16 mit 1MHz oberhalb 50Hz
Wiederholrate kommst, also keine Sorge.
20Hz war ein von mir willkürlich gewählter Wert.
Wenn Du auf 8MHz internen R/C Oszillator umstellst, kommst Du weit
drüber.
Vorsicht beim Umstellen der Fuses, man kann den µC damit stilllegen.
Wenn dann kein externer Takt zur Verfügung steht ist man erst einmal
aufgeschmissen. Sollte ein STK500 zur Verfügung stehen, wär's kein
Problem, der kann ein Taktsignal liefern.
Du wirst für Deinen Code einen Timer benötigen, schau' Dir das
timer0.bas Beispiel im Samples Verzeichnis von Bascom an. Dieses
Beispiel zeigt wie man einen Timer konfiguriert und damit eine
Interruptroutine aufruft, im Beispiel die >Tim0_isr<
Wenn Du Timer0 verwendest, würdest Du mit einem Prescaler von 8 und
einem MCU Clock von 1MHz eine Aufrufrate der InterruptServiceRoutine
(ISR) von 488Hz bekommen, geteilt durch 20 Spalten entspräche das einer
Wiederholrate von 24Hz.
Den nächstkleineren Prescaler von 1 würd' ich nicht nehmen, da würde zu
wenig Zeit für die ISR bleiben.
Schneller geht's noch, wenn man:
- Den MCU Clock hochsetzt
- Den Timer "vorlädt", d.h. beim Aufruf der ISR auf einen Wert > 0 setzt
- den CTC Mode des Timers nutzt
>Genau das ist Multiplexing.
Okay, dann habe ich das schonmal abgehakt.
Ich habe mich heute intensiv mit deinem code beschäftigt und gleich
wieder einige Fragen dazu:
1. Die Spaltenbytes sind doch quasi nichts anderes, als die daten für
die Zeilentreiber, oder?
2. Was tut der Befehl >Incr< in dieser Schleife?
1
Do
2
IncrShifts
3
Waitms200
4
IfShifts>4ThenShifts=0
5
Loop
3. Wie kann ich die Bits der Zeilentreiber für ein Spaltenbyte ausgeben?
Ich gebe z.B. den PORTB als Freigabeport für die Zeilen an. Dort soll er
mir also alle Bits auf high setzen, die für dieses Spaltenbyte benötigt
werden.
Ich denke, dass diese Informationen für die benötigte Zeile in den
Zahlen hinter dem >Data< bei den Spaltenbytes stehen?
Solange les' ich mir mal etwas über die Setzung von Variablen als Bytes
durch.
Alles eine Sache von Befehlen und Verstand.
Ich habe bereits mein Brett mit dem M16, den Treibern und den
Dot-Matrixanzeigen fertig zusammengelötet, weil ich nun weiß, dass ich
das Programm in ca. 2 Wochen fertig haben muss und es auch tun WERDE!
Meint ihr, dass ich es schaffen können werde und ihr mich trotz der
vielen Fragen dennoch unterstützt?
Sven Schmidt schrieb:> 1. Die Spaltenbytes sind doch quasi nichts anderes, als die daten für> die Zeilentreiber, oder?
Genau.
Sven Schmidt schrieb:> 2. Was tut der Befehl >Incr< in dieser Schleife?
Der Befehl Incr ist in der Bascom-Hilfe zu finden. Er erhöht die
nachfolgende Variable.
Sven Schmidt schrieb:> Ich gebe z.B. den PORTB als Freigabeport für die Zeilen an.
Du holst Dir ein Byte Daten mit Lookup und schreibst:
PortB = ein_Byte_Daten_aus_Lookup
Jeder Portpin wird auf High gesetzt bei dem das Bit im übergebenen Byte
auf 1 war. Beispiel, übergebenes Byte = 15, Wert in Binär: 00001111,
PortB = LLLLHHHH.
Sven Schmidt schrieb:> Meint ihr, dass ich es schaffen können werde und ihr mich trotz der> vielen Fragen dennoch unterstützt?
Da ich keine gespaltene Persönlichkeit bin, kann ich nur für mich
antworten, soweit mich's betrifft, helf' ich Dir ja bereits. Ob Du's
schaffst ? Keine Ahnung, kommt darauf an, wie schnell Du lernst und
welche Energie Du dafür aufwendest.
Es wäre vorteilhaft, wenn Du die Ports wie folgt verwendest:
1
Zeilenport Alias PortB
2
Spaltenport_0_7 Alias PortA
3
Spaltenport_8_15 Alias PortC
4
Spaltenport_16_19 Alias PortD
Portpin 0 des Zeilenports muss unten sein, die Spalte 0 muss links sein.
Denn dann passt's im Notfall zu meinem fertigen Code, den ich heut' in
'ner freien Minute zusammengebastelt habe :D
Damit Du eine Vorstellung hast, welchen Umfang das in etwa haben kann:
Der Hauptcode ist 26 Zeilen lang. Inklusive aller Deklarationen,
exklusive der Data Zeilen sind's 77 Zeilen.
Als Bildwiederholfrequenz bei 1MHz sind knapp 200Hz möglich.
Da die Lena aber nicht meine Freundin ist, wirst Du Dir die Arbeit schon
selbst machen dürfen. Außerdem wolltest Du ja etwas lernen ;-)
So, da bin ich wieder.
In der Schule habe ich mir etwas über Interrupts durchgelesen und alles
soweit verstanden. Ich erkläre mal mit eigenen Worten:
Do-Loop-Schleife läuft mit einem Timer. Bei einem bestimmten Timer-Wert
wird ein Interrupt ausgelöst:
Spalte_Position = Spalte_Position + 1
Es wird ein Spaltenbyte aus dem Label >Text1< gezogen, die Zeilenpins
per Lookup ausgerechnet und ein bestimmter Spaltenpin mithilfe der
Variablen >Spalte_Position< auf high gesetzt.
warte x ms
Alle Bytes auf low stellen
Return
Ist natürlich nicht vollständig, da fehlt ja noch die verschiebung
außerhalb des Displays. Ich möchte aber ersteinmal wissen, ob ich nun
das Programmprinzip so verstanden habe.
>Sven Schmidt schrieb:>> Ich gebe z.B. den PORTB als Freigabeport für die Zeilen an.>Du holst Dir ein Byte Daten mit Lookup und schreibst:>PortB = ein_Byte_Daten_aus_Lookup>Jeder Portpin wird auf High gesetzt bei dem das Bit im übergebenen Byte>auf 1 war. Beispiel, übergebenes Byte = 15, Wert in Binär: 00001111,>PortB = LLLLHHHH.
Habe ich dann also sofort auf den PortB die ersten 4 Bits auf high und
den Rest low? Was muss denn statt dem "ein_Byte_Daten_aus_Lookup"
eingeben?
Etwa die Variable Port_Zeile? Dann noch >Port_Zeile alias PortB< und gut
is'?
1
Port_Zeile=Lookup(Frame_Pos,Text1)
Wenn nämlich Port_Zeile das selbe wie Lookup... ist, dann kann ich diese
Variable, welche mir sagt, dass dieses und dieses Bit von dem Byte auf
high bzw low sind, dem PORTB zuordnen?
Nochmal eine Frage zu den Spaltenbytes:
Hinter dem Data sind ja alle Spaltenbytes aufgelistet. Wenn also mein
Programm immerweider meine Interruptroutine aufruft, muss er doch
wissen, dass er nicht wieder das erste byte, sondern das zweite nehmen
soll. Da muss also wieder irgendwo mit einer >+1< die Spalte ausgewählt
werden. Weiß das Programm von selbst, dass es immer nach der Reihe zu
gehen hat oder muss man ihm sagen, dass er immer das nächste Spaltenbyte
aufrufen soll? Das tut ja dieses Lookup.
Ich habe vorgestern das Buch "AVR RISC Mikrocontroller mit BASCOM-AVR"
bestellt. Leider ist es immernoch nicht da. Ich hoffe, dass euch das
Buch mit meinen Fragen entlassten wird.
Ahja: Ich habe den Zeilen bereits den PortC verpasst und angelötet.
Auf PortB geht das nicht, denn er kann ja bekanntlich nur 6 Pins
ausgeben.
Für die Spalten werde ich PortA, PortD und von PortB die Bits 0-3
verwenden. Geht das so klar?
Ich bin dann mal Zeitungen austragen...
Sven Schmidt schrieb:> Do-Loop-Schleife läuft mit einem Timer. Bei einem bestimmten Timer-Wert> wird ein Interrupt ausgelöst:
Nicht ganz. Die Do/Loop hat man in jedem Programm drin, damit der MC
kontrolliert läuft, z.B.:
1
Do
2
' mach was 1
3
' mach was 2
4
' mach was 3
5
Loop
Ein Interrupt kann nun diesen "normalen" Programmablauf unterbrechen.
Der Timerinterrupt hat verschiedene Möglichkeiten zu unterbrechen, aber
wir nehmen hier den Overflow Interrupt. Der OVF löst aus wenn Timer0,
der 8Bit breit ist, also nur von 0-255 gehen kann, auf 255 war und beim
darauf folgenden Takt auf 0 überläuft.
Dann wird gerade da in der Do/Loop unterbrochen, wo sich der MC gerade
befindet, z.B. bei "mach was 2".
Der MC merkt sich, daß er von "mach was 2" rausspringt, damit er später
dort exakt weitermachen kann. Dann wird die betreffende Timer OVF ISR
angesprungen, der Code darin ausgeführt und wenn er fertig ist, macht er
wieder genau bei "mach was 2" in der Do/Loop weiter.
Auch mein Code benötigt eine Do/Loop, nur ist sie vollständig leer, da
ich das Scrollen mit dem Multiplexen in der ISR selbst synchronisiere,
das gibt einen störungsfreien Bildaufbau.
Sven Schmidt schrieb:> Etwa die Variable Port_Zeile? Dann noch >Port_Zeile alias PortB< und gut> is'? Port_Zeile = Lookup(Frame_Pos , Text1)
Ja. Das würde klappen, jedoch speichere ich dennoch in eine Variable
zwischen. Das hat als Grund, daß ich dann den neuen Zeilenwert bereits
in der Variable habe. Diese zu verwenden geht sehr schnell.
Im Gegensatz braucht der Lookup Befehl deutlich länger.
Da ich aber nun die Spaltentreiber austaste (alle auf 0 setze), dem
Zeilentreiber die neue Zeilenvariable zuweise, und jetzt erst wieder den
neuen Spaltentreiber einschalte, möchte ich die Zeit, in der die Spalten
ausgeschaltet sind, so kurz wie möglich halten. Deswegen vermeide ich
zwischen Aus- und wieder Einschalten den langsameren Lookup, und führe
den vorher aus, wo er nicht stört.
Man vermeidet sog. "Geisterbilder" mit diesem "Austasten".
Sven Schmidt schrieb:> Wenn nämlich Port_Zeile das selbe wie Lookup... ist, dann kann ich diese> Variable, welche mir sagt, dass dieses und dieses Bit von dem Byte auf> high bzw low sind, dem PORTB zuordnen?
Port_Zeile ist durch den Alias nur ein anderer Bezeichner für das
Gleiche, nämlich den PortB. Es wird dadurch KEINE Variable. Es ist
genauso als ob man da PortB hinschreiben würde. Dieses "Alias" hat
verschiedene Vorteile, auf die ich aber jetzt nicht eingehe.
Sven Schmidt schrieb:> Hinter dem Data sind ja alle Spaltenbytes aufgelistet. Wenn also mein> Programm immerweider meine Interruptroutine aufruft, muss er doch> wissen, dass er nicht wieder das erste byte, sondern das zweite nehmen> soll. Da muss also wieder irgendwo mit einer >+1< die Spalte ausgewählt> werden. Weiß das Programm von selbst, dass es immer nach der Reihe zu> gehen hat oder muss man ihm sagen, dass er immer das nächste Spaltenbyte> aufrufen soll? Das tut ja dieses Lookup.
Das macht der Programmteil hier:
MWS schrieb:> Frame_Pos = Spalte + Shifts> Port_Zeile = Lookup(Frame_Pos , Text1)
Wenn Spalte immer von 0-19 durchzählt und Shifts noch 0 ist, wird
Frame_Pos: 0,1,2...19,0,1 usw., dementsprechend werden die Data
Spaltenbytes von 0-19 ausgegeben.
Wird Shifts um 1 erhöht, wird Frame_Pos folgendes Ergebnis liefern:
1,2,3...20,1,2 usw., damit wird also Spaltenbyte 1-20 augegeben.
Genau das bewirkt später das scrollen.
Sven Schmidt schrieb:> Für die Spalten werde ich PortA, PortD und von PortB die Bits 0-3> verwenden. Geht das so klar?
Ja, das ist einfach anpassbar. Wichtig ist, daß die Zeilenportpins unten
bei 0 anfangen und die Spaltenportpins links bei 0 anfangen, bis 7, und
dann der nächste Port wieder mit 0. Das ist aber auch für Dein eigenes
Programm wichtig.
Sven Schmidt schrieb:> Ich bin dann mal Zeitungen austragen...
Da beneide ich Dich jetzt nicht :D
Da melde ich mich mal wieder:
Gerade habe ich versucht, mittels der Spaltenbytes des Bildspeichers
eine Spalte des Zeichens "H" auszugeben.
Natürlich bin ich sofort gescheitert:
Ich bekomme es nicht hin, die Werte, welche der Variablen >Port_Zeile<
übergeben werden, dem PortC zuzuschreiben.
Habe es schon so versucht:
Eigentlich sollt jetzt >port_zeile< den Wert 127 tragen und ihn PortC
übermittel.
Nur tut er das nicht, also ich kann zumindest an keinem Portpin von
PortC einen positiven Pegel messen.
Wo liegt das Problem?
Sven Schmidt schrieb:> Wo liegt das Problem?
Arrays beginnen zwar in Bascom mit 1 (außer mit dem neuen
Compilerschalter), aber bei Lookup beginnt der erste Eintrag immer bei
0.
Außerdem heist's nur: PortC = Port_zeile
Was soll das &B..., kompiliert das überhaupt ?
Und Obacht !
Auf PortC lauert eine beliebte Anfängerfalle, das JTAG-Interface. Dieses
blockiert die Pins PC2, PC3 und PC5. Das Interface kann über die Fuses
abgeschaltet werden.
Schau' Dir auch die mitgelieferten Beispiele an, da werden zu Anfang die
Stacks im Code definiert. Es wäre eine gute Idee, das auch so zu machen.
>Arrays beginnen zwar in Bascom mit 1 (außer mit dem neuen>Compilerschalter), aber bei Lookup beginnt der erste Eintrag immer bei>0.
Stimmt, es gibt eh kein Spaltenbyte 1, sondern nur das nullte, also 127.
Habe jetzt das &B() weggenommen, eh schwachsinnig, ist ja die binäre
Schreibweise, und frame_pos = 0 gegeben und nun so stehen. Komiplieren
lässt es sich jetzt auch problemlos, jedoch gibts immernoch keinen Pegel
auf PortC.
Irgendetwas scheint noch nicht mit dem PortC und der Variablen zu
stimmen.
EDIT:
JTAGEN habe ich schon lange aus...
Alle Portpins lassen sich schalten, das habe ich gestestet. Also an
denen kann es ganz sicher nicht liegen.
Wenn's nicht klappt, dann systematisch vorgehen, zuerst:
PortC = 255
Wenn das klappt, dann:
Port_zeile = 255
PortC = Port_zeile
Usw.
Diese Art Code lässt sich im Simulator gut prüfen.
Das mit dem systematischen Vorgehen ist nicht mehr notwendig - ich habe
legiglich vergessen, eine Spalte auf high zu setzen. :D
jajaja...was so kleine Fehler ausmachen können, erstaunlich.
Okay, soweit, so gut.
Jetzt mache ich mich mal ans Probieren mit dem Timer0.
Noch eine kurze Frage dazu.
1. Wofür steht dieses Zählen von 0-255 im Timer0?
Da muss doch garnichts gezählt werden. Er muss lediglich zu einer
Subrountine springen, wenn der Timer0 mit dem OVF überläuft, das
ausführen, was er auszuführen hat, und wieder von Vorn' beginnen. Mehr
ist da doch nich?
Wie kommst Du dann auf etwa 77 Zeilen in deinem Notfallprogramm?
Sven Schmidt schrieb:> 1. Wofür steht dieses Zählen von 0-255 im Timer0?
Die Timer, egal ob Timer0, 1, 2 usw. sind nun mal Zähler, die machen nur
ihren Job :D
Timer0 ist ein 8Bit Timer, der kann nur von 0 - 255 zählen. Diese Zähler
existieren in Hardware im Chip, sie arbeiten selbstständig wenn man
ihnen mal gesagt hat, was sie machen sollen.
Den Takt bekommen diese Zähler u.A. (und hier in unserem Beispiel) vom
Prescaler, dem Vorteiler. Ist der Prescaler gleich 8, dann wird in
Deiner Konfiguration der Systemtakt von 3686400Hz Quarz durch 8 geteilt,
also 460800Hz, und damit wird der Zähler getaktet.
Um nun einmal durchzulaufen, also von 0,1,2...255,0 braucht der Timer
256 Takte, er läuft also mit 460800 / 256 = 1800Hz durch. Wenn der
Overflow Interrupt aktiviert ist, wird diese OVF ISR 1800 mal pro
Sekunde aufgerufen.
Das passiert dann alles von selbst und vor allem: sehr genau.
Sven Schmidt schrieb:> Wie kommst Du dann auf etwa 77 Zeilen in deinem Notfallprogramm?
Bascom zeigt mir links unten die Zeile an, und in Zeile 77 steht meine
letzte Anweisung, dann kommen nur noch die Data Zeilen.
Sven Schmidt schrieb:> Da muss doch garnichts gezählt werden. Er muss lediglich zu einer> Subrountine springen, wenn der Timer0 mit dem OVF überläuft, das> ausführen, was er auszuführen hat, und wieder von Vorn' beginnen. Mehr> ist da doch nich?
Ah... War nur zur Erklärung geschrieben. Tatsächlich
benötigst/verarbeitest Du den Zählerstand von Timer0 nicht.
Außer vielleicht durch ein Preload, dann greifst Du schreibend darauf
zu.
So wie ich das mit der Taktfrequenz sehe, musst Du aber kein Preload
machen, Du bekommst bei Prescaler = 8 dann 90Hz Wiederholrate, das
sollte gut passen.
YES, so langsam habe ich den Dreh raus. (:
Also ist Timerß garnicht so komplex, wie ich es mir die ganze Zeit über
vorgestellt habe.
So, habe nun versucht, den ersten Buchstaben abzubilden:
1
$regfile="m16def.dat"
2
$crystal=3686400
3
4
DimPort_zeileAsByte
5
DimFrame_posAsByte
6
DimSpalteAsByte
7
8
ConfigPorta=Output
9
ConfigPortc=Output
10
11
Beginn:
12
13
Frame_pos=0
14
15
Spalte=0
16
17
Do
18
19
Frame_pos=Frame_pos+1
20
21
Spalte=Spalte+1
22
23
24
Port_zeile=Lookup(frame_pos,Text1)
25
26
27
Portc=Port_zeile
28
29
Porta=Spalte
30
31
32
Waitms10
33
34
35
Porta=0
36
37
Portc=0
38
39
40
Port_zeile=0
41
42
IfSpalte>=6Then'wennspalte6ist,zu>Beginn<springen
43
GotoBeginn
44
EndIf
45
46
47
Loop
48
End
49
50
Text1:
51
Data127,73,73,73,65,0'E
Bei diesem Programm sehe ich auf der Anzeige die letzten 3 Spalten, dann
fängt der MC an, mir irgendwelche unbekannten Dinge auszuspucken...
Aber das kommt wenigstens bei raus:
ooo
-
-
oo
-
-
ooo
Wo der Rest bleibt, weiß ich aber:
Ich gebe keinen Wert von 0-255 sondern normale Ziffern von 0 bis
unenedlich.
Das kann man ja nicht so einfach dem PortA zuweisen.
Jetzt die Frage: Wie addiere ich zu einer Variablen die Zahlen
0,1,2,4,8,46,32,64,128, wenn ich immer um ein Bit weiter bzw zurückgehe?
Geht das mit diesem >Shift left, right< -Befehl?
Ich könnte das natürlich auch binär machen, das probiere ich gleich mal
aus, aber ich hätte es lieber in Zahlen.
Lass mal das Goto weg, kein guter Stil, benötigt man auch nicht.
1
If Spalte >= 6 Then
2
Frame_pos = 0
3
Spalte = 0
4
End If
Sven Schmidt schrieb:> Geht das mit diesem >Shift left, right< -Befehl?
Ja, so mache ich das auch. Am Anfang auf 1 setzen und dann immer um 1
nach links schieben.
Sven Schmidt schrieb:> Port_zeile = 0
Ist überflüssig, wird sowieso durch Lookup neu gesetzt.
Sven Schmidt schrieb:> Ich könnte das natürlich auch binär machen, das probiere ich gleich mal> aus, aber ich hätte es lieber in Zahlen.
Für den MC ist alles binär.
Aber keine so Aktionen mehr wie die erste Gosub-Orgie :D
Man könnte tatsächlich mit einem zweiten Data-Feld arbeiten, aber Shift
ist viel eleganter.
Soweit, so gut....
Leute, ich hab gute Nachrichten: Mit dem Programm bin ich so gut wie
fertig.(:
Da ihr mir so intensiv geholfen habt, konnte ich es auch verstehen und
nun selbst produzieren, mehr oder weniger gut.
Ledigilich eine Sache mahct mich zu schaffen:
Ich komme leider nicht mit dem Festlegen der Schiebewerte zum Scrollen
der >frame_pos< zurecht.
Das Programm soll mir bei jedem hundersten Overflow ( Wiederholung = 100
) die gesamten Standorte der Spaltenbytes um einen Wert nach links oder
rechts verschieben.
Ich werde es ersteinmal weiter probieren, vorallem das Einscrollen...
Hah je... Danach frag ich bei eventuellen Fragen nach.
Ist der Code so okay?
Es darf pro Aufruf der ISR nur 1 Spalte ausgegeben werden !
Denn sonst ist das nicht Timergesteuert. Dann kannst Du es genauso in
der Hauptschleife laufen lassen. Im Moment braucht Dein Code länger als
der Timer, der trifft also immer vorher ein und deshalb steht IMMER ein
Timerinterrupt an. Das ist nicht so recht Sinn der Sache.
Die Variable Shifts fehlt komplett. Diese sorgt in meinem Beispielcode
dafür, daß gescrollt wird. Dazu muss sie jeweils zu frame_pos addiert
werden.
Schau Dir mal mein ursprüngliches Beispiel an.
Die Loop muss aus der ISR raus, dann das rein:
Sven Schmidt schrieb:> EDIT:>>>Do< kommt erst nach dem >Mach_was:<. Funktioniert aber dennoch einwandfrei.
Nur eben nicht so, wie's gedacht ist...
Vergleich' mal anhängenden modifizierten Code mit Deinem Eigenen.
Sind nur ein paar Sachen umgestellt.
Ein Wait, ob ms oder s hat auf gar keinen Fall in einer
Timerinterruptroutine etwas zu suchen, genauso wenig wie hier das
Do/Loop.
Deine Timerroutine dauert ca. 6400 Prozessorzyklen, der Timer löst aber
bereits nach 2048 (Prescaler 8 x 256) Prozessorzyklen aus. Was glaubst
Du, hat das zur Folge ?
Es gibt auch noch einen kleinen Schönheitsfehler, bis Spalte 8 sind alle
Spaltentreiber aus. Das behebt sich aber so schnell, daß man nichts
davon merkt.
Ich hab noch den Shifts-Block eingebaut.
Die ISR wird mit Timer 1800 mal pro Sekunde aufgerufen, also würde 900
jede halbe Sekunde eine Spalte weiter scrollen
Wobei es eine bessere Methode gäbe diese Variable hochzuzählen, und zwar
wäre das hier drin:
1
Elseif Frame_pos = 20 Then
Denn dieses Elseif wird aufgerufen, wenn alle Spalten ausgegeben wurden,
das ist die ideale (synchrone) Position um hochzuzählen.
Shifts selbst einzubauen, damit das auch scrollt, überlasse ich Dir.
Sollte aber eine leichte Übung sein, wenn Du das Prinzip verstanden
hast.
Habe es gerade hinbekommen, den Text zu scrollen.
Nur ein Problem: Der Text scheint zu lang für das Programm zu sein. Bis
zum Wort "GUTEN" kommt er problemlos durch, doch dann fängt mir der MC
an, kurz noch dunkle umrisse von Teilen des "GUTEN" auszugeben und
bricht dann vollkommen ab und kehrt nicht mehr zum Anfang zurück. Das
passiert bei allen Texten. Ein Fehler in den Spaltenbytes ist also
auszuschließen.
Kann es sein, dass da irgendetwas überfordert ist mit dem Rechnen? Ab
einer bestimmten Spaltenbytezahl kann er nicht mehr und bricht ab. Das
ist ziemlich frustrierend.
Weiß jemand rat?
Sonst bin ich eben fertig. Ging ja schneller als erwartet. Mit dem
Gosub-Horrror wäre ich bis heute noch nicht mal bis zur Hälfte gekommen.
:D
Ich danke euch allen nochmals für die gute Unterstützung, auch wenn
einige Erklärungen vor lauter Fachbegriffen für einen Leien zu
verzweifeln übrig ließen. (:
Also das ist ein wenig dem Pferd von hinten in's Auge geschossen :D
D.h. ein wenig kompliziert.
Es hätte gereicht, bei laufschrift_sven_mod.bas die Frame_Pos aus Shifts
und Spalten zu errechnen. Wie ich aber erst jetzt bemerke, hast Du die
eigentlich selbsterklärende Variable Frame_Pos dort als Spaltenzähler
zweckentfremdet, und so war da vielleicht schwieriger drauf zu kommen.
Also, im Code hätte also statt Frame_Pos besser "Spalte" gestanden, die
wären dann immer von 0-19 durchgezählt worden.
Dann hätte da vorteilhafterweise auch gestanden:
1
Frame_Pos = Spalte + Shifts
2
Port_zeile = Lookup(Frame_Pos , Text1)
Dein Code ist, sagen wir mal, "interessant", aber wenn er funktioniert,
soll's mir recht sein.
Sven Schmidt schrieb:> doch dann fängt mir der MC> an, kurz noch dunkle umrisse von Teilen des "GUTEN" auszugeben und> bricht dann vollkommen ab und kehrt nicht mehr zum Anfang zurück.
Der Fehler, warum der Resttext nicht ausgegeben wird, dürfte die falsche
Deklaration von Frame_Pos als Byte sein.
Das muss ein Word sein, diese Variable dient als Zeiger und als Byte
gehen da natürlich nicht mehr als 256 Positionen. Danach verhaspelt sich
Deine Logik mit dem "If Frame_pos = X1 Then" usw., da das nun nicht mehr
aufgeht.
Dann mal viel Erfolg und hoffen wir, daß es die Lena zu schätzen weis
;-)
Ludwig
>Der Fehler, warum der Resttext nicht ausgegeben wird, dürfte die falsche>Deklaration von Frame_Pos als Byte sein.
Henn ich frame_pos auf word umbenenne, kommen irgendwelche Hieroglyphen
in der Anzeige heraus. Ich habe außerdem nun >Spalte< als Anhaltspunkt
für die Spaltentreiber genommen. Das selbe kommt dabei raus. Außerdem
muss ich ja drei einzelne Ports hintereinander einschalten. Das machts
ja eben schwieriger.
Sven Schmidt schrieb:> Henn ich frame_pos auf word umbenenne
Umbenenne ? Du meinst dimensionieren ?
Wenn Dein Code prinzipiell funktioniert, dann muss er auch mit:
1
Dim Frame_pos As Word
hinhauen.
Sven Schmidt schrieb:> Ich habe außerdem nun >Spalte< als Anhaltspunkt> für die Spaltentreiber genommen.
Zeig' mal Deinen Code, bzw. probier' mal den Anhängenden aus, der um die
Adressierung per Shifts erweitert ist.
Sven Schmidt schrieb:> Das machts ja eben schwieriger.
Dies hier war meine Lösung, würde nur nicht ganz passen, weil Du die
Ports ungünstiger verdrahtet hast (Teil-Port in der Mitte)
1
Dim Spalten_Sel As Long
2
Dim Sp_0_7_Val As Byte At Spalten_Sel Overlay
3
Dim Sp_8_15_Val As Byte At Spalten_Sel + 1 Overlay
4
Dim Sp_16_19_Val As Byte At Spalten_Sel + 2 Overlay
5
...
6
Shift Spalten_Sel , Left
Das shiftet eine 1 durch die Long Variable (32 Bit breit) durch, die
Overlays holen dann aus dieser Long die einzelnen Bytes für die
Spaltenports raus.
Soo,
ich melde mich dann mal, aber diesmal zuletzt:
Das Geschenk hat der Lena gefallen. (:
Außerdem funktionierte jetzt auch der Code von MWS. Eigentlich tat das
meiner auch, nur hab ich den Fehler erst später erkannt.
Ich danke euch allen nocheinmal für eure Hilfe. Ihr habt mir zwar nichts
beigebracht, aber mich unterstützt, was für Anfänger sehr wichtig zu
seinen scheint! Ohne euch wäre ich zu dem hier nicht gekommen und müsste
mich weiter mit dem Gosub-Befehl herumschlagen.
Ich wünsche euch allen ein besinnliches Weihnachtsfest und ein gutes
neues Jahr!
MfG
Sven Schmidt
hallo leute!
Ich melde mich dann wieder mal!
Ein Bekannter wollte, dass ich ihm eine Led-Matrix mit 10x150 Pixeln
Bastle und ein Programm (nur mit Standschrift) für schreibe.
Ich weiß ja nun, wie so ein Programm aufgebaut ist, dank Euch. Nur hab
ich jetzt einige Dinge, die man nicht mit meinem Wissen umsetzen kann:
-150 Spaltenpixel sind fürs Spaltenmultiplexing eher ungeeignet
-ich müsste jetzt irgendwie Bytes für jeweils 150 Zeilenpixel und eben
nicht für jeden einzelnen Buchstaben sondern für einen ganzen Satz
setzen
wie ist das anzustellen?