Bascom 3 Wire LCD mit Schieberegister

avrkarl

Neues Mitglied
4 Mai 2011
28
0
0
Sprachen
Die Ansteuerung eines LCDs mit BASCOM ist wunderbar leicht. Manchmal hat man jedoch nicht so viele Ausgänge mehr am µC frei und man muss andere Wege suchen. Jetzt hat Cassio hier kürzlich eine sehr ausgefeilte Methode vorgestellt, ein Display über I2C anzusteuern. Aus praktischem und auch akademischem Interesse habe ich mich mal daran versucht, so eine Ansteuerung über ein Schieberegister zu bewerkstelligen. Herausgekommen ist der nachfolgende Code, der nur noch drei Leitung ("3 Wire") zur Steuerung des LCDs im 4 Bit Modus benötigt. Es wäre sogar möglich, mit nur 2 Leitungen auszukommen, aber damit habe ich mich (noch) nicht befasst.

Der Code ist eher praktischer Natur und berücksichtigt nur 16x2 LCDs im 4 Bit Modus, R/W wird nicht unterstützt. Eine Anpassung an 16x4 ist aber ohne weiteres möglich. Nachgebildet habe ich die folgenden BASCOM Befehle:

Initlcd > Init_3w
Cls > Cls_3w
Lcd x > Lcd_3w("MeinText")
Locate y, x > Locate_3w(y,x)

Als Schieberegister kommt ein günstiges 74HC595 zum Einsatz. Die Ansteuerung ist im Code angegeben.

Im Prinzip ist der Code nur eine Abarbeitung des HD44780-Datenblatts. Das Schieberegister wird über SHIFTOUT mit Daten gefüllt. Die ersten beiden Bits kontrollieren RS und E.

RS=0 : Befehl wird empfangen / RS=1 Daten werden empfangen. E(nable)=1/0 ist selbsterklärend.
Nachdem das Register mit Daten gefüllt ist, müssen diese noch über Q0....Q5 ausgegeben werden. Das erledigt die Befehlsfolge:

Code:
Rck = 0
Rck = 1
Rck = 0

Im 4-Mit Modus müssen die beiden Nibbles des Command- oder Data-Bytes nacheinander übertragen werden. Dazu muss man das Byte mit SWAP "herumdrehen" und nur die ersten 4 Bits übertragen. Die zweite Hälfte des Bytes wird ohne SWAP übertragen. Dadurch das RS und E ebenfalls gesetzt werden müssen, werden bei jedem Vorgang 2 Bits + Nibble = 6 Bits übertragen.

Nach dem einschalten ist ein LCD immer im 8 Bit Modus, deshalb werden bei den ersten 4 Befehlen im Init nur 4 Bits übertragen. Das aber nur am Rande.

Der Code ist kurz getestet, nicht unbedingt optimiert und enthält nicht alle Befehle, die BASCOM für die LCD-Steuerung anbietet. Vielleicht findet ihn der ein oder andere jedoch trotzdem nützlich.

Code:
'##################################### 3 WIRE LCD BASCOM ###########################
' ATmega
' 74HC595 SHIFT REGISTER
' 2x16 LCD (HD44780)
' + 5V
'
'             74HC595
'             ________
'             |      |----1-Q1~~~~DB6 LCD 13
'             |      |----2-Q2~~~~DB5 LCD 12
'     Vcc-16--|      |----3-Q3~~~~DB4 LCD 11
'     GND--8--|      |----4-Q4~~~~RS  LCD  4
'             |      |----5-Q5~~~~E   LCD  5
' Vcc~~MR-10--|      |----6-Q6
' GND~~OE-13--|      |----7-Q7
'             |      |---15-Q0~~~~DB7 LCD 14
'      Q7S-9--|      |
'             |      |---11-SHCP~~PB1 (Clk) µC
'             |      |---12-STCP~~PB2 (Rck) µC
'             |      |---14-DS~~~~PB0 (Dat) µC
'             --------
'
' LCD: 1: GND / 2: VDD / 3: VEE / 4: RS = Q4 / 5: RW = GND / 6: E=Q5 .... 11: DB4 = Q3 / 12: DB5 = Q2 / 13: DB6 = Q1 / 14: DB7 = Q0




