Forum: Mikrocontroller und Digitale Elektronik LCD Display am PIC - verstädnisfrage BUS Übertragung


von Seier M. (Gast)


Lesenswert?

Hallo an alle,

Ich will zu Testzwecken einen ganz einfachen 2 Zeilen LCD Display 
benutzen. Ich weiß dass das Thema hier schon durch und durchgekaut 
worden ist, jedoch habe ich eine Frage für die ich noch mir keine gute 
Erklärung gefunden habe.

Seite 16
Und zwar orientiere ich mich an folgende Anleitung: 
http://www.stefan-buchgeher.info/elektronik/lcd/lcd_doku.pdf

Es wird kein Interface(I2C, SPI, Uart..) benutzt. Das Display kommt mit 
seinen 4 Datenleitungen und die restlichen Pins (RS, Write etc) an den 
Mikrocontroller.

Wie funktioniert die Übertragung, ohne solche Peripherie? Seite 16 unten 
wird der ganze Bus irgendwie an den Port B gebunden, soganz verstehe ich 
das aber nicht. WIE könnte man die Datenleitungen für den PIC noch 
definieren? (ohne den ganzen Port dafür zu benutzen)

Da die LCD's alle gleich sind bzw mit dem HD44780 ausgestattet sind, 
habe ich an folgendes gedacht: 
https://www.amazon.de/AZDelivery-HD44780-Display-Schnittstelle-Anzeigen/dp/B01N3B8JMN
Das I2C Interface ist in meinem Fall ja Optional.

Danke im Vorraus,
Gruß!

von Teo D. (teoderix)


Lesenswert?

Seier M. schrieb:
> Wie funktioniert die Übertragung, ohne solche Peripherie?

Wenn du keine HW hast, die dir diese Arbeit abnimmt, musst du diese 
Funktionalität halt selbst programmieren.

Seier M. schrieb:
> WIE könnte man die Datenleitungen für den PIC noch
> definieren? (ohne den ganzen Port dafür zu benutzen)

Du hast doch die volle Kontrolle über jeden einzelnen IO-Pin!
Entweder du machst es dir einfach und legst Daten und Steuerleitungen 
auf einen Port. Um die ungenutzten Pins für andre Aufgaben frei zu 
halten, werden diese ausmaskiert, so das diese nach nem beschreiben 
des Port unverändert bleiben. 
https://www.mikrocontroller.net/articles/Bitmanipulation
So ist es auch möglich, mit etwas mehr Aufwand, jeden beliebigen Pin auf 
unterschiedlichen Ports zu verwenden.

von Volker S. (vloki)


Lesenswert?

Seier M. schrieb:
> Seite 16 Und zwar orientiere ich mich an folgende Anleitung:...

Du verwendest auch den gleichen Compiler?
Welchen PIC hast du?

Seier M. schrieb:
> Wie funktioniert die Übertragung, ohne solche Peripherie?

Was meinst du hier mit Peripherie? Ganz allgemein brauchst du nur die 
entsprechende Anzahl von Pins zum Ansteuern des LCD. Die können alle am 
selben Port sein, müssen aber nicht...

: Bearbeitet durch User
von Seier M. (Gast)


Lesenswert?

Hallo,

Wenn ich das richtig verstehe:
In der Anleitung wurde folgendes gemacht:
1
 #pragma char LCD_DATA @PORTB
Da wurde also der gesamte PORTB dem LCD_DATA zugewiesen. Das sieht für 
mich aus als wäre es das selbe wie bei einem #define.. Dass hier überall 
wo Daten in LCD_DATA geschrieben werden, das gleiche ist wie wenn da 
PORTB stehen würde?
Obwohl das #define ja nur etwas ersetzen geht, das #pragma hat da ja 
schon ne wichtigere Rolle.

Verwende den XC16 Compiler mit einem PIC24.
Damit meinte ich dass ich kein I2C, SPI oder sontiges mehr zur Verfügung 
habe.:/

lG

von Peter D. (peda)


Lesenswert?

Seier M. schrieb:
> Wie funktioniert die Übertragung, ohne solche Peripherie?

Direkt mit Bit setzen/löschen. Damit spart man den Umweg über einen 
extra IC.
Oftmals kann man aber nicht alle Pins auf den selben Port legen, dann 
kann man es so lösen:
https://www.avrfreaks.net/forum/tutc-lcd-tutorial-1001

Die Syntax für Bitdefinitionen kann beim PIC-Compiler abweichen.

