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]