$regfile = "m8def.dat"
$crystal = 3686400
$baud = 9600

$hwstack = 64
$swstack = 64
$framesize = 64

'#####################################

Config Portb.0 = Output
Config Portb.1 = Output
Config Portb.2 = Output

Dat Alias Portb.0
Clk Alias Portb.1
Rck Alias Portb.2

'#####################################

Dim Rse As Byte                                             'RS and E
Dim I As Byte
Dim Lcd_string As String * 16
Dim Character(17) As Byte At Lcd_string Overlay

'#####################################

Declare Sub Write_lcd_cmd8(byval Cmd As Byte)               'Write command
Declare Sub Write_lcd_cmd(byval Cmd As Byte)                'Write command in 4 Bit mode
Declare Sub Write_lcd_txt(byval Txt As Byte)                'LCD Init
Declare Sub Init_3w                                         'LCD Cls
Declare Sub Cls_3w
Declare Sub Lcd_3w(byval Lcdstring As String)               'LCD output
Declare Sub Locate_3w(byval Y As Byte , Byval X As Byte)    'LCD Locate

'#####################################

Call Init_3w
Call Cls_3w

'#####################################  Test Test Test

Do

   Call Locate_3w(1 , 1) : Call Lcd_3w( "Hello World")
   Wait 1
   Call Locate_3w(2 , 1) : Call Lcd_3w( "Second Line")
   Wait 2
   Call Cls_3w
   Call Locate_3w(1 , 1) : Call Lcd_3w( "1")
   Wait 1
   Call Locate_3w(1 , 2) : Call Lcd_3w( "2")
   Wait 1
   Call Locate_3w(1 , 3) : Call Lcd_3w( "3")
   Wait 1
   Call Locate_3w(1 , 3) : Call Lcd_3w( "C")
   Wait 1
   Call Locate_3w(1 , 2) : Call Lcd_3w( "B")
   Wait 1
   Call Locate_3w(1 , 1) : Call Lcd_3w( "A")
   Wait 2
   Call Cls_3w
   Call Locate_3w(1 , 1) : Call Lcd_3w( "1234567890123456")
   Call Locate_3w(2 , 1) : Call Lcd_3w( "ABCDEFGHIJKLMNOP")
   Wait 2
   Call Cls_3w
   Wait 1

Loop

'#####################################    Write LCD Command  (8 Bit Mode)

Sub Write_lcd_cmd8(byval Cmd As Byte)

   Rse = &B01                                               'E=1 Rs=0

   For I = 0 To 1

      Shiftout Dat , Clk , Rse , 2 , 2                      'send Rs and E
      Shiftout Dat , Clk , Cmd , 2 , 4                      'send upper nibble

      Rck = 0
      Rck = 1
      Rck = 0

      Rse = &B00                                            'E=0 Rs=0

   Next

End Sub

'#####################################   Write LCD Command  (4 Bit Mode)

Sub Write_lcd_cmd(byval Cmd As Byte)

   Local Cmd2 As Byte

   Cmd2 = Cmd

   Swap Cmd

   Rse = &B01                                               'E=1 Rs=0

   For I = 0 To 1                                           'upper nibble

      Shiftout Dat , Clk , Rse , 2 , 2                      'send Rs and E
      Shiftout Dat , Clk , Cmd , 2 , 4                      'send nibble

      Rck = 0
      Rck = 1
      Rck = 0

      Rse = &B00                                            'E=0 Rs=0

   Next

   Rse = &B01

   For I = 0 To 1                                           'lower nibble

      Shiftout Dat , Clk , Rse , 2 , 2                      'send Rs and E
      Shiftout Dat , Clk , Cmd2 , 2 , 4                     'send nibble

      Rck = 0
      Rck = 1
      Rck = 0

      Rse = &B00                                            'E=0 Rs=0

   Next

End Sub

'#####################################   Write LCD Character  (4 Bit Mode)

