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ß!
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.
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
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
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.
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
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.
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
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.
Hallo, habe noch eine fertige LCD44780 Routine, geschrieben für einen DSPIC30F4012,kann auch für PIC24 direkt eingesetzt werden(gleiche Architektur). Gruss PICFAN
hier noch zwei Routinen zum Einbinden Gruss Picfan
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.