GLCD, farbiges XV-Display und BASCOM (Beispiele) FAQ

Hallo,

@Cassio:

Mit dem Timing gibt es da keine Probleme :)

@Bonze:

Ich habe im ersten Versuch das Ganze mit Functions aufgebaut. Das Ergebnis war bei einem ATMega8 für ein paar wenige Funktionen: 34% Flash.
Mit der jetzigen Version habe ich alle wichtigen Funktionen drin und einiges an Testcode und brauche nur noch 26% Speicher.
 
meinte nur das damit wahrscheinlich es besser zu handeln ist, man schreibt 1funktion übergibt der die werte ,.,usw.
das geht doch auch mit subs oder?
z.B. kreis zeichne(radius, x-koordinaten, y-koordinaten,farbe, linienstärke),
oder was es da alles gibt,.
 
Hi,

man schreibt 1funktion übergibt der die werte ,.,usw.
das geht doch auch mit subs oder?
z.B. kreis zeichne(radius, x-koordinaten, y-koordinaten,farbe, linienstärke),
oder was es da alles gibt,.
das geht auch mit normalen Subs und globalen Variablen. So wie zB bei
DCF77 oder anderen. Das ist auch nicht unübersichtlicher. Man muß sich beim
Programmieren dann nur etwas am Riemen reißen mit den Variablennamen.
Bei lokalen Variablen und bei Funktionen werden die Werte eigentlich vor der
Verarbeitung nur noch einmal "umgetopft" aber mehr nicht.

Gruß
Dino
 
.....die Werte eigentlich vor der Verarbeitung nur noch einmal "umgetopft" aber mehr nicht.

Hallo zusammen!

So wie Dino, sehe ich das auch.
Mit "Function" und "Call" werden immer nur Variablen an andere Variablen übergeben.
Ich bin aber der Meinung, dass die genannte Kombination schneller ist als eine Gosub-Anweisung..... wenn sie sonst auch immer mehr Speicher benötigt.

Es kommt wohl wieder mal auf den Verwendungszweck drauf an. :rolleyes:

Solange ich keine zeitlichen Probleme bei der Abarbeitung des Programmes bekomme, nehme ich aber auch immer lieber Gosub. ;)

Gruß,
Cassio
 
Update zu Beitrag Nr. 10

Hallo zusammen !

Der Gute HBA (HinterBlauenAugen) hatte mich darauf hingewiesen, dass ich meine Lösung zum Zerlegen des Textstrings "Eingabe" in einzelne Zeichen wesentlich einfacher und schneller realisieren kann.

Das "Zauberwort" dafür heißt: Overlay

Ich hatte mich bis jetzt nicht wirklich mit "Overlay" befasst, weil ich im Hinterkopf immer noch einen alten Hinweis hatte.....
"Früher" hieß es beim Overlay: Man müsste die genauer Speicheradresse kennen, um die darin enthaltenen Daten zu "manipulieren".
HBA hatte mich aber eines besseren belehrt und mir einen Tipp gegeben, wie ich das Overlay dimensionieren muss. :)

Aus dem Grunde habe ich meine Routine zum Senden der einzelnen Zeichen aus dem Textstring geändert!


Kurzer Blick zurück....
(Vollständiger Beitrag Nr. 10)
Vorher wurde der Textstring mit den Befehlen "Len()", "Mid()" und "Asc()" zerlegt und in die jeweils zugehörige ASCII-Nummer ermittelt.

Vollständige alte Subroutine:
Code:
Text:
'Text-String ausgeben

Bitwait Display_busy , Set
Reset Display_cs                                            ' Chipselect Display Module
Waitus 2

I = &H48                                                    ' Display Text
Spiout I , 1

Bitwait Display_busy , Reset
Spiout X1 , 1                                               ' Send Parameter
Spiout Y1 , 1
Spiout Xmax , 1

' Eingabestring in einzelne Zeichen zerlegen
   For Zz = 1 To Len(eingabe)                               'Pro Zeichen im String aufwärtszählen
      Zeichen = Mid(eingabe , Zz , 1)                       'Einzelne Ziffer, oder Buchstabe aus String
      Char = Asc(zeichen)

     Spiout Char , 1
   Next Zz

Char = 0                                                    'Binäre Null zum Abschluss für den Textstring !
Spiout Char , 1

Bitwait Display_busy , Set
Set Display_cs                                              ' Chipselect Display Module
Waitus 1

Return



Und nun die neue Variante:

Im Header bitte hinzufügen:
Dim Eingabe_o(23) As Byte At Eingabe Overlay
(Dafür kann: Dim Zeichen As String * 1 entfallen)

In die Subroutine "Text" wird dann folgendes eingetragen:
(Bitte die alte "For Zz - Next Zz Schleife" entfernen !)