Sub Write_lcd_txt(byval Txt As Byte)

   Local Txt2 As Byte

   Txt2 = Txt

   Swap Txt

   Rse = &B11                                               'E=1 Rs=1

   For I = 0 To 1                                           'upper nibble

      Shiftout Dat , Clk , Rse , 2 , 2                      'send Rs and E
      Shiftout Dat , Clk , Txt , 2 , 4                      'send nibble

      Rck = 0
      Rck = 1
      Rck = 0

      Rse = &B10                                            'E=0 Rs=1

   Next

   Rse = &B11                                               'E=1 Rs=1

   For I = 0 To 1                                           'lower nibble

      Shiftout Dat , Clk , Rse , 2 , 2                      'send Rs and E
      Shiftout Dat , Clk , Txt2 , 2 , 4                     'send nibble

      Rck = 0
      Rck = 1
      Rck = 0

      Rse = &B10                                            'E=0 Rs=1

  Next

End Sub

'#####################################    Init LCD

Sub Init_3w

   Waitms 20
   Call Write_lcd_cmd8(&B0000_0011)                         'Init 4 Bit 1x
   Waitms 5
   Call Write_lcd_cmd8(&B0000_0011)                         '2x
   Waitms 5
   Call Write_lcd_cmd8(&B0000_0011)                         '3x
   Waitms 5
   Call Write_lcd_cmd8(&B0000_0010)                         '4 Bit Mode
   Waitms 5
   Call Write_lcd_cmd(&B0010_1000)                          '4 Bit / 2 Lines /  5x8 Font
   Waitms 5
   Call Write_lcd_cmd(&B0000_1100)                          'Display ON / Cursor OFF / Blinking OFF
   Waitms 5
   Call Write_lcd_cmd(&B0000_0100)                          'Increment /  Shift OFF
   Waitms 5

End Sub

'#####################################   CLS

Sub Cls_3w

   Call Write_lcd_cmd(&B0000_0001)
   Waitms 5

End Sub

'#####################################  LOCATE  (y,x)

Sub Locate_3w(byval Y As Byte , Byval X As Byte)

   X = X - 1

   Call Write_lcd_cmd(&B0000_0010)                          'Cursor home
   Waitms 5

   If Y = 1 Then
      Call Write_lcd_cmd(&H80 + X)                          '1st line
   Elseif Y = 2 Then
      Call Write_lcd_cmd(&Hc0 + X)                          '2nd line
   End If

End Sub

'#####################################  LCD   (String)

Sub Lcd_3w(byval Lcdstring As String)

   Local Strlen As Byte
   Local A As Byte

   Strlen = Len(lcdstring)
   Lcd_string = Lcdstring

   For A = 1 To Strlen
      Call Write_lcd_txt(character(a))
   Next

End Sub

'#####################################
 

Cassio

Aktives Mitglied
29 Okt 2008
4,027
17
38
Region Hannover
Sprachen
  1. BascomAVR
Hallo AVRkarl!

Das ist natürlich auch eine Möglichkeit Pins am Controller zu sparen, oder einen kleinen AVR mit einem LCD zu betreiben. :)

Glückwunsch, zur fertigen Idee! :flowers:


Ich habe mir jetzt nicht alle Routinen im Detail angesehen, aber ich gehe davon aus, dass du es schon getestet haben wirst. ;)
Die ein oder andere Optimierung habe ich beim "Durchscrollen" zwar schon entdeckt, aber darum geht es jetzt ja nicht!

Viel Spaß weiterhin,
Cassio
 

avrkarl

Neues Mitglied
4 Mai 2011
28
0
0
Sprachen
Hallo Cassio,

vielen Dank für die Blumen. :)

Etwas Optimierungsbedarf gibt es sicherlich. Habe mich mal dran gemacht und 2 "For Next" wegreduziert, spart schon ein paar %. Man könnte die einzelnen Subs sicherlich auch noch zusammenfassen.

