PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LCD-Ausgabe



Limloz
27.06.2011, 13:09
Hallo,

ich habe hier schon viele Ideen und Lösungen aus dem Forum für mich mitgenommen - mich aber nun auch mal angemeldet um auch selbst eine Frage stellen zu können.

Ich möchte u. a. Druckwerte auf einem LCD kontinuierlich zur Anzeige bringen.
Ursprung dieser Druckwerte ist später der ADC-Interrupt.
Zur Simulation dessen läuft aktuell ein Zähler in der Main-Loop.

Um schnelle Programmteile von der langsamen LCD-Ausgabe zu entkoppeln, initialisier ich mein Display mit den Bascom-High-Level-Befehlen, beschreibe es aber in einem Timer-Interrupt mit jeweils 1 Zeichen/Interrupt.

Einen konstanten Displayinhalt kann ich mit dieser Methode (fortwährendes zeichenweises Überschreiben des Displays) fehlerfrei ausgeben. Hieraus schließe ich, dass das Timing zwischen µC und LCD stimmt.

Gebe ich allerdings meinen unsynchron laufenden Zählerstand aus, tauchen oft an eigentlich leeren Plätzen Zeichen und Zahlen auf.

Hier mein Testprogramm:



$regfile = "M128def.dat"
$crystal = 16000000
$hwstack = 64
$swstack = 64
$framesize = 64

'UART
Config Com2 = 57600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Open "com2:" For Binary As #1

'LCD
Lcd_rw Alias Portc.2 : Config Lcd_rw = Output : Lcd_rw = 0
Lcd_en Alias Portc.3 : Config Lcd_en = Output : Lcd_en = 0
Lcd_rs Alias Portc.1 : Config Lcd_rs = Output : Lcd_rs = 0
Lcd_data Alias Portc : Config Lcd_data = Output
Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , _
Db7 = Portc.7 , E = Portc.3 , Rs = Portc.1
Config Lcd = 16 * 1a
Initlcd
Cursor Off Noblink
Cls

'Zeitbasis
Config Timer0 = Timer , Prescale = 64
Enable Timer0
On Timer0 Tick
Enable Interrupts


Dim Displaypuffer1 As String * 16
Dim Displaypuffer1_char(16) As Byte At Displaypuffer1 Overlay
Dim Displaypuffer2 As String * 16
Dim Display_cnt As Byte
Displaypuffer1 = "- Test -12....78"

Dim Temp As Byte
Dim Zaehler As Long
Dim Temp2 As String * 16


Declare Sub Lcdwritebyte(byval _byte As Byte)
Declare Sub Lcd_write(byval _text As String)


Do
Incr Zaehler
Temp2 = Str(zaehler)
Call Lcd_write(temp2)
Waitms 50
Loop
End


Tick:
Display_cnt = Display_cnt And 15
Incr Display_cnt

Displaypuffer1 = Displaypuffer2 'auskommentieren für konstanten Displayinhalt

Temp = Displaypuffer1_char(display_cnt)
Call Lcdwritebyte(temp)
Return


Sub Lcdwritebyte(_byte As Byte)
Local _temp As Byte
Lcd_en = 0 : Lcd_rs = 1
Lcd_data = Lcd_data And &H0F
_temp = _byte And &HF0
Lcd_data = Lcd_data Or _temp

Lcd_en = 1 : !nop : Lcd_en = 0

Lcd_data = Lcd_data And &H0F
Shift _byte , Left , 4
_temp = _byte And &HF0
Lcd_data = Lcd_data Or _temp

Lcd_en = 1 : !nop : Lcd_en = 0
End Sub


Sub Lcd_write(byval _text As String )
Local _pos As Byte
_pos = 16 - Len(_text)
Displaypuffer2 = _text + Space(_pos)
End Sub




Wie lassen sich diese falschen Ausgaben vermeiden?

Danke für Eure Hilfe
-Limloz-

peterfido
28.06.2011, 16:56
Im Timerinterrupt gehören keine LCD (und Print) -Anweisungen. Auch das Aufrufen einer Sub ist da fehl am Platze. Wenn die Werte sich schneller ändern, als das Display es anzeigen kann und die Werte nicht anderweitig gespeichert / verarbeitet werden, kann die Abfrage der Werte auch zyklisch (der Displaygeschwindigkeit angepasst) erfolgen.