Seier M. schrieb:
> Damit meinte ich dass ich kein I2C, SPI oder sontiges mehr zur Verfügung
> habe.:/

I2C, SPI lassen sich ebenfalls mit beliebigen IO-Pins durch Bit 
setzen/löschen implementieren.

von Volker S. (vloki)


Lesenswert?

Seier M. schrieb:
> In der Anleitung wurde folgendes gemacht: #pragma char LCD_DATA @PORTB

Das scheint mir etwas eher Compiler spezifisches zu sein.
Ich kenne das eher so (etwas speziell, weil auch für Daten beliebige 
Pins möglich)
1
#define  LCD_E       LATCbits.LATC1
2
#define  LCD_E_DIR   TRISCbits.TRISC1
3
#define  LCD_RW      LATCbits.LATC0
4
#define  LCD_RW_DIR  TRISCbits.TRISC0
5
#define  LCD_RS      LATAbits.LATA5
6
#define  LCD_RS_DIR  TRISAbits.TRISA5
7
8
#define  LCD_D4_IN  PORTBbits.RB2
9
#define  LCD_D5_IN  PORTBbits.RB3
10
#define  LCD_D6_IN  PORTBbits.RB4
11
#define  LCD_D7_IN  PORTBbits.RB5
12
#define  LCD_D4_OUT  LATBbits.LATB2
13
#define  LCD_D5_OUT  LATBbits.LATB3
14
#define  LCD_D6_OUT  LATBbits.LATB4
15
#define  LCD_D7_OUT  LATBbits.LATB5
16
#define  LCD_D4_DIR  TRISBbits.TRISB2
17
#define  LCD_D5_DIR  TRISBbits.TRISB3
18
#define  LCD_D6_DIR  TRISBbits.TRISB4
19
#define  LCD_D7_DIR  TRISBbits.TRISB5
20
21
#define LCD_DIR_IN()  LCD_D4_DIR = LCD_D5_DIR = LCD_D6_DIR = LCD_D7_DIR = 1
22
#define LCD_DIR_OUT() LCD_D4_DIR = LCD_D5_DIR = LCD_D6_DIR = LCD_D7_DIR = 0
23
24
#define LCD_STROBE()    LCD_E = 1; LCD_DELAY_1US(); LCD_E = 0;

Beim Schreiben sieht das dann etwa so aus:
1
void LCD_Write(unsigned char value) // command or data
2
{
3
    LCD_data.all = value;
4
    LCD_RW = LCD_WR;
5
6
    LCD_D7_OUT = LCD_data.bit7;
7
    LCD_D6_OUT = LCD_data.bit6;
8
    LCD_D5_OUT = LCD_data.bit5;
9
    LCD_D4_OUT = LCD_data.bit4;
10
#ifndef LCD_USE_8BIT_DATA
11
    LCD_STROBE();
12
#endif
13
14
    LCD_D3_OUT = LCD_data.bit3;
15
    LCD_D2_OUT = LCD_data.bit2;
16
    LCD_D1_OUT = LCD_data.bit1;
17
    LCD_D0_OUT = LCD_data.bit0;
18
    LCD_STROBE();
19
}

Kannst du natürlich auch in deinem PDF schauen, wie das dort läuft.
(Die Anleitung scheint allerdings auch eher für einen PIC16 zu sein)

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Seier M. schrieb:
> Und zwar orientiere ich mich an folgende Anleitung:
> http://www.stefan-buchgeher.info/elektronik/lcd/lcd_doku.pdf
>
> Es wird kein Interface(I2C, SPI, Uart..) benutzt. Das Display kommt mit
> seinen 4 Datenleitungen und die restlichen Pins (RS, Write etc) an den
> Mikrocontroller.
>
> Wie funktioniert die Übertragung, ohne solche Peripherie?

Ja an was für eine Peripherie hast du denn so gedacht? Für sowas gibt es 
keine! Guck dir das Diagramm auf Seite 7 an, da findest du alles, was du 
an Informationen brauchst.

Also setze RS high oder low, je nachdem ob du Displaydaten oder 
Steuerkommandos schreiben willst, dann:

Setze R/W auf low zum Schreiben, dann:

Setze deine 4 Datenbit so, wie du sie haben willst, dann:

Mache nen High-Impuls an E(nable), dann:

bei 4 Bit Betrieb nochmal das Ganze mit den anderen 4 Bit, dann:

Warte bei manchen Steuerkommandos ne Weile, weil deren Verarbeitung im 
Display halt dauert.

Das war's eigentlich. Ich geb dir mal ein Beispiel (Auszug, zum 
Angucken. Nicht zum gedankenlosen copy&paste):
1
          INCLUDE P16F716.PIC
2
3
; Hardware:
4
; Pollin-LCD 2x8Zeichen Alpha, 4 Datenbit
5
; der PIC läuft mit 18.432 MHz
6
7
8
; Portbelegung
9
; Port B
10
CE_LCD:   BIT   PortB,0  ; out
11
RefCt:    BIT   PortB,1  ; in
12
RW_LCD:   BIT   PortB,2  ; out
13
RS_LCD:   BIT   PortB,3  ; out
14
D4:       BIT   PortB,4
15
D5:       BIT   PortB,5
16
D6:       BIT   PortB,6
17
D7:       BIT   PortB,7
18
19
20
21
; Port D auf Input stellen OHNE W anzurühren
22
Dir_IN:   BSF    RP0
23
          BSF    TrisB,4
24
          BSF    TrisB,5
25
          BSF    TrisB,6
26
          BSF    TrisB,7
27
          BCF    RP0
28
          RETURN
29
30
; Port D auf Output stellen OHNE W anzurühren
31
Dir_OUT:  BSF    RP0
32
          BCF    TrisB,4
33
          BCF    TrisB,5
34
          BCF    TrisB,6
35
          BCF    TrisB,7
36
          BCF    RP0
37
          RETURN
38
39
; Ausgabepuffer löschen
40
ClearString:
41
         MOVLW  16
42
         MOVWF  Hudl
43
         MOVLW  RString+1
44
         MOVWF  FSR
45
         MOVLW  ' '
46
_clz:    MOVWF  Indirect
47
         INCF   FSR,F
48
         DECFSZ Hudl,F
49
         GOTO   _clz
50
         CLRF   RString
51
         RETURN   
52
                  
53
54
55
; Ausgabe auf LCD mit Warten auf Ready vom LCD
56
SayIt:   BSF    toRS_LCD
57
         SKIP   toString
58
         GOTO   OutLCD
59
         MOVWF  RChar
60
         MOVF   RString,W
61
         ANDLW  15
62
         ADDLW  RString+1         
63
         MOVWF  FSR
64
         MOVF   RChar,W
65
         MOVWF  Indirect
66
         INCF   RString,F
67
         RETURN      
68
         
69
70
; toRS-LCD muß für Zeichenausgabe gesetzt sein
71
OutLCD:  MOVWF  RChar
72
         INCF   LxPos,F
73
         CALL   Dir_IN
74
_ow:     BSF    RW_LCD
75
         BCF    RS_LCD
76
         BSF    CE_LCD
77
         NOP
78
         NOP
79
         MOVF   PortB,W
80
         BCF    CE_LCD
81
         ANDLW  10000000b
82
         SKIP   Z
83
         GOTO   _ow
84
         CALL   Dir_OUT
85
         GOTO   _out
86
87
; direkte Ausgabe auf LCD ohne Warten.
88
Out_imm: MOVWF  RChar
89
90
_out:    CALL   Dir_OUT
91
         ; RS einstellen
92
         SKIP   toRS_LCD
93
         BCF    RS_LCD
94
         SKIP   NOT toRS_LCD
95
         BSF    RS_LCD
96
         MOVF   PortB,W
97
         ANDLW  B'00001111'
98
         MOVWF  RPort
99
100
         ; zuerst hi
101
         MOVF   RChar,W
102
         ANDLW  B'11110000'
103
         IORWF  RPort,W
104
         MOVWF  PortB
105
         BCF    RW_LCD
106
         BSF    CE_LCD
107
         NOP
108
         NOP
109
         BCF    CE_LCD
110
111
         ; dann lo
112
         SWAPF  RChar,W
113
         ANDLW  B'11110000'
114
         IORWF  RPort,W
115
         MOVWF  PortB
116
         BCF    RW_LCD
117
         BSF    CE_LCD
118
         NOP
119
         NOP
120
         BCF    CE_LCD
121
         SKIP   toRS_LCD
122
         RETURN
123
         MOVLW  5
124
         CALL   Wait
125
         RETURN
126
127
; Schreibposition im LCD setzen.
128
129
GoLast:  MOVLW  71
130
         GOTO   SetPosi
131
132
GoZeile2:
133
         MOVLW  64
