1 | ;***** Vor der Verwendung initialisieren mit lcall initLCD **************
|
2 | ;***** veränderte Register: r2 bis r7 der Registerbank 1 *****
|
3 | ;***** daher Stack hinter den Bitadressierbaren Bereich: mov sp,#2fh *****
|
4 | ;***** Übergaberegister ist der Akku **************
|
5 |
|
6 | ;include reg_51.pdf ;Registeradressen einbinden
|
7 |
|
8 | LCD_ROUTINES SEGMENT CODE ;Name für das folgende relative Codesegment
|
9 |
|
10 | RSEG LCD_ROUTINES ;relatives Segment, wird vom Linker hinter anderes Codesegment gehängt
|
11 |
|
12 | LCD_PORT EQU P0 ; *** Hier den verwendeten Port einsetzen !!!!!!!!!!!! ****
|
13 |
|
14 | public initLCD,loeschzeile1,loeschzeile2,textzeile1,textzeile2,cursorpos,textaus,zifferaus, hexaus, dezaus, loeschen
|
15 |
|
16 |
|
17 | ;---- Verwendung der Hilfsprogramme: ------------------------------------
|
18 | ; lcall initLCD ;Initialiserung des LCD-Displays
|
19 | ; lcall loeschen ;gesamtes Diplay löschen
|
20 | ; lcall loeschzeile1 ;nur Zeile 1 des Displays löschen
|
21 | ; lcall loeschzeile2 ;nur Zeile 2 des Displays löschen
|
22 |
|
23 | ;*** Die 16 Zeichen belegen die Display-Adressen 00h-0Fh (Zeile1) und 40h-4Fh (Zeile2)
|
24 | ; mov a,#03 ;Cursor auf die 4. Anzeigestelle setzen
|
25 | ; lcall cursorpos
|
26 |
|
27 | ;*** Textausgaben ************* die Anfangsadresse des Textes muß ***********
|
28 | ;*** im DPTR stehen und der Text muß mit einer 0 abgeschlossen werden! *****
|
29 | ; mov dptr,#Text1 ;Text ab der
|
30 | ; lcall textaus ;aktuellen Cursorposition ausgeben
|
31 | ; mov dptr,#Text1 ;Text ab der 1.Stelle
|
32 | ; lcall textzeile1 ;in Zeile 1 ausgeben
|
33 | ; mov dptr,#Text1 ;Text ab der 1.Stelle
|
34 | ; lcall textzeile2 ;in Zeile 2 ausgeben
|
35 | ;Text1: db 'Hallo! Test...',0 ;Angabe des auszugebenden Textes am Programmende
|
36 |
|
37 | ;*** Zahlenausgaben: Übergaberegister ist der Akku *******************************************
|
38 | ; mov a,p1 ;Ausgabe des Portinhalts von P1
|
39 | ; lcall zifferaus ;mit nur einer Ziffer (Lownibbel) an das Display
|
40 | ; mov a,p1 ;Ausgabe des Portinhalts von P1 als 2-stellige Hexzahl
|
41 | ; lcall hexaus ;Es werden immer 2 Stellen mit führenden Nullen ausgegeben
|
42 | ; mov a,p1 ;Ausgabe des Portinhalts von P1 als 3-stellige Dezimalzahl
|
43 | ; lcall dezaus ;Es werden immer 3 Stellen ausgegeben, führende Nullen sind dunkel
|
44 | ; mov a,p1 ;Ausgabe des Portinhalts von P1 als 8-Bit-Dualzahl
|
45 | ; lcall dualaus ;Es werden immer 8 Stellen ausgegeben mit führenden Nullen
|
46 | ; mov a,p1 ;Ausgabe des Portinhalts von P1 als 8-Bit-Dualzahl
|
47 | ; lcall dualaus1 ;rechtsbündig in Zeile1
|
48 | ; mov a,p1 ;Ausgabe des Portinhalts von P1 als 8-Bit-Dualzahl
|
49 | ; lcall dualaus2 ;rechtsbündig in Zeile2
|
50 |
|
51 | ;*** Anwendungsbeispiele siehe Datei LCDTEST.asm *******************************
|
52 |
|
53 |
|
54 |
|
55 | ;****** Definitionen / Abkürzungen ************************************************
|
56 | reg2 EQU 0Ah ;Register der Bank1
|
57 | reg3 EQU 0Bh
|
58 | reg4 EQU 0Ch
|
59 | reg5 EQU 0Dh
|
60 | reg6 EQU 0Eh
|
61 | reg7 EQU 0Fh
|
62 |
|
63 | ; **************** Display initialisieren ****************
|
64 | ;
|
65 | ; Display arbeitet im 2*4-Bit Modus
|
66 | ;
|
67 | ; Die 16 Zeichen belegen die Display-Adressen 00-0F und 40-4F (HEX!)
|
68 | ;
|
69 | ; Bit: 7 6 5 4 3 2 1 0
|
70 | ; Register Read/ 0 Takt D7/D3 D6/D2 D5/D1 D4/D0
|
71 | ; Select Write
|
72 |
|
73 | initLCD: mov LCD_PORT,#00010011b ;aufwecken! Takt=1
|
74 | mov LCD_PORT,#00000011b ; Takt=0
|
75 |
|
76 | mov reg5,#10 ; ca. 5 msec warten
|
77 | w0: djnz reg4,w0
|
78 | djnz reg5,w0
|
79 |
|
80 | mov LCD_PORT,#00010011b ;aufwecken! Takt=1
|
81 | mov LCD_PORT,#00000011b ; Takt=0
|
82 | w2: djnz reg5,w2 ; wartet 100 usec
|
83 |
|
84 | mov LCD_PORT,#00010011b ;aufwecken! Takt=1
|
85 | mov LCD_PORT,#00000011b ; Takt=0
|
86 | w3: djnz reg5,w3 ; wartet 100 usec
|
87 |
|
88 | mov LCD_PORT,#00010010b ;8->4 BITS UMSCHALTEN, Takt=1
|
89 | mov LCD_PORT,#00000010b ; Takt=0
|
90 | w4: djnz reg5,w4
|
91 |
|
92 | mov A,#00101000b ;Function set 4 bits
|
93 | lcall LCDbefehl ;Ausgabe im 4Bit-Modus
|
94 |
|
95 | mov A,#00001100b ; Display AN, Cursor AUS
|
96 | lcall LCDbefehl ;des Zeichens an der Cursorposition
|
97 |
|
98 | mov A,#00000110b ; Not Shifted Display, Increment
|
99 | lcall LCDbefehl
|
100 | ret
|
101 |
|
102 | ;*********** Loeschen Display *****************************************
|
103 | loeschen: mov A,#00000001b ;Display clear
|
104 | lcall LCDbefehl
|
105 | ret
|
106 | ;*********** Cursor AN ************************************************
|
107 | cursorAN: mov A,#00001110b ;Cursor und Display AN
|
108 | lcall LCDbefehl
|
109 | ret
|
110 | ;*********** Cursor AUS ***********************************************
|
111 | cursorAUS: mov A,#00001100b ;Cursor AUS, Display AN
|
112 | lcall LCDbefehl
|
113 | ret
|
114 |
|
115 | ;*********** Cursorposition *******************************************
|
116 | cursorpos: orl a,#10000000b ;Kennung für DD RAM address set
|
117 | lcall LCDbefehl
|
118 | ret
|
119 | ;*********** Cursorhome ***********************************************
|
120 | cursorhome: mov A,#00000010b ;Cursor home
|
121 | lcall LCDbefehl
|
122 | ret
|
123 |
|
124 | ;*********** Zeile 1 löschen ******************************************
|
125 | loeschzeile1: mov A,#00000010b ;Cursor home
|
126 | lcall LCDbefehl
|
127 | mov dptr,#textloesch
|
128 | lcall textzeile1
|
129 | mov A,#00000010b ;Cursor home
|
130 | lcall LCDbefehl
|
131 | ret
|
132 | textloesch: DB ' ',0
|
133 |
|
134 | ;*********** Zeile 2 löschen ******************************************
|
135 | loeschzeile2: mov a,#40h
|
136 | lcall cursorpos ;Cursor auf Position 1.Stelle/2.Zeile
|
137 | mov dptr,#textloesch
|
138 | lcall textzeile2
|
139 | mov a,#40h
|
140 | lcall cursorpos ;Cursor auf Position 1.Stelle/2.Zeile
|
141 | ret
|
142 |
|
143 | ;*********** Text an Zeile 1 ausgeben *********************************
|
144 | textzeile1: mov A,#00000010b ;Cursor home
|
145 | lcall LCDbefehl
|
146 | textaus: mov reg4,#0 ;0 ins r4 => Buchstabe 0
|
147 | textloop: mov A,reg4 ;Nr des Buchstabens in den Akku
|
148 | inc reg4
|
149 | cjne a,#10h,holbuchst ;schon Maximalzahl an Buchstaben?
|
150 | sjmp textende ;für eine Zeile => ja => Ende
|
151 | holbuchst: movc A,@A+DPTR ;Text Buchstabenweise holen
|
152 | jz textende ;falls 0 => Ende, sonst ausgeben
|
153 | ausgeben: lcall LCDtext
|
154 | sjmp textloop
|
155 | textende: ret
|
156 |
|
157 | ;*********** Text an Zeile 2 ausgeben *********************************
|
158 | textzeile2: mov a,#40h
|
159 | lcall cursorpos ;Cursor auf 1.Stelle/2.Zeile
|
160 | sjmp textaus
|
161 |
|
162 | ;********* Textaus (Text ab momentaner Cursorposition ausgeben **********
|
163 | ;textaus: mov a,#0
|
164 | ; movc a,@a+dptr ;Text zeichenweise holen
|
165 | ; jz textend ;Ende wenn Ordnungszahl des zeichens=0
|
166 | ; lcall LCDtext
|
167 | ; inc dptr ;nächstes zeichen
|
168 | ; sjmp textaus
|
169 | ;textend: ret
|
170 |
|
171 | ;********* Befehl fr LCD-Display im Akku ausgeben an LCD_PORT **************
|
172 | ;*************** RS R/W D7 D6 D5 D4 D3 D2 D1 D0
|
173 | ;*************** 0 0 x x x x x x x x
|
174 | LCDbefehl: push ACC
|
175 | swap a ;High- und Low-Nibbel tauschen
|
176 | anl A,#00001111b ;4 Bits maskieren
|
177 | orl A,#00010000b ;Übergabetakt = 1, High-Nibbel senden
|
178 | mov LCD_PORT,A
|
179 | anl A,#00001111b ;Takt = 0
|
180 | mov LCD_PORT,A
|
181 | pop ACC
|
182 | anl A,#00001111b ;Low-Nibble
|
183 | orl A,#00010000b ;Takt = 1
|
184 | mov LCD_PORT,A
|
185 | anl A,#00001111b ;Takt = 0
|
186 | mov LCD_PORT,A
|
187 | sjmp wbusy ;warten bis Bearbeitung beendet
|
188 |
|
189 | ;********* Text fr LCD-Display im Akku ausgeben an LCD_PORT **************
|
190 | ;*************** RS R/W D7 D6 D5 D4 D3 D2 D1 D0
|
191 | ;*************** 1 0 x x x x x x x x
|
192 | LCDtext:push ACC
|
193 | swap a ;Nibbel vertauschen
|
194 | anl A,#00001111b ;4 Bits maskieren
|
195 | orl A,#10010000b ;Übergabetakt = 1, RS = 1 (Befehl!)
|
196 | mov LCD_PORT,A
|
197 | anl A,#10001111b ;Takt = 0
|
198 | mov LCD_PORT,A
|
199 | pop ACC
|
200 | anl A,#00001111b ;Low-Nibble
|
201 | orl A,#10010000b ;Takt = 1, RS = 1
|
202 | mov LCD_PORT,A
|
203 | anl A,#10001111b ;Takt = 0
|
204 | mov LCD_PORT,A
|
205 | ;************** warten bis Bearbeitung im Display beendet **********
|
206 | wbusy: mov LCD_PORT,#01011111b ; Busy lesen, Takt=1, RS = 0
|
207 | mov A,LCD_PORT ; und holen
|
208 | mov LCD_PORT,#01001111b ; Takt=0
|
209 | nop
|
210 | mov LCD_PORT,#01011111b ; Low-Byte holen (ohne Bedeutung)
|
211 | mov LCD_PORT,#01001111b
|
212 |
|
213 | mov reg2,50 ;Zeitverzögerung 1ms
|
214 | warteR2: mov reg3,#10 ;statt auf busy warten
|
215 | warteR3: djnz reg3,warteR3 ;wenn LCD an p0
|
216 | djnz reg2,warteR2
|
217 |
|
218 | ; jb ACC.3,wbusy ; Busy? warten , geht nicht mit LCD an p0
|
219 | ret
|
220 |
|
221 | ;*********************** dezaus *********************************************
|
222 | ;+++++++++ Die Zahl im Akku wird als Dezimalzahl ausgegeben +++++++++++++++++
|
223 | ;--------- Es werden immer 3 Stellen ausgegeben, führende Nullen sind dunkel
|
224 | dezaus:
|
225 | push acc
|
226 | mov b,#100 ;der in A stehende Wert wird durch 100
|
227 | div ab ;geteilt und die Hunderter-Ziffer in
|
228 | mov reg7,a ;r7 gegeben
|
229 | mov a,b ;die verbleibende Zehnerzahl
|
230 | mov b,#10 ;wird durch 10
|
231 | div ab ;geteilt
|
232 | swap a ;Die Zehnerziffer wird das High-Nibbel,
|
233 | add a,b ;die Einerziffer das Low-Nibbel
|
234 | mov reg5,a ;diese BCD-Zahl wird in r5 gespeichert
|
235 | mov a,reg7 ;die vorderste BCD-Ziffer
|
236 | mov reg4,a ;wird in r4 gesichert und
|
237 | jnz ausg1 ;wird normal ausgegeben, falls sie nicht 0 ist
|
238 | mov a,#31 ;leere Anzeige
|
239 | lcall lcdtext ;falls null
|
240 | sjmp Ziff2
|
241 | ausg1: lcall sendascii ;1.Ziffer ausgeben
|
242 | Ziff2: mov a,reg5 ;2. u. 3. Ziffer zurückholen
|
243 | hex0: mov reg7,a ;zwischenspeichern in r7
|
244 | anl a,#0f0h ;High-Nibbel maskieren
|
245 | swap a ;und zur Ziffer im Low-Nibbel machen
|
246 | jnz ausg2 ;wird normal ausgegeben, falls sie nicht 0 ist
|
247 | cjne a,reg4,ausg2 ;nur 0 unterdrücken falls 1.Ziffer auch 0 war
|
248 | mov a,#31 ;leere Anzeige
|
249 | lcall lcdtext ;falls null
|
250 | sjmp Ziff3
|
251 | ausg2: lcall sendascii ;2.Ziffer ausgeben
|
252 | Ziff3: mov a,reg7 ;Zwischengespeicherte Zahl zurck
|
253 | anl a,#0fh ;Low-Nibbel ausblenden
|
254 | lcall sendascii ;und ausgeben
|
255 | dezend: pop acc
|
256 | ret
|
257 |
|
258 | ;*********************** hexaus *****************************************
|
259 | ;+++++++++ Die Zahl im Akku wird hexadezimal ausgegeben +++++++++++++++++
|
260 | ;--------- Es werden immer 2 Stellen mit führenden Nullen ausgegeben ----
|
261 | hexaus: push acc
|
262 | mov reg7,a ;zwischenspeichern in r7
|
263 | anl a,#0f0h ;High-Nibbel maskieren
|
264 | swap a ;und zur Ziffer im Low-Nibbel machen
|
265 | ; cjne a,#0,ausg2Z ;zur Unterdrückung der führenden Null
|
266 | ; mov a,#20 ;leere Anzeige
|
267 | ; lcall lcdtext ;
|
268 | ; sjmp weit2 ;
|
269 | ausg2Z: lcall sendascii ;
|
270 | weit2: mov a,reg7 ;Zwischengespeicherte Zahl zurck
|
271 | anl a,#0fh ;Low-Nibbel ausblenden
|
272 | lcall sendascii ;und ausgeben
|
273 | pop acc
|
274 | ret
|
275 |
|
276 | ;****************** dualaus (Zahl im Akku als 8-Bit-Dualzahl ausgeben) ********
|
277 | dualaus:
|
278 | push acc
|
279 | mov reg5,#8 ;Zähler
|
280 | dloop: mov reg7,a ;Zahl zwischenspeichern
|
281 | jb acc.7,d1 ;Sprung zur "1"-Ausgabe wenn Bit=1
|
282 | mov a,#0 ;Null ausgeben
|
283 | lcall sendascii ;
|
284 | sjmp d2 ;
|
285 | d1: mov a,#1 ;Eins ausgeben
|
286 | lcall sendascii ;
|
287 | d2: mov a,reg7 ;zwischengespeicherte Zahl zurück
|
288 | rl a ;nächstes Bit
|
289 | djnz reg5,dloop ;von vorne falls noch nicht alle 8 Bit
|
290 | pop acc
|
291 | ret
|
292 |
|
293 | ;***************** Duale Ausgabe rechtsbündig in Zeile 1 *********************
|
294 | dualaus1:
|
295 | push acc
|
296 | mov a,#08
|
297 | lcall cursorpos
|
298 | pop acc
|
299 | lcall dualaus
|
300 | ret
|
301 | ;***************** Duale Ausgabe rechtsbündig in Zeile 2 *********************
|
302 | dualaus2:
|
303 | push acc
|
304 | mov a,#48
|
305 | lcall cursorpos
|
306 | pop acc
|
307 | lcall dualaus
|
308 | ret
|
309 |
|
310 | ;************** sendascii (1 Hexziffer als Ascii-Zeichen senden) *********
|
311 | sendascii:
|
312 | mov reg6,a
|
313 | subb a,#0Ah
|
314 | mov a,reg6
|
315 | jc zahl
|
316 | Buchst: add a,#37h
|
317 | sjmp weit1
|
318 | zahl: clr c ;Carry zurcksetzen, sonst Fehler bei add
|
319 | add a,#30h
|
320 | weit1: lcall LCDtext
|
321 | ret
|
322 |
|
323 | ;*************** zifferaus (eine Ziffer 0 bis 9 ausgeben *****************
|
324 | zifferaus:
|
325 | push acc
|
326 | anl a,#0Fh
|
327 | lcall sendascii
|
328 | pop acc
|
329 | ret
|
330 |
|
331 | ;****** PIN-Belegung für LCD-Display LTN 214 R-10 am LCD_PORT **************
|
332 | ; * Uebertragung eines Bytes als 2 * 4 Bits.
|
333 | ; * Ansicht von oben auf Display
|
334 | ; * 1 GND--------------------------------------------------> GND
|
335 | ; * 2 +5Volt-----------------------------------------------> +5V
|
336 | ; * 3 V0: Steuerspannung Kontrast 0..5 Volt erlaubt,-------> V0
|
337 | ; * Arbeitspunkt ca. 0.6 V (am besten Spindeltrimmer zum Einst.)
|
338 | ; * 4 RS: Registersatz (Display oder Befehl)---------------> LCD_PORT.7
|
339 | ; * 5 R/W: Schreiben oder lesen----------------------------> LCD_PORT.6
|
340 | ; * 6 E: Uebergabetakt-------------------------------------> LCD_PORT.4
|
341 | ; * 7-10: frei (eigentlich D0 - D3, wird aber nicht verwendet)
|
342 | ; * 11: D4/D0----------------------------------------------> LCD_PORT.0
|
343 | ; * 12: D5/D1----------------------------------------------> LCD_PORT.1
|
344 | ; * 13: D6/D2----------------------------------------------> LCD_PORT.2
|
345 | ; * 14: D7/D3----------------------------------------------> LCD_PORT.3
|
346 | ; *******************************************************
|
347 |
|
348 | END
|