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]
Lesezeichen