CodeBox bascom

' Eingabestring in einzelne Zeichen zerlegen

For Zz = 1 To Len(eingabe) 'Pro Zeichen im String aufwärtszählen
Char = Eingabe_o(zz) 'ASCII-Zeichen aus dem Eingabe-Array lesen
Spiout Char , 1
Next Zz


Eine Umwandlung der einzelnen Stringzeichen mit "Asc()" ist nicht mehr notwendig, weil im Array schon die zugehörign ASCII-Nummern abgelegt werden. :)

Der Programmcode ist nun nicht nur kürzer sondern auch effektiver! ;)

Vollständige neue Subroutine "Text":


CodeBox bascom

Text:
'Text-String ausgeben

Gosub Positionen

Bitwait Display_busy , Set
Reset Display_cs ' Chipselect Display Module
Waitus 2

I = &H48 ' Display Text
Spiout I , 1

Bitwait Display_busy , Reset
Spiout X1 , 1 ' Send Parameter
Spiout Y1 , 1
Spiout Xmax , 1

' Eingabestring in einzelne Zeichen zerlegen
For Zz = 1 To Len(eingabe) 'Pro Zeichen im String aufwärtszählen
Char = Eingabe_o(zz) 'ASCII-Zeichen aus dem Overlay Eingabe lesen
Spiout Char , 1
Next Zz

Char = 0 'Binäre Null zum Abschluss für den Textstring !
Spiout Char , 1

Bitwait Display_busy , Set
Set Display_cs ' Chipselect Display Module
Waitus 1

Return




Danke noch mal an HBA, für den Hinweis und die Tipps ! :flowers:

Grüße,
Cassio
 
Hallo Cassio,
hast du eigentlich mal ausprobiert, ob du die Zeichen nicht alle zusammen schicken kannst. Anstelle der For-Schleife

For Zz = 1 To Len(eingabe) 'Pro Zeichen im String aufwärtszählen
Char = Eingabe_o(zz) 'ASCII-Zeichen aus dem Eingabe-Array lesen
Spiout Char , 1
Next Zz

könntest du dann schreiben

Zz = Len(eingabe)
Spiout Eingabe_o(1), Zz

HBA
 
Hallo,

Das "Zauberwort" dafür heißt: Overlay
...
Im Header bitte hinzufügen:
Dim Eingabe_o(23) As Byte At Eingabe Overlay
...


CodeBox bascom

Char = Eingabe_o(zz) 'ASCII-Zeichen aus dem Eingabe-Array lesen
ich hab ja auch schon ein wenig mit Overlay rumexperimentiert ...

Heißt also man legt mit dem DIM sozusagen einen Speicherbereich im SRAM
an der 23 Byte groß ist und füttert ihn mit dem String. Danach kann man
mit der Variable ZZ als Adress-Pointer die einzelnen Bytes aus diesem Bereich
herauspicken.

Das sollte also auch in beiden Richtungen gehen. Also auch für das schreiben.


CodeBox bascom

Eingabe_o(zz) = Char 'ASCII-Zeichen in das Eingabe-Array schreiben

hoffe ich doch mal ...

Wie groß kann man das Array auf Byte-Basis machen ? Ein String darf ja
maximal 254 Zeichen lang sein (wenn man nicht die extra Library laden will).
Gehen da 256 Byte ? Also zB mit ...
Dim Speicherfeld_o(256) As Byte At Speicherfeld Overlay

Ich suche im Moment noch eine einfache und schnelle Möglichkeit mit 256Byte
großen Speicherfeldern im SRAM Daten abzulegen oder zu lesen. Zum Bsp für
Ringbuffer oder ähnliche Sachen. So schön elegant wie in Assembler geht das
ja unter BASCOM leider nicht. Außerdem muß ich noch ein wenig den internen
SRAM-Aufbau von BASCOM-Programmen verinnerlichen (HW-Stack, SW-Stack,
Frame, ...) Also wo alles im Speicher liegt, was wovon verwendet wird und
wie groß was sein sollte.

Aber das ist nen anderes Thema ... ;)

Gruß
Dino
 
könntest du dann schreiben

Zz = Len(eingabe)
Spiout Eingabe_o(1), Zz

Hallo HBA !

Ich weißt nicht, ob dies funktioniert.....
Dirk kann dazu bestimmt noch genaueres sagen, aber das Displaymodul erwartet immer nur ein Byte und dann das Nächste.

Ich weiß nicht, ob "Spiout" dies in deiner Form so realisiert. :hmmmm:
Müsste ich sonst mal ausprobieren. ;)

Gruß,
Cassio
 
Das sollte also auch in beiden Richtungen gehen. Also auch für das schreiben.


CodeBox bascom

Eingabe_o(zz) = Char 'ASCII-Zeichen in das Eingabe-Array schreiben

hoffe ich doch mal ...
Jo.

Wie groß kann man das Array auf Byte-Basis machen ? Ein String darf ja
maximal 254 Zeichen lang sein (wenn man nicht die extra Library laden will).
Gehen da 256 Byte ? Also zB mit ...
Dim Speicherfeld_o(256) As Byte At Speicherfeld Overlay
Array dürfen in Bascom ja bis zu 65535 Elemente enthalten, also auch hier.
Tatsächlich brauchst du dich um die Anzahl bei der Dimensionierung überhaupt nicht zu kümmern.
Das geht auch
Dim Speicherfeld_o(1) As Byte At Speicherfeld Overlay
Danach kannst du lustig den kompletten Speicherbereich den µC über Speicherfeld_o lesen und schreiben. Solange du immer eine Variable als Index nimmst. Speicherfeld_o(2) filtert der Compiler raus.

Und für die ganz Harten bezeichnet
Index=0
Speicherfeld_o(index)

dies die SRAM Zelle unmittelbar vor Speicherfeld_o(1)
Das kann man sehr gut zum 0-basierten Indizieren nutzen.

Was auch nirgendwo steht ist, dass dies geht
Speicherfeld_o(Index + 1) und Speicherfeld_o(Index - 1)
Das ist häufig in Schleifen ganz praktisch. Und es kostet soweit ich das sehe nichts. Die Anzahl Takte bleibt gleich.

All das ist natürlich nicht auf Overlays eingeschränkt, sondern geht mit jedem Array.

HBA
 
Ich weiß nicht, ob "Spiout" dies in deiner Form so realisiert. :hmmmm:
Müsste ich sonst mal ausprobieren. ;)
Müsste man mal an Hardware ausprobieren.
Das SPIOUT macht es jedenfalls. Könnte aber sein, dass es für das Display zu schnell ist.

Ich war nur darauf gekommen, weil direkt da drüber dies steht:
Spiout X1 , 1 ' Send Parameter
Spiout Y1 , 1
Spiout Xmax , 1

Dies dürfte auch nichts anderes sein als drei Werte direkt hintereinander.

HBA
 
Die Anzahl Takte bleibt gleich.

Hallo HBA!

Mal eine Frage zum Verständnis für mich. ;)

Woher nimmst du die Anzahl der Takte eigentlich? :hmmmm:
Habe ich da in BASCOM evtl. etwas übersehen, oder brauche ich dafür eine andere Software.... oder rechnest du das selber aus?

Ich habe auch mal in einem Buch gelesen, dass man sich das BASCOM-Programm als ASM-Liste anzeigen lassen kann.... und dort auch die Takte (und Zeiten) errechnet werden können.
Tatsächlich habe ich diese Funktion aber noch nicht entdeckt.
Gibt es das nun, oder handelt es sich dabei ggf. um ein PlugIn, oder habe ich da etwas falsch verstanden?
Ich bin zwar des ASM nicht mächtig.... wäre aber trotzdem interessant.

Gruß,
Cassio
 
Ich benutze dazu den Simulator.
Am unteren Rand stehen die Takte.
Wenn du das Programm angehalten hast und mit der rechten Maustaste auf die Zahl gehst, kommt in einem Fensterchen "Clear Cycles". Wenn du das anklickst, wird der Counter wieder auf 0 gesetzt.

ASM schaue ich mir nur im AVR-Studio an. Ist mir aber meistens zu aufwändig, das zu verstehen.

HBA
 
Spiout X1 , 1 ' Send Parameter
Spiout Y1 , 1
Spiout Xmax , 1

Dies dürfte auch nichts anderes sein als drei Werte direkt hintereinander.

Hi HBA!

Ja, dem würde ich zustimmen.....

Wenn ich aber Spiout richtig verstanden habe, dann bedeutet die letzte Ziffer doch immer, wieviele Bytes gesendet werden.
Da das Modul aber immer nur ein Byte erwartet und dann das Nächste, scheint es für mich nicht das Gleiche zu sein. :hmmmm:

Muss ich Dirk einfach mal fragen...... oder ich probiere es selber mal aus. ;)

Gruß,
Cassio
 
Hi HBA !

Ich habe mal ein Testprogramm in den Simulator geladen...

Der Screenshot zeigt die aktuelle Overlayfunktion....
Taktbeispiel_1.jpg

Du meinst ganz unten am Rand den Wert hinter "Cycl.:" ?

Dann muss ich den an der passenden Stelle auf Null setzen und das Programm dann schrittweise bis zum zweiten "Messpunkt" ausführen.
Anschließend habe ich die benötigten Takte?
Ist das so richtig?

Je nach Quarz kann ich ja dann auch die benötigte Zeit ausrechnen, oder?

Gruß,
Cassio
 
Ja, genau so.
Die zeit für den im Programm angegebenen Quarz steht ja schon da.
Du musst nicht im Einzelschritt gehen. Wenn du an die zweite Stelle auch einen Haltepunkt setzt, dann kannst du über F5 oder die Play Taste oben links bis dahin weiterlaufen lassen.
Bei deinem abgebildeten Programm musst du nur bedenken, dass die meiste Zeit für die Prints draufgeht.

HBA
 
Da das Modul aber immer nur ein Byte erwartet und dann das Nächste, scheint es für mich nicht das Gleiche zu sein. :hmmmm:

Hi HBA!

Warte mal......
Du magst doch Recht haben! :hmmmm:

Da die Werte X1, Y1 usw. einzeln abgefragt werden müssen, wird natürlich auch immer nur ein Byte gesendet (Spiout X1 , 1 dann Spiout Y1 , 1 und so weiter).
Wenn ich aber alle passenden Bytes gleich nacheinander aus dem Array lesen kann, müsste es doch funktionieren.
Die Hauptsache ist doch, die Werte kommen Byteweise in der erwarteten richtigen Reihenfolge!

Muss ich doch glatt mal ausprobieren. ;)

Gruß,
Cassio
 
Hi Cassio

Da die Werte X1, Y1 usw. einzeln abgefragt werden müssen, wird natürlich auch immer nur ein Byte gesendet (Spiout X1 , 1 dann Spiout Y1 , 1 und so weiter).
Wenn ich aber alle passenden Bytes gleich nacheinander aus dem Array lesen kann, müsste es doch funktionieren.
Die Hauptsache ist doch, die Werte kommen Byteweise in der erwarteten richtigen Reihenfolge!
im Endeffekt muß doch nur die richtige Sequenz (Reihenfolge) rüberkommen.
Man muß nur beim Senden drauf achten das der LCD-Controller schon wieder
neues Futter vertragen kann (Busy). Alles andere sollte Nebensache sein ;)
Du könntest also auch die Werte für X1, Y1, ... in ein Feld packen und das in
einem Rutsch rüberschieben wenn der Controller das so schnell verkraften kann.

Gruß
Dino
 
Hi Dino!

Ja, ich denke auch dass ich dies einfach mal ausprobieren muss.
Es sei denn, Dirk hat das selber schon getestet. ;)

Allerdings werfe ich heute den mkII nicht mehr an.....
Ist mir schon zu spät und ich bin schon mächtig :boring:

Gruß,
Cassio
 
Hallo zusammen,

die Parameterwerte könnt ihr direkt hintereinander übertragen. Ich bin jetzt kein Bascomexperte aber ich denke mal dass die Routine Spiout immer prüft, ob sie in das SPI-Datenregister schreiben darf, anders ausgedrückt, ob noch eine Übertragung aktiv ist oder nicht (Abfrage des SPIF-Flags). Ist der zweite Parameter von Spiout größer als 1, werden einfach die N Bytes übertragen, wobei der erste Parameter dann als Array angesehen wird.

In C sieht eine Übertragung mit HardwareSPI so aus, das entspricht Spiout output, 1

Code:
unsigned char XV_SPI_WriteRead (unsigned char output)
{
  unsigned char input;
    
  SPDR = output;                            //put byte 'output' in SPI data register
  while(!(SPSR & 0x80));                    //wait for transfer complete, poll SPIF-flag
  input = SPDR;                            //read value in SPI data reg.
    
  return input;                            //return the byte clocked in from SPI slave
}
Einen String würde man dann so übertragen, das letzte Byte muss eine Null sein. Dies entspricht dann sicherlich Spiout String, Laenge
Code:
  while (s[i])    // max. string length = 100
  {
    XV_SPI_WriteRead(s[i]);  
    i++;  
  }
Also einfach alles nacheinander übertragen, ohne BUSY abzufragen.

Das könnte man natürlich auch mit anderen Parametern machen, zum Beispiel bei den Koordinaten oder Farbwerten, wenn man diese vorher in der richtigen Reihenfolge in ein ByteArray schreibt und dann dieses mit Spiout Array, Laenge überträgt.

Grüße,
Dirk
 
Hallo zusammen!

Ich habe es nun mal ausprobiert und es funktioniert auch ohne die For-Next Schleife. :)

Damit kann man also auch zum Übertragen der Daten, wie von HBA vorgeschlagen, folgendes verwendet werden:
Code:
' Eingabestring via Overlay-Array übertragen
Zz = Len(eingabe)                                           'Zeichenlänge der Eingabe ermitteln
Spiout Eingabe_o(1) , Zz


Die Änderung wird dann automatisch in der Vorstellung für meine neue Struktur mit enthalten sein. ;)

Gruß,
Cassio
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)