PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LCD-Display 8bit mit busy-flag-Abfrage



BoGe-Ro
25.08.2010, 09:27
Hallo Forum,

ich verwende ein 4*20 Zeichen Dispay mit HD44780-Controller im 8bit-Modus.

Da die Ausgabe mit LCD "irgendwas" zu lange dauert, möchte ich notwendige Ausgaben in ein Variablenpuffer legen und in Ruhezeiten ausgeben.

Um auch in diesen Ruhezeiten schnell zu sein möchte ich das Busy-Flag abfragen und nicht einfach nur warten.

Leider werden nach der Busy-Flag-Abfrage nur noch abwechselnd volle Kästchen ($FF) und Leerzeichen ausgegeben.
Auch wird das Cls im Main-loop nach der ersten Busy-Flag-Abfrage nicht mehr ausgeführt.

Das Problem vermute ich in Datenrichtungsangabe, denn füge ich in der lcd_put()-Sub am Anfang ein DDRC = 1 ein, erhalte ich ebenfalls abwechselnde Kästchen





$regfile = "m128def.dat"
$crystal = 16000000
$framesize = 100
$swstack = 100
$hwstack = 100
$baud = 57600
'$sim



Testpin Alias Portf.4 : Config Testpin = Output : Testpin = 0
Declare Sub Lcd_put(_x As Byte)
Declare Sub Lcd_busy()


'################### LCD Settings #############################################
Dim Lcd_textbuffer As String * 20 , Lcd_textbuffer1 As String * 20
Config Lcdpin = Pin , Port = Portc , E = Portd.5 , Rs = Portg.3
Config Lcd = 20 * 4
Config Portg.4 = Output

Lcd_enable Alias Portd.5
Lcd_rs Alias Portg.3
Lcd_rw Alias Portg.4
Lcd_data Alias Portc
Cursor Off
Initlcd
Cls

Dim Lcd_zeile1 As String * 20
Dim Lcd_zeile1_char(20) As Byte At Lcd_zeile1 Overlay

Dim Lcd_zeile2 As String * 20
Dim Lcd_zeile2_char(20) As Byte At Lcd_zeile2 Overlay

Dim Lcd_zeile3 As String * 20
Dim Lcd_zeile3_char(20) As Byte At Lcd_zeile3 Overlay

Dim Lcd_zeile4 As String * 20
Dim Lcd_zeile4_char(20) As Byte At Lcd_zeile4 Overlay

Dim I As Byte


Do
Cls
Lcd_zeile1 = "0123456789"
'input Lcd_zeile1

For I = 1 To Len(lcd_zeile1)
toggle Testpin
Call Lcd_put(lcd_zeile1_char(i))
toggle Testpin
Waitms 100
Next I
Decr I
Lowerline : Lcd "ready, " ; I ; " zeichen"
Wait 5
Loop
End



Sub Lcd_put(_x As Byte)
'DDRC = 1
Lcd_data = _x
Lcd_rw = 0
Lcd_rs = 1
!nop
!nop
Lcd_enable = 1
!nop
!nop
Lcd_enable = 0
Call Lcd_busy()
End Sub




Sub Lcd_busy
Ddrc = 0
Portc = 1
Lcd_rs = 0
Lcd_rw = 1
!nop
!nop
Do
Toggle Lcd_enable
!nop
!nop
Loop Until Pinc.7 = 0
Ddrc = 1
End Sub



Was mache ich verkehrt? oder besser, was wäre besser?

Gruß und Dank

BoGe-Ro

BoGe-Ro
25.08.2010, 13:13
die lösung war einfach - mit toggle hats dann geklappt.

hier der aktuelle Programm-Code mit Kommentaren


$regfile = "m128def.dat"
$crystal = 16000000
$framesize = 100
$swstack = 100
$hwstack = 100
$baud = 57600
'$sim

Luefter_pwm Alias Portb.4 : Config Luefter_pwm = Output : Luefter_pwm = 0
Testpin Alias Portf.4 : Config Testpin = Output : Testpin = 0

Declare Sub Lcd_ausgabe()
Declare Sub Lcd_put(_x As Byte)
Declare Sub Lcd_cls()
Declare Sub Lcd_print(byval _x As Byte , Byval _y As Byte , Byval _text As String)

'################### LCD Settings #############################################
Dim Lcd_textbuffer As String * 20 , Lcd_textbuffer1 As String * 20
Config Lcdpin = Pin , Port = Portc , E = Portd.5 , Rs = Portg.3
Config Lcd = 20 * 4
Config Portg.4 = Output

Lcd_enable Alias Portd.5
Lcd_rs Alias Portg.3
Lcd_rw Alias Portg.4
Lcd_data Alias Portc
Cursor Off
Initlcd
Deflcdchar 0 , 4 , 14 , 31 , 4 , 4 , 4 , 4 , 32 ' Pfeil hoch
Deflcdchar 1 , 4 , 4 , 4 , 4 , 31 , 14 , 4 , 32 ' Pfeil runter
Deflcdchar 2 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 32 ' Pause-Zeichen
Deflcdchar 3 , 16 , 24 , 28 , 30 , 28 , 24 , 16 , 32 ' Play-Zeichen
Deflcdchar 4 , 32 , 32 , 31 , 31 , 31 , 31 , 31 , 32 ' Stop-Zeichen
Deflcdchar 5 , 32 , 32 , 32 , 32 , 12 , 10 , 12 , 10 ' kleines R
Deflcdchar 6 , 32 , 32 , 32 , 32 , 10 , 10 , 12 , 10 ' kleines K
Deflcdchar 7 , 32 , 32 , 32 , 32 , 8 , 8 , 8 , 14 ' kleines L
Cls


Dim Lcd_4zeilen As String * 80
Dim Lcd_4zeilen_char(80) As Byte At Lcd_4zeilen Overlay


Dim I As Byte
Dim Text As String * 20


Do

Call Lcd_print(1 , 1 , "Das ist die 1. Zeile")
Call Lcd_print(1 , 2 , "Das ist die 2. Zeile")
Text = "T" + Chr(5) + "= 5 " + Chr($df) + "C"
Call Lcd_print(1 , 3 , Text)
Call Lcd_print(1 , 4 , "Das ist die 4. Zeile")

Toggle Testpin
Call Lcd_cls()
'Cls
Toggle Testpin

Call Lcd_ausgabe
Waitms 100
Loop
End


Sub Lcd_ausgabe
Local _i As Byte
For _i = 1 To 80 : Call Lcd_put(lcd_4zeilen_char(_i)) : Next _i
End Sub


Sub Lcd_put(_x As Byte)
' Dauer für die Ausgabe von 20 Zeichen: 1,1ms
' 80 Zeichen: 3,1ms (bei 27 nop's Pause)
' mit Lcd Chr(_x) in der Funktion 20 Z: 23ms

If _x = 0 Then _x = $a0 'chr(0) auf Leerzeichen mappen
Lcd_data = _x 'Datenbyte auf Bus legen
Lcd_rw = 0 'Schreibbefehl
Lcd_rs = 1 'Datenpuffer
!nop
!nop
Lcd_enable = 1
!nop
!nop
Lcd_enable = 0


'auf Display-Ready warten
Toggle Ddrc 'Busrichtung lesen
Lcd_rw = 1 'Lesebefehl
Lcd_rs = 0 'Steuerpuffer
!nop
!nop
Do
Toggle Lcd_enable
!nop
Loop Until Pinc.7 = 0 'auf busy-flag warten
Toggle Ddrc 'Busrichtung schreiben
End Sub



Sub Lcd_print(byval _x As Byte , Byval _y As Byte , _text As String * 20)
'Z1S1 = 1-20
'Z2S1 = 41-60
'Z3S1 = 21-40
'Z4S1 = 61-80
Local _position As Byte
Local _anzahl As Byte
Local _i As Byte
Select Case _y
Case 1 : _position = 0
Case 2 : _position = 40
Case 3 : _position = 20
Case 4 : _position = 60
End Select
_position = _position + _x
_anzahl = Len(_text)
_i = Memcopy(_text , Lcd_4zeilen_char(_position) , _anzahl)
End Sub


Sub Lcd_cls()
'Dauer knapp 1.6ms
'Bsacom CLS dauert 5.2ms
Lcd_data = 1 'Datenbyte auf Bus legen
Lcd_rw = 0 'Schreibbefehl
Lcd_rs = 0 'Datenpuffer
!nop
!nop
Lcd_enable = 1
!nop
!nop
Lcd_enable = 0

'auf Display-Ready warten
Toggle Ddrc 'Busrichtung lesen
Lcd_rw = 1 'Lesebefehl
Lcd_rs = 0 'Steuerpuffer
!nop
!nop
Do
Toggle Lcd_enable
!nop
Loop Until Pinc.7 = 0 'auf busy-flag warten
Toggle Ddrc 'Busrichtung schreiben
End Sub

linux_80
25.08.2010, 13:32
Hallo,

hast du beim 1. Versuch da wirklich DDRC = 1 angegeben, dann klappt das nicht, da muss 0 oder 255 hin, damit alle Bits rein oder raus zeigen.
Geht dann auch schneller als mit Toggle, denn da wird das Register erst noch ausgelesen, und dann umgedreht.

BoGe-Ro
25.08.2010, 13:49
ohhh, wie peinlich ;-)

du hast recht, alles auf 1 ist ja wirklich 255 und nicht 1

Habs gerade nochmal geändert. Hier also der jetzt aktuelle Code.
Zeitlich wirds schneller, aber im unmessbaren Bereich.
Hab noch eine Funktion zum Zeilen-Löschen reingepackt.
Morgen wirds dann in das richtige Programm eingefügt - mal schauen, welche Funktionen dabei noch notwendig werden

Aber besten Dank



$regfile = "m128def.dat"
$crystal = 16000000
$framesize = 100
$swstack = 100
$hwstack = 100
$baud = 57600
'$sim

Luefter_pwm Alias Portb.4 : Config Luefter_pwm = Output : Luefter_pwm = 0
Testpin Alias Portf.4 : Config Testpin = Output : Testpin = 0

Declare Sub Lcd_ausgabe()
Declare Sub Lcd_put(_x As Byte)
Declare Sub Lcd_cls()
Declare Sub Lcd_clc(byval _y As Byte) 'Clear Column
Declare Sub Lcd_print(byval _x As Byte , Byval _y As Byte , Byval _text As String)

'################### LCD Settings #############################################
Dim Lcd_textbuffer As String * 20 , Lcd_textbuffer1 As String * 20
Config Lcdpin = Pin , Port = Portc , E = Portd.5 , Rs = Portg.3
Config Lcd = 20 * 4
Config Portg.4 = Output

Lcd_enable Alias Portd.5
Lcd_rs Alias Portg.3
Lcd_rw Alias Portg.4
Lcd_data Alias Portc
Cursor Off
Initlcd
Deflcdchar 0 , 4 , 14 , 31 , 4 , 4 , 4 , 4 , 32 ' Pfeil hoch
Deflcdchar 1 , 4 , 4 , 4 , 4 , 31 , 14 , 4 , 32 ' Pfeil runter
Deflcdchar 2 , 27 , 27 , 27 , 27 , 27 , 27 , 27 , 32 ' Pause-Zeichen
Deflcdchar 3 , 16 , 24 , 28 , 30 , 28 , 24 , 16 , 32 ' Play-Zeichen
Deflcdchar 4 , 32 , 32 , 31 , 31 , 31 , 31 , 31 , 32 ' Stop-Zeichen
Deflcdchar 5 , 32 , 32 , 32 , 32 , 12 , 10 , 12 , 10 ' kleines R
Deflcdchar 6 , 32 , 32 , 32 , 32 , 10 , 10 , 12 , 10 ' kleines K
Deflcdchar 7 , 32 , 32 , 32 , 32 , 8 , 8 , 8 , 14 ' kleines L
Cls


Dim Lcd_4zeilen As String * 80
Dim Lcd_4zeilen_char(80) As Byte At Lcd_4zeilen Overlay


Dim I As Byte
Dim Text As String * 20


Do
Incr I : If I = 5 Then I = 1
Call Lcd_print(1 , 1 , "Das ist die 1. Zeile")
Call Lcd_print(1 , 2 , "Das ist die 2. Zeile")
Text = "T" + Chr(5) + "= 5 " + Chr($df) + "C"
Call Lcd_print(1 , 3 , Text)
Call Lcd_print(1 , 4 , "Das ist die 4. Zeile")


'Call Lcd_cls()
'Call Lcd_clc(i)
'Cls

Toggle Testpin
Call Lcd_ausgabe
Toggle Testpin
Waitms 100
Loop
End


Sub Lcd_ausgabe
Local _i As Byte
For _i = 1 To 80 : Call Lcd_put(lcd_4zeilen_char(_i)) : Next _i
End Sub


Sub Lcd_put(_x As Byte)
' Dauer für die Ausgabe von 20 Zeichen: 1,1ms
' 80 Zeichen: 3,1ms (bei 27 nop's Pause)
' mit Lcd Chr(_x) in der Funktion 20 Z: 23ms

If _x = 0 Then _x = $a0 'chr(0) auf Leerzeichen mappen
Ddrc = 255 'Busrichtung schreiben
Lcd_data = _x 'Datenbyte auf Bus legen
Lcd_rw = 0 'Schreibbefehl
Lcd_rs = 1 'Datenpuffer
!nop
!nop
Lcd_enable = 1
!nop
!nop
Lcd_enable = 0


'auf Display-Ready warten
Ddrc = 0 'Busrichtung lesen
Lcd_rw = 1 'Lesebefehl
Lcd_rs = 0 'Steuerpuffer
!nop
!nop
Do
Toggle Lcd_enable
!nop
Loop Until Pinc.7 = 0 'auf busy-flag warten
Ddrc = 255 'Busrichtung schreiben
End Sub



Sub Lcd_print(byval _x As Byte , Byval _y As Byte , _text As String * 20)
'Z1S1 = 1-20
'Z2S1 = 41-60
'Z3S1 = 21-40
'Z4S1 = 61-80
Local _position As Byte
Local _anzahl As Byte
Local _i As Byte
Select Case _y
Case 1 : _position = 0
Case 2 : _position = 40
Case 3 : _position = 20
Case 4 : _position = 60
End Select
_position = _position + _x
_anzahl = Len(_text)
_i = Memcopy(_text , Lcd_4zeilen_char(_position) , _anzahl)
End Sub


Sub Lcd_cls()
'Dauer knapp 1.6ms
'Bsacom CLS dauert 5.2ms
Lcd_data = 1 'Datenbyte auf Bus legen
Lcd_rw = 0 'Schreibbefehl
Lcd_rs = 0 'Datenpuffer
!nop
!nop
Lcd_enable = 1
!nop
!nop
Lcd_enable = 0

'auf Display-Ready warten
Toggle Ddrc 'Busrichtung lesen
Lcd_rw = 1 'Lesebefehl
Lcd_rs = 0 'Steuerpuffer
!nop
!nop
Do
Toggle Lcd_enable
!nop
Loop Until Pinc.7 = 0 'auf busy-flag warten
Toggle Ddrc 'Busrichtung schreiben
End Sub



Sub Lcd_clc(byval _y As Byte) 'Clear Column
'Dauer: 37µs
Local _position As Byte
Local _i As Byte
Local _zeichen As String * 1 : _zeichen = " "
Select Case _y
Case 1 : _position = 0
Case 2 : _position = 40
Case 3 : _position = 20
Case 4 : _position = 60
End Select
Incr _position
_i = Memcopy(_zeichen , Lcd_4zeilen_char(_position) , 20 , 2)
End Sub