134
         GOTO   SetPosi
135
GoZeile1:
136
         CLRW
137
138
SetPosi: MOVWF  LxPos
139
         IORLW  B'10000000'
140
         BCF    toRS_LCD
141
         CALL   OutLCD
142
         BSF    toRS_LCD
143
         MOVLW  15
144
         ANDWF  LxPos,F
145
         RETURN
146
147
148
ClrEol:  MOVF   LxPos,W
149
         ANDLW  16
150
         SKIP   Z
151
         RETURN
152
         MOVLW  ' '
153
         CALL   SayIt
154
         GOTO   ClrEol
155
156
157
; LCD initialisieren
158
InitLCD:
159
         BCF      CE_LCD      ; CE lo
160
         BCF      RS_LCD      ; RS lo
161
         BCF      RW_LCD      ; R/W auf write
162
         BCF      toRS_LCD    ; auch in den Flags
163
         MOVLW    30          ; 30 ms
164
         CALL     Wait
165
         BCF      toRS_LCD
166
         MOVLW    B'00101000' ; 4 Bit Modus
167
         CALL     Out_imm
168
         MOVLW    10          ; 10 ms
169
         CALL     Wait
170
         MOVLW    00010100b   ; CursorMove+rechts
171
         CALL     Out_imm
172
         CALL     Wait_1
173
         MOVLW    00001100b   ; On+noCursor+noBlink
174
         CALL     Out_imm
175
         CALL     Wait_1
176
         MOVLW    00000110b   ; Increment+noShift
177
         CALL     Out_imm
178
         CALL     Wait_1
179
         MOVLW    00000001b   ; Clear
180
         CALL     Out_imm
181
         CALL     Wait_1
182
         MOVLW    00000011b   ; Clear
183
         CALL     Out_imm
184
         CALL     Wait_1
185
         BSF      toRS_LCD    ; 1 = Zeichenausgabe
186
         MOVLW    30          ; 30 ms
187
         CALL     Wait
188
         CALL     LadeLcdCharset
189
         RETURN
So, das war's, ist ja auch recht länglich geworden (ausnahmsweise...)
Die restlichen Daten und Unterprogramme (Wait und so) kannst du dir ja 
denken.

W.S.

von Karl B. (gustav)


Lesenswert?

W.S. schrieb:
> Mache nen High-Impuls an E(nable), dann:


Hi,
ein High/Low-Übergang kommt natürlich noch danach. (Impulsdauer meistens 
1000 ns.)
LCD Enable triggert auf die fallende Flanke.


Seier M. schrieb:
> Wie funktioniert die Übertragung, ohne solche Peripherie?

Beitrag "Re: RE Bit Display EA DIP204-4 (KS0073)"
so sieht das Display die Signale.
Im Zeitlupentempo. Und der MC-Port wird entsprechend programmiert.

(OK. Da sind noch Fehler im Video. 0x0C z.B. Aber sollte nur das Prinzip 
veranschaulichen.)

ciao
gustav
P.S.:
Die Portbitzuordnung kann auch anders gewählt werden. 
(Software-Anpassung)
Hier:
LSB-MSB
RS-R/W-Enable-n.c. D4-D5-D6-D7

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

W.S. schrieb:
> So, das war's, ist ja auch recht länglich geworden

Wer sich heutzutage sich noch mit Assembler abquält, der wird eben mit 
langem und unportablen Code bestraft.

von picfan (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
habe noch eine fertige LCD44780 Routine, geschrieben für einen 
DSPIC30F4012,kann auch für PIC24 direkt eingesetzt werden(gleiche 
Architektur).
Gruss PICFAN

von picfan (Gast)


Angehängte Dateien:

Lesenswert?

hier noch zwei Routinen zum Einbinden
Gruss Picfan

von Seier M. (Gast)


Lesenswert?

Hallo,

Vielen vielen Dank an alle! Ich merke, das Thema ist immer noch sehr 
aktuell!
Dann ist die Ansteuerung ja doch nicht schwierig. Mich hatte eben wie 
gesagt nur die eine Compiler spezifische Anlegung des Buses gewundert.

Hier ist auch noch eine gute Code Sammlung aus diesem Forum:
Beitrag "[ASM & C] HD44780 an PIC24 (3.3V oder 5V)"

Somit ist dieses Thema abgeschlossen, hier wird der eine oder andere 
wohl auf gute Sammlungen zurückgreifen können!
Nochmals Liebend Dank!

-Seier M.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.