Code:
'##################################### 3 WIRE LCD BASCOM ###########################
' ATmega
' 74HC595 SHIFT REGISTER
' 2x16 LCD (HD44780)
' + 5V
'
'             74HC595
'             ________
'             |      |----1-Q1~~~~DB6 LCD 13
'             |      |----2-Q2~~~~DB5 LCD 12
'     Vcc-16--|      |----3-Q3~~~~DB4 LCD 11
'     GND--8--|      |----4-Q4~~~~RS  LCD  4
'             |      |----5-Q5~~~~E   LCD  5
' Vcc~~MR-10--|      |----6-Q6
' GND~~OE-13--|      |----7-Q7
'             |      |---15-Q0~~~~DB7 LCD 14
'      Q7S-9--|      |
'             |      |---11-SHCP~~PB1 (Clk) µC
'             |      |---12-STCP~~PB2 (Rck) µC
'             |      |---14-DS~~~~PB0 (Dat) µC
'             --------
'
' LCD: 1: GND / 2: VDD / 3: VEE / 4: RS = Q4 / 5: RW = GND / 6: E=Q5 .... 11: DB4 = Q3 / 12: DB5 = Q2 / 13: DB6 = Q1 / 14: DB7 = Q0
'
'##################################### 3 WIRE LCD BASCOM ###########################



$regfile = "m8def.dat"
$crystal = 3686400
$baud = 9600

$hwstack = 64
$swstack = 64
$framesize = 64

'#####################################

Config Portb.0 = Output
Config Portb.1 = Output
Config Portb.2 = Output

Dat Alias Portb.0
Clk Alias Portb.1
Rck Alias Portb.2

'#####################################

Dim Rse As Byte                                             'RS and E
Dim I As Byte
Dim Lcd_string As String * 16
Dim Character(17) As Byte At Lcd_string Overlay

'#####################################

Declare Sub Write_lcd_cmd8(byval Cmd As Byte)               'Write command
Declare Sub Write_lcd_cmd(byval Cmd As Byte)                'Write command in 4 Bit mode
Declare Sub Write_lcd_txt(byval Txt As Byte)                'LCD Init
Declare Sub Init_3w                                         'LCD Cls
Declare Sub Cls_3w
Declare Sub Lcd_3w(byval Lcdstring As String)               'LCD output
Declare Sub Locate_3w(byval Y As Byte , Byval X As Byte)    'LCD Locate

'#####################################

Call Init_3w
Call Cls_3w

'#####################################  Test Test Test

Do

   Call Locate_3w(1 , 1) : Call Lcd_3w( "Hello World")
   Wait 1
   Call Locate_3w(2 , 1) : Call Lcd_3w( "Second Line")
   Wait 2
   Call Cls_3w
   Call Locate_3w(1 , 1) : Call Lcd_3w( "1")
   Wait 1
   Call Locate_3w(1 , 2) : Call Lcd_3w( "2")
   Wait 1
   Call Locate_3w(1 , 3) : Call Lcd_3w( "3")
   Wait 1
   Call Locate_3w(1 , 3) : Call Lcd_3w( "C")
   Wait 1
   Call Locate_3w(1 , 2) : Call Lcd_3w( "B")
   Wait 1
   Call Locate_3w(1 , 1) : Call Lcd_3w( "A")
   Wait 2
   Call Cls_3w
   Call Locate_3w(1 , 1) : Call Lcd_3w( "1234567890123456")
   Call Locate_3w(2 , 1) : Call Lcd_3w( "ABCDEFGHIJKLMNOP")
   Wait 2
   Call Cls_3w
   Wait 1

Loop

'#####################################    Write LCD Command  (8 Bit Mode)

Sub Write_lcd_cmd8(byval Cmd As Byte)

   Rse = &B01                                               'E=1 Rs=0

   For I = 0 To 1

      Shiftout Dat , Clk , Rse , 2 , 2                      'send Rs and E
      Shiftout Dat , Clk , Cmd , 2 , 4                      'send lower nibble

      Rck = 0
      Rck = 1
      Rck = 0

      Toggle Rse.0                                          'E=0 Rs=0

   Next

End Sub

'#####################################   Write LCD Command  (4 Bit Mode)
' I=0: upper nibble / RS=0 / E=1
' I=1: upper nibble / RS=0 / E=0
' I=2: lower nibble / RS=0 / E=1
' I=3: lower nibble / RS=0 / E=0

Sub Write_lcd_cmd(byval Cmd As Byte)

   Swap Cmd
   Rse = &B01                                               'E=1 Rs=0

   For I = 0 To 3

      If I = 2 Then Swap Cmd

      Shiftout Dat , Clk , Rse , 2 , 2                      'send Rs and E
      Shiftout Dat , Clk , Cmd , 2 , 4                      'send nibble

      Rck = 0
      Rck = 1
      Rck = 0

      Toggle Rse.0                                          'E=0 Rs=0

   Next


End Sub

'#####################################   Write LCD Character  (4 Bit Mode)
' I=0: upper nibble / RS=1 / E=1
' I=1: upper nibble / RS=1 / E=0
' I=2: lower nibble / RS=1 / E=1
' I=3: lower nibble / RS=1 / E=0


Sub Write_lcd_txt(byval Txt As Byte)

   Swap Txt
   Rse = &B11                                               'E=1 Rs=1

   For I = 0 To 3

      If I = 2 Then Swap Txt

      Shiftout Dat , Clk , Rse , 2 , 2                      'send Rs and E
      Shiftout Dat , Clk , Txt , 2 , 4                      'send nibble

      Rck = 0
      Rck = 1
      Rck = 0

      Toggle Rse.0                                          'E=0 Rs=1

   Next Asc

End Sub

'#####################################    Init LCD

Sub Init_3w

   Waitms 20
   Call Write_lcd_cmd8(&B0000_0011)                         'Init 4 Bit 1x
   Waitms 5
   Call Write_lcd_cmd8(&B0000_0011)                         '2x
   Waitms 5
   Call Write_lcd_cmd8(&B0000_0011)                         '3x
   Waitms 5
   Call Write_lcd_cmd8(&B0000_0010)                         '4 Bit Mode
   Waitms 5
   Call Write_lcd_cmd(&B0010_1000)                          '4 Bit / 2 Lines /  5x8 Font
   Waitms 5
   Call Write_lcd_cmd(&B0000_1100)                          'Display ON / Cursor OFF / Blinking OFF
   Waitms 5
   Call Write_lcd_cmd(&B0000_0100)                          'Increment /  Shift OFF
   Waitms 5

End Sub

'#####################################   CLS

Sub Cls_3w

   Call Write_lcd_cmd(&B0000_0001)
   Waitms 5

End Sub

'#####################################  LOCATE  (y,x)

Sub Locate_3w(byval Y As Byte , Byval X As Byte)

   Decr X

   Call Write_lcd_cmd(&B0000_0010)                          'Cursor home
   Waitms 5

   If Y = 1 Then
      Call Write_lcd_cmd(&H80 + X)                          '1st line
   Elseif Y = 2 Then
      Call Write_lcd_cmd(&Hc0 + X)                          '2nd line
   End If

End Sub

'#####################################  LCD   (String)

Sub Lcd_3w(byval Lcdstring As String)

   Local Strlen As Byte
   Local A As Byte

   Strlen = Len(lcdstring)
   Lcd_string = Lcdstring

   For A = 1 To Strlen
      Call Write_lcd_txt(character(a))
   Next

End Sub

'#####################################
 

Cassio

Aktives Mitglied
29 Okt 2008
4,027
17
38
Region Hannover
Sprachen
  1. BascomAVR
Hallo AVRKarl!

Gern geschehen, mit den Blumen! :)

Hast du eine Möglichkeit die Ausgabe der Daten zu messen, wie z.B. mit einem Analyser?
So hätte man mal einen Anhaltswert, wie schnell das Ganze wirklich ist.


Ach so.... Es ist jetzt zwar keine Optimierung im Sinne von Speicherplatz oder Geschwindigkeit, aber.....
Die ganzen CALL Aufrufe kannst du im Programm auch weglassen.
Das lässt sich dann beim Programmieren einfacher scheiben, weil die ganzen Klammern auch gleich entfallen. :wink:

Beispiel:
Aus der Anweisung mit CALL....
Code:
Call Locate_3w(1 , 1) 
Call Lcd_3w( "Hello World")

.....würde es dann ohne CALL so funktionieren:
Code:
Locate_3w 1 , 1 
Lcd_3w "Hello World"

Das sieht dann doch schon fast nach einem "Original-Befehl" in BASCOM aus. :)
Kannst es ja mal probieren.


Was mir dabei gerade noch einfällt....
Hast du eine Idee, wie man per BYVAL eine Variable z.B. als Long ODER String definieren könnte? :hmmmm:
Man muss ja dummerweise immer eine Angabe machen.
Schön wäre es aber, wenn man mit einer Variable flexibler wäre.
Ich schätze mal, da bleibt nur der Umweg über ein Overlay, oder ggf. mit direkten Speicheradressen.

Das "unangenehme" bei der Übergabe des Textes in die Sub ist nämlich, dass es immer ein String sein muss.
Binäre Werte, direkt aus den Variablen, kann man so leider nicht übergeben.
Hast du da vielleicht eine Idee?

Grüße,
Cassio
 

avrkarl

Neues Mitglied
4 Mai 2011
28
0
0
Sprachen
Hast du eine Möglichkeit die Ausgabe der Daten zu messen, wie z.B. mit einem Analyser?
So hätte man mal einen Anhaltswert, wie schnell das Ganze wirklich ist.

Hallo Cassio,

ja, habe ich. Zum einen mal "Hello World":

hellow.png

Hier wird zuerst Locate_3w angesprungen und der Befehl "Call Write_lcd_cmd(&B0000_0010)" ausgeführt. Danach wartet das Programm 1 ms (Achtung, anders als im angegebenen Code, da waren es noch 5 ms!) danach folgt das Kommando zur Positionsbestimmung und danach wird "Hello World" ausgegeben.

In Anlehnung an Deine Geschwindigkeitsmessung bei der I2C Routine habe ich die zwei Zeilen des LCDs mit jeweils 16x "X" gefüllt. Nach jeder kompletten Ausgabe wird 100 ms lang gewartet.

Code:
For I1 = 1 To 2
         For I2 = 1 To 16
            Call Locate_3w(i1 , I2) : Call Lcd_3w( "X")
         Next I2
Next I1

Das Ergebnis siehst Du hier:

timing1.png

Danke für den Hinweis mit dem Call. Ich hänge irgendwie an der Klammern...:D


Das "unangenehme" bei der Übergabe des Textes in die Sub ist nämlich, dass es immer ein String sein muss.
Binäre Werte, direkt aus den Variablen, kann man so leider nicht übergeben.
Hast du da vielleicht eine Idee?

Ich wüsste jetzt auch nur die OVERLAY-Variante. Vielleicht habe ich aber auch nicht richtig verstanden, was Du meinst? Bezieht es sich auf die Sub Lcd_3w(byval Lcd_string As String)?

Viele Grüße,
Sebastian
 

Cassio

Aktives Mitglied
29 Okt 2008
4,027
17
38
Region Hannover
Sprachen
  1. BascomAVR
Hallo Sebastian!

Na, das ist ja ein Service.....
Da bekommt man sogar gleich die Bilder vom LA geliefert. :)

Tja und die Geschwindigkeit kann sich auch sehen lassen! Ist doch ganz OK!
Wenn ich das jetzt richtig verstanden habe, dann werden 2x16 (32 Zeichen) von den Zeitmarken 13,040 bis 70,060 gesendet.
Die Differenz ist damit: 57,02 ms
Bei 32 Zeichen sind das dann... 57,02ms / 32 = ca. 1,8ms pro Zeichen
(nur zum Vergleich, bei 108 Zeichen wären es dann auch nur 192ms)

Na, ist doch völlig OK!
Wenn du deine Routinen (je nach Lust) noch auf den SPI-Bus umstellst, dann könnstest du die Signale sogar mit 2MHz ausgeben.
Ich weiß aber nicht, ob die CLCD`s das mitmachen. :hmmmm:


Auf alle Fälle finde ich deine Idee richtig gut!
Sie ist schnell, zuverlässig und obendrein noch günstiger, weil ein 74_595 wesentlich billiger ist, als ein PCF8574(A). :wink:

Da gratuliere ich doch noch mal! :adore:

Grüße,
Cassio


PS: Das Thema mit den Bytes oder String müssen wir jetzt hier nicht diskutieren.
Dafür ist mir dein gelungener Thread mit dem LCD zu wertvoll. ;)
 

avrkarl

Neues Mitglied
4 Mai 2011
28
0
0
Sprachen
Danke, Cassio.

Die Ausgabe ist nicht gerade superschnell, da nicht nur die beiden Nibbles übertragen werden, sondern auch noch E irgendwie gesetzt werden muss. Das ganz führt dann wieder zu der Frage, ob man nicht E separat schalten kann. Das kann man sogar, muss dann aber, wenn man mit nur 3 Leitungen auskommen will, Rck und Clk des Schieberegisters zusammenschalten. Keine Ahnung, wie viel schneller das dann alles wird. Evtl. probiere ich das mal aus. Viel interessanter finde ich die Fragestellung, ob man sogar nur mit 2 Pins auskommen kann. :cool:

Wie Du schon schreibst, es ist wahrscheinlich eher kontraproduktiv, die Geschwindigkeit noch weiter nach oben zu treiben, da das LCD irgendwann nicht mehr mitmacht. So habe ich z.B.versucht, in der vorletzten Sub die Pause nach Cursor Home zu verkürzen, was nur bis zu einem gewissen Grad funktioniert. Wartet man hier nicht lang genug, kommt nur noch Buchstabensalat auf dem LCD an.

Viele Grüße,
Sebastian
 

Cassio

Aktives Mitglied
29 Okt 2008
4,027
17
38
Region Hannover
Sprachen
  1. BascomAVR
Hallo Sebastian!

Nun ja, wenn du nur zwei Pins vom Controller verwenden möchtest, dann nimm doch einfach den TWI! :cool:


Was die Geschwindigkeit von CLCD`s betrifft, da hatte ich beim 27x4 anfangs ein paar Messungen gemacht.
Wie du auf dem nachfolgenden Bild oben rechts sehen kannst, beträgt sie Pause zwischen zwei Signalen auf der E-Leitung gerade mal 41,8 Mikrosekunden!
27x4_E_Timing.png
Da können wir mit unseren Bus-Systemen wohl noch etwas Gas geben. ;)
Allerdings kenne ich das mit den wirren Zeichen auch, wenn die Geschwindigkeit zu hoch war.

Hier jetzt mal das ganze INIT, wo auch sehr schön der "Umstieg" auf 4bit zu sehen ist.
27x4_INIT-Timing_am_uC.png


Ich überlege jetzt gerade, ob ich noch eine SPI-Version erstellen sollte. :hmmmm:
Eigentlich fehlt uns dass nun noch in der Sammlung. :)

Den E-Pin separat zu schalten (und zu führen) halt ich für keine sinnvolle Idee.
Was soll das bringen? Bevor die Datenbits nicht anliegen, kannst du den E-Pin sowie nicht "latchen".
Ich müsste mir dein Programm noch mal genauer ansehen, wann und wie du den E-Pin aktivierst.
Bei meinen Versuchen habe ich festgestellt dass es völlig ausreichend ist, wenn die Datenbits und das High für den E-Pin zeitgleich anliegen und dann der E-Pin alleine wieder Low geschaltet wird.
Du musst also nicht extra:
E-Pin High,
Datanbits anlegen
E-Pin Low

Es reicht auch vollkommen:
E-Pin High UND Datenbits anlegen,
E-Pin Low

Kannst es ja mal testen, wenn du es nicht sowieso schon so gemacht hast. :wink:

Grüße,
Cassio
 

avrkarl

Neues Mitglied
4 Mai 2011
28
0
0
Sprachen
Hallo Sebastian!

Nun ja, wenn du nur zwei Pins vom Controller verwenden möchtest, dann nimm doch einfach den TWI! :cool:

Ja, ja, ja, natürlich, mache ich. Das 2-Pin Schieberegister dient nur der Weiterbildung. ;)

Ich überlege jetzt gerade, ob ich noch eine SPI-Version erstellen sollte. :hmmmm:
Eigentlich fehlt uns dass nun noch in der Sammlung. :)

Gern, Cassio.

Habe gerade eine Lieferung bekommen, auf die ich sehr sehr lange gewartet habe, die muss erst einmal kontaktiert werden....meine LCD-Projekte müsssen deshalb ein wenig warten.

Den E-Pin separat zu schalten (und zu führen) halt ich für keine sinnvolle Idee.
Was soll das bringen? Bevor die Datenbits nicht anliegen, kannst du den E-Pin sowie nicht "latchen".
Ich müsste mir dein Programm noch mal genauer ansehen, wann und wie du den E-Pin aktivierst.
Bei meinen Versuchen habe ich festgestellt dass es völlig ausreichend ist, wenn die Datenbits und das High für den E-Pin zeitgleich anliegen und dann der E-Pin alleine wieder Low geschaltet wird.
Du musst also nicht extra:
E-Pin High,
Datanbits anlegen
E-Pin Low

Es reicht auch vollkommen:
E-Pin High UND Datenbits anlegen,
E-Pin Low

Kannst es ja mal testen, wenn du es nicht sowieso schon so gemacht hast. :wink:

Habe es mir nach Deinem Beitrag noch einmal durchdacht. Du hast recht. Auf das eine mehr durchgeschobene Bit kommt es nicht an.

Viele Grüße,
Sebastian
 

dino03

Aktives Mitglied
27 Okt 2008
6,756
18
38
Sprachen
  1. BascomAVR
  2. Assembler
Hallo zusammen,

Den E-Pin separat zu schalten (und zu führen) halt ich für keine sinnvolle Idee.
Was soll das bringen? Bevor die Datenbits nicht anliegen, kannst du den E-Pin sowie nicht "latchen".
Ich müsste mir dein Programm noch mal genauer ansehen, wann und wie du den E-Pin aktivierst.
Bei meinen Versuchen habe ich festgestellt dass es völlig ausreichend ist, wenn die Datenbits und das High für den E-Pin zeitgleich anliegen und dann der E-Pin alleine wieder Low geschaltet wird.
Du musst also nicht extra:
E-Pin High,
Datanbits anlegen
E-Pin Low

Es reicht auch vollkommen:
E-Pin High UND Datenbits anlegen,
E-Pin Low

Kannst es ja mal testen, wenn du es nicht sowieso schon so gemacht hast. :wink:
Habe es mir nach Deinem Beitrag noch einmal durchdacht. Du hast recht. Auf das eine mehr durchgeschobene Bit kommt es nicht an.
naja ... so würde ich das nicht sehen. Durch das toggeln des E-Bits kommt normalerweise die dreifache Bitmenge zustande:
- einmal alles mit E=0
- nochmal alles mit E=1
- und das dritte mal wieder mit E=0

selbst mit Cassio seinem Ansatz bleibt die doppelte Bitmenge übrig.

Man kann ja annehmen das jegliche Datenübertragung die zum Schieberegister kommt und dort übernommen wird auch durch einen E-Puls in das Display übertragen werden soll.

Ich hätte da für eine Beschleunigung und Entlastung des Atmels darum folgenden Vorschlag ...
1. Den Übernahmepuls für das Datenlatch wird direkt am Datenlatch angeschlossen (so wie jetzt)
2. Den Übernahmepuls vom Datenlatch mit einem RC-Netzwerk um etwa 100-200ns verzögern (Zwischensignal)
3. Dieses verzögerte Zwischensignal zu einem Puls von benötigter Länge formen (ein paar Microsekunden?).

Mit einem 7486 (4fach EXOR) und zwei RC-Gliedern sollte das zu machen sein. Dadurch spart man sich eine oder sogar zwei komplette Übertragungen der ganzen Bits. Allerdings erkauft mit dem Einsatz eines weiteren kleinen ICs und 4 Bauteilen. Dadurch wird auch wieder ein Bit bei der Übertragung für andere Zwecke frei weil der E-Puls ja nun vom Latch-Signal abgeleitet wird. Das geht aber normalerweise nur mit Displays mit einem E-Pin. Bei Displays mit 2 E-Pins müßte man mit einem Bit auswählen welchen der Pins man nun mit dem erzeugten E-Puls befeuern will.

Gruß
Dino
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)