- LiFePO4 Speicher Test         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: Library für Bascom: Array anlegen und beschreiben

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    12.07.2008
    Ort
    Villingen-Schwenningen
    Beiträge
    143

    Library für Bascom: Array anlegen und beschreiben

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo zusammen,

    ich habe ein paar Routinen in Bascom geschrieben, die ich nach und nach in eine Lib übertragen will. Hier ein Beispiel:

    Code:
       Sub OSDClear()
       '[OSDClear]
        _OSDClear:
          lds xl,{_Screen_Start}                                ' Startadresse Bildbuffer laden
          lds xh,{_Screen_Start+1}
          ldi yl,lbyte(BufferSize)                              ' BufferZize nach Y
          ldi yh,hbyte(BufferSize)
          clr r24
        _OSDClearScreen:
          st x+,r24
          sbiw yl,1
          breq _OSDClearScreenExit
          rjmp _OSDClearScreen
        _OSDClearScreenExit:
       End Sub
    Nun greife ich über diese Routinen auf ein ByteArray zu, was in Bascom auch funktioniert. Das Array brauche ich aber später in der Lib und nicht im Hauptprogramm.

    Nun die Frage:
    Wie definiere ich in einer Library ein Array über beispielsweise 512 Byte. Muss das in einer Routine gemacht werden oder wird das ganz am Anfang gemacht?

    Das ganze soll ähnlich funktionieren wie der Befehl
    Code:
    Config Serialin=Buffered
    Der Buffer wird erst angelegt, wenn die Initialisierung aufgerufen wird.

    Wie wird also das Array angelegt und wie kann ich innerhalb der Lib z.B. auf den ersten Index des Arrays zugreifen?

    Ich verwende aktuell die Vollversion BascomAVR 1.11.9.5

    Vielen Dank schon mal für eure Hilfe!

    Mitch.

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Nun, das definieren von Speicherplatz findet ja beim compilieren statt und nicht zu laufzeit.
    Beim DIM-en werden ja label-adressen festgelegt, die dann als HIGH() und LOW() in die Befehle eingebaut werden.
    "COnfig serialin=buffered" wird daher schon zur Compile-Time ausgewertet.

    Du kannst aber z.b. deiner LIB die Grösse deines Arrays als
    CONST ArrSize = 512
    festelegen und dieses Symbol "ArrSize" in der LIB verwenden ( um es in die Assembler-befehle einzubauen, s.o)

    EIn bisschen was über Libraries hab ich da geschrieben:
    http://www.rn-wissen.de/index.php/Bascom_Libraries
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    12.07.2008
    Ort
    Villingen-Schwenningen
    Beiträge
    143
    Das klingt aus deinem Munde ja simpel.
    Leider stellen sich mir trotzdem eine menge Fragen.

    Vielleicht kannst du das mit einem kurzen Code-Schnipsel verdeutlichen.

    Ich Frage mich gerade, wenn ich die ArraySize in einer Constante ablege und in Bascom werden ja auch Variablen gedimt. Woher weis dann Bascom, dass die nächste Variable erst im Anschluss kommt und nicht in den Array-Bereich gerät?

    Nehmen wir an ich schreibe folgendes:

    zunächst Bascomcode:
    Code:
    Dim Variable1 as Byte
    Dim Variable2 as Word
    
    $Lib "MyLib.lib"
    
    Dim Variable3 as Word
    und in der Lib wird ein Array definiert mit Namen MyArray in dieser Art:

    Code in der Lib
    Code:
    MyArray:
    .equ MyArraySize = 512
    Ich glaube der Code ist so nicht ganz korrekt, zeigt aber, wie ich deine Erklärung verstanden habe.

    Irgendwie tappe ich da noch im Dunkeln.

    Und da die Lib zwischen Variable2 und Variable3 eingefügt ist. Wird die Variable3 nicht in diesem Array-Bereich dimensioniert?

    Ich verstehe das nicht.

    kurzes Codebeispiel wäre klasse.[/code]

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Moin ! (spät, aber doch)
    Also: Speicherplatz definieren bzw reservieren muss man im Bascom-Code mit den "DIM's".
    In den Libraries ist sowas nicht vorgesehen und eigentlich auch nicht möglich. Nur von den Stack's kann man sich zur Laufzeit was abzwicken.

    Diese Abhängigkeit der Library von den Bascom-Dims hat aber den Vorteil, dass man die Library-Funktionen nicht angreifen muss, wenn man z.B auf einen grösseren/kleineren µC wechselt.

    Ich definiere also im Bascom
    Code:
    Const ArrSize = 512
    DIM MyArray(ArrSize) as Byte
    Dadurch ist der Platz belegt und wird von Bascom nicht mehr angegriffen

    Damit die Library-Funktion dies Definition auch mitkriegt, habe ich mehrere Möglichkeiten,
    eine davon ist die, dass die Namen der Variablen fix vereinbart sind
    d.h. die Library geht davon aus, das im Bascom-Teil immer
    "MyArray" und "ArrSize" verwendet werden.

    Um Dir ganz konkreten Code vorzuschlagen, würde es mir helfen zu wissen, was die Library-Routinen in Etwa können sollen.
    Daraus ergeben sich nämlich unterschiedliche empfehlenswerte Vorgangsweisen.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    12.07.2008
    Ort
    Villingen-Schwenningen
    Beiträge
    143

    Beispielcode

    Hallo

    Ich versuche mich daran, einen OSD (On Screen Display) zu realisieren.
    Das ganze mit einem ATmega aufgebaut und mit I2C-Schnittstelle versehen.

    Das OSD verwendet einen Buffer als Bildspeicher, der z.B. in 16 Spalten (Zeichen) und 16 Zeilen aufgeteilt ist. Also ein 16x16 Bildspeicher.

    Die Routinen, die eventuell in einer Lib untergebracht werden sollen, haben die Aufgabe, Textstring in diesen Buffer zu schreiben.

    Eine Routine OSDSetCursor(Spalte,Zeile) setzt den Bildzeiger auf die Zeile und Spalte, wo der Text später eingeblendet werden soll.

    Eine weitere Roitune OSDWriteText(text) schreibt dann den Text an die entsprechende Stelle im Bildspeicher.

    Eine Dritte Routine OSDClear() löscht den Buffer wieder.

    Es gibt noch ein paar zusätzliche Routinen, um OSD einzuschalten OSDOn() und auschhalten OSDOff().

    Soviel zur Erklärung der Routinen.

    Die Lib habe ich derzeit so aufgeteilt.

    Die Header-Datei, die die Constanten und Dimensionierungen enthält. Unter anderem auch den Screen_Buffer(). Das sieht so aus:

    Code:
       ' Projekt:           OSD (On Screen Display)
       ' Modul:             Screen.h
       ' erstellt:          08.11.2009
       ' letzte Änderung:   09.11.2009
       ' Beschreibung:
       ' Headerdatei zu Modul Screen.bas
    
    
    
    Declare Sub OSDInit()
    Declare Sub OSDClear()
    Declare Sub OSDOn()
    Declare Sub OSDOff()
    Declare Sub OSDSetCursor(byval Zeile as Byte , byval Spalte as Byte)
    Declare Sub OSDWriteString(Byval Text as String)
    
    Dim _Screen_Buffer(BufferSize) as Byte                      ' Bild-Speicher
    Dim _Screen_Offset as Word                                  ' Offset Bildbuffer für Schreibzugriffe
    Dim _Screen_Start as Word                                   ' Startadresse Bildbuffer
    
    Dim OSD_Char as Byte
    Die eigentlichen Routinen habe ich in einem 2. Modul untergebracht und sieht so aus:
    Code:
       ' Projekt:           OSD (On Screen Display)
       ' Modul:
       ' erstellt:          08.11.2009
       ' letzte Änderung:   08.11.2009
       ' Beschreibung:
       ' Routinen zum Bearbeiten des OSD-Screen-Buffer
    
       $nocompile
    
    '  ----------------------------------------------
    '  OSD initialisieren
    '  ----------------------------------------------
    
       Sub OSDInit()
       '[OSDInit]
        _OSDInit:
          loadadr _Screen_Buffer(1) , x                         ' Start-Adresse Bildspeicher berechnen
          sts {_Screen_Start},xl                                ' und in _Screen_Start speichern
          sts {_Screen_Start+1},xh
    
          clr r24                                               ' _Screen_Offset zücksetzen
          sts {_Screen_Offset},r24
          sts {_Screen_Offset+1},r24
          rcall _OSDClear                                       ' Bildschirm löschen
       '[END]
       End Sub
    
    '  ----------------------------------------------
    '  Bildschirm löschen
    '  ----------------------------------------------
    
       Sub OSDClear()
       '[OSDClear]
        _OSDClear:
          lds xl,{_Screen_Start}                                ' Startadresse Bildbuffer laden
          lds xh,{_Screen_Start+1}
          ldi yl,lbyte(BufferSize)                              ' BufferZize nach Y
          ldi yh,hbyte(BufferSize)
          clr r24
        _OSDClearScreen:
          st x+,r24
          sbiw yl,1
          breq _OSDClearScreenExit
          rjmp _OSDClearScreen
        _OSDClearScreenExit:
       '[END]
       End Sub
    
    '  ----------------------------------------------
    '  Cursor-Position setzen
    '  Zeile:  Werte 0 bis 23
    '  Spalte: Werte 0 bis CharPerLine (Zeichen pro Zeile)
    '  ----------------------------------------------
    
       Sub OSDSetCursor(byval Zeile as Byte , byval Spalte as Byte)
       '[OSDSetCursor]
        _OSDSetCursor:
          ldd xl,y+2                                            ' Zeiger auf Zeile
          ldd xh,y+3
          ld r24,x                                              ' Zeile nach r24
          ldi r25,CharPerLine
          mul r24 , r25
    
          ldd xl,y+0                                            ' Zeiger auf Spalte
          ldd xh,y+1
          ld r25,x                                              ' Spalte nach r25
    
          add r0,r25                                            ' Spalte addieren
          clr r25
          adc r1,r25
          sts {_Screen_Offset},r0
          sts {_Screen_Offset+1},r1
       '[END]
       End Sub
    
    '  ----------------------------------------------
    '  Text in Buffer schreiben
    '  SetCursor sollte zuvor aufgerufen werden!
    '  ----------------------------------------------
    
       Sub OSDWriteString(byval Text as String)
       '[OSDWriteString]
        _OSDWriteString:
          local Offset as Word
          Offset = _Screen_Start + _Screen_Offset               ' Adresse berechnen
          ldd zl,y+0                                            ' Adresse auf lokale Variable Offset nach Z
          ldd zh,y+1
          ld xl,z+                                              ' Wert lokaler Variable Offset nach X
          ld xh,z
          loadadr Text , z                                      ' Zeiger auf Text nach Z
    
        _WriteStringNextChar:
          ld r24,z+
          cpi r24,0                                             ' letztes Zeichen?
          breq _WriteStringExit
          st x+,r24
          rjmp _WriteStringNextChar
        _WriteStringExit:
       '[END]
       End Sub
    
    '  ----------------------------------------------
    '  OSD einschalten
    '  ----------------------------------------------
    
       Sub OSDOn()
       '[OSDOn]
        _OSDOn:
          nop
       '[END]
       End Sub
    
    '  ----------------------------------------------
    '  OSD ausschalten
    '  ----------------------------------------------
    
       Sub OSDOff()
       '[OSDOff]
        _OSDOFF:
          nop
       '[END]
       End Sub
    Die Routinen funktionieren soweit und sind auch schon andeutungsweise für Lib vorbereitet.

    In der Lib hätte ich gerne das Modul 1 (Header) + Modul 1 (Routinen) gehabt. Schließlich soll der Benutzer der Library nicht noch von Hand irgendwelche Konstanten oder Buffer dimensionieren müssen.

    Schön wäre natürlich auch ein Configurations-Befehl ala Bascom zur Initialisierung des Buffers und des PortPin für die Ausgabe des OSD.

    In Etwa so:
    Config OSD=Zeichen,Zeilen

    und
    Config OSDPin=PortB.1

    Allerdings weiß ich nicht, ob das mit Config möglich ist.

    Weist du Rat?

    Gruß Mitch.

    [/b]

  6. #6
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Ich schau mir deine Routinen noch genauer an.

    Das mit "Config" wird aber wohl nix, das spielt Bascom nicht mit.
    aber, nur als Beispiel:
    Code:
    Const OSDZeichen  = 16
    Const OSDZeilen    =  16
    Const OSDPort       =  PortB
    Const OSDPin        =  1
    kommt mir eigentlich auch nicht so schlimm vor
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    12.07.2008
    Ort
    Villingen-Schwenningen
    Beiträge
    143
    Hallo Robert,

    da fehlt noch der Screenbuffer, der Zeiger für den Bildspeicher, der Offset dazu und dann wird es unübersichtlich. Es muss auch noch jede Routine deklariert werden und noch ein $External je Routine eingefügt werden.

    Das wird immer mehr. Da ist man fast einfacher bedient, eine Bas zu inkluden, die diese Declares, usw ethält. In dieser steckt dann auch der $Lib Befehl.

    Eigentlich wollte ich das alles etwas vereinfachen deswegen auch die Lib.

    Mitch

  8. #8
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Nun, ich persönlich verwende Libraries recht umfangreich, dabei mache ich auch genau das:
    Ein Bascom-Include, das auf diese Art die Schnittstelle zu der Library bildet.
    Dabei verwende ich immer einen Art Kontroll-Block, der von Bascom und der Library gemeinschaftlich verwendet wird.

    Im Bascom musst du nur die Routinen deklarieren u. $external definieren, die du vom Bascom aus aufrufen willst. Das musst du aber so wie so.
    Das wäre in deinem Fall offenbar
    OSDSetCursor(Spalte,Zeile)
    OSDWriteText(text)
    OSDClear()
    OSDOn()
    OSDOff().
    Das scheint mir nicht unzumutbar.

    aaaaaaber eins muss klar sein:

    Diese ganze Planung und Vorgangsweise ist sinnvoll, wenn man dann diese Libraries in mehreren Projekten braucht.

    Für eine einzige Anwendung / Programm

    kann man auch überlegen, bei Bascom zu bleiben und nur trickreichen Dinge mit Inline-Assembler zu lösen.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    12.07.2008
    Ort
    Villingen-Schwenningen
    Beiträge
    143
    OK Robert,

    ich danke dir fürs erste für deine Ausführungen.
    Ich hoffe doch, ich kann mich nochmal an dich wenden wenn Bedarf beseht?

    Mitch.

  10. #10
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Ich bittte sogar darum
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen