1 | ;***************************************************************
|
2 | ;Programm LCD.ASM
|
3 | ;Es wird vorausgesetzt, dass die Anzeige einen HD44780 oder
|
4 | ;kompatiblen Controller verwendet.
|
5 | ;ATmega8535 mit 8 MHz Takt
|
6 | ;***************************************************************
|
7 |
|
8 | .include "m8def.inc" ;muss im selben
|
9 | ;Verzeichnis stehen
|
10 | ;***************************************************************
|
11 | ;Board spezifizierungen
|
12 | ;***************************************************************
|
13 |
|
14 | .ifndef XTAL
|
15 | .equ XTAL = 4000000 ;Quarztakt hier: 8 MHz
|
16 |
|
17 | ;***************************************************************
|
18 | ;Definition der Steuerleitungen
|
19 | ;***************************************************************
|
20 |
|
21 | .equ E = PD0 ;E an Pin PA0
|
22 | .equ RW = PD1 ;RW an Pin PA1
|
23 | .equ RS = PD2 ;RS an Pin PA2
|
24 | .equ CS1 = PD3 ;Linke Seite des Displays
|
25 | .equ CS2 = PD4 ;Rechte Seite des Displays
|
26 | .equ BF = PB7 ;Busy flag
|
27 | .equ LED1 = 0b00100000
|
28 | .equ LED2 = 0b01000000
|
29 | .equ LED3 = 0b01100000
|
30 |
|
31 | ;***************************************************************
|
32 | ;LCD Befehle
|
33 | ;***************************************************************
|
34 |
|
35 | .equ clear_LCD = 0b00000001 ;loesche Anzeige
|
36 | .equ home_LCD = 0b00000010 ;return home
|
37 | .equ set_LCD = 0b00111100 ;8 bits,2 Zeilen,5x7dots
|
38 | .equ LCD_on = 0b00001110 ;schalte LCD ein
|
39 | .equ entry_mode = 0b00000110 ;setze Cursor
|
40 |
|
41 | ;***************************************************************
|
42 | ;Variablendefinition
|
43 | ;***************************************************************
|
44 |
|
45 | .def zeichen = r0 ;Zeichen aus der Tabelle
|
46 | .def buffer = r16 ;RX/TX Daten von/zu LCD
|
47 | .def counter = r17 ;Zaehler fuer den Text
|
48 | .def temp1 = r18
|
49 | .def temp2 = r19
|
50 |
|
51 |
|
52 |
|
53 | .CSEG
|
54 | .ORG 0x00 ; Programm beginnt bei 0
|
55 | rjmp main ; Starte Hauptprogramm
|
56 |
|
57 | ;***************************************************************
|
58 | ; Subroutine init
|
59 | ; Initialisiere PORTA
|
60 | ;***************************************************************
|
61 |
|
62 | init:
|
63 |
|
64 | ldi temp1,0b11111111
|
65 | out DDRD,temp1 ;PORTA ist Ausgang
|
66 | out DDRB,temp1 ;PORTD ist Ausgang
|
67 | cbi PORTD,E ;E initialisieren
|
68 | cbi PORTD,RS
|
69 | cbi PORTD,RW
|
70 | cbi PORTD,CS1 ;Linke Seite des Displays
|
71 | cbi PORTD,CS2 ;Rechte Seite des Displays
|
72 | ret
|
73 |
|
74 |
|
75 |
|
76 | ;***************************************************************
|
77 | ; Subroutine busy_flag
|
78 | ; Diese Routine testet, ob die LCD-Anzeige bereit ist, einen
|
79 | ; neuen Befehl oder weitere Daten zu empfangen.
|
80 | ;***************************************************************
|
81 |
|
82 | busy_flag:
|
83 |
|
84 | ldi temp1,0b00000000 ;PORTC ist Eingang
|
85 | out DDRB,temp1
|
86 | sbi PORTD,CS1
|
87 | sbi PORTD,CS2
|
88 | cbi PORTD,RS ;Befehl wird gesendet
|
89 | rcall delay50us
|
90 | sbi PORTD,RW ;setze LCD in Lesemodus
|
91 | rcall delay50us
|
92 | sbi PORTD,E ;spreche LCD an
|
93 | rcall delay50us
|
94 | sbic PINB,BF ;LCD bereit?
|
95 | rjmp busy_flag ;nein, wiederhole
|
96 | cbi PORTD,E ;disable LCD
|
97 | ret ;LCD bereit
|
98 |
|
99 |
|
100 | ;***************************************************************
|
101 | ; Subroutine write_data
|
102 | ; Diese Routine sendet Daten zur LCD-Anzeige.
|
103 | ; Die Daten muessen im Register buffer uebergeben werden.
|
104 | ;***************************************************************
|
105 |
|
106 | write_data:
|
107 | rcall busy_flag ;LCD bereit?
|
108 | ldi temp1,0b11111111 ;PORTC ist Ausgang
|
109 | out DDRB,temp1
|
110 | sbi PORTD,CS1
|
111 | sbi PORTD,CS2
|
112 | sbi PORTD,RS ;Daten werden gesendet
|
113 | cbi PORTD,RW ;LCD in Schreibmodus
|
114 | sbi PORTD,E ;spreche LCD an
|
115 | out PORTB,buffer ;sende Daten
|
116 | cbi PORTD,E ;disable LCD
|
117 | ret
|
118 |
|
119 |
|
120 | ;***************************************************************
|
121 | ; Subroutine write_instr
|
122 | ; Diese Routine sendet Befehle zur LCD-Anzeige.
|
123 | ; Der Befehl muss im Register buffer uebergeben werden.
|
124 | ;***************************************************************
|
125 |
|
126 | write_instr:
|
127 | rcall busy_flag ;LCD bereit?
|
128 | ldi temp1,0b11111111 ;RB ist Ausgang
|
129 | out DDRB,temp1
|
130 | sbi PORTD,CS1
|
131 | sbi PORTD,CS2
|
132 | cbi PORTD,RS ;Befehl wird gesendet
|
133 | cbi PORTD,RW ;LCD in Schreibmodus
|
134 | sbi PORTD,E ;spreche LCD an
|
135 | out PORTB,buffer ;sende Befehl
|
136 | cbi PORTD,E ;disable LCD
|
137 | ret
|
138 |
|
139 | ;***************************************************************
|
140 | ; Diese Routine errechnet die Pausenzeiten 50us
|
141 | ; in Abhängigkeit des eingebauten Quarz
|
142 | ;***************************************************************
|
143 |
|
144 | delay50us: ; 50us Pause
|
145 |
|
146 | ldi temp1, ( XTAL * 50 / 3 ) / 1000000
|
147 |
|
148 | delay50us_:
|
149 | dec temp1
|
150 | brne delay50us_
|
151 | ret ; wieder zurück
|
152 |
|
153 | ;***************************************************************
|
154 | ; Hauptprogramm
|
155 | ; Schreibt "ATmega8535" in die erste Zeile und "LCD-Routine"
|
156 | ; in die zweite Zeile des LCDs.
|
157 | ;***************************************************************
|
158 |
|
159 | main:
|
160 | ldi temp1,LOW(RAMEND) ;setze Stack-Pointer
|
161 | out SPL,temp1 ;an das SRAM-Ende
|
162 | ldi temp1,HIGH(RAMEND)
|
163 | out SPH,temp1
|
164 |
|
165 | ldi r19, LED1 ;LED1 AN
|
166 | out PORTC, r19
|
167 |
|
168 | rcall init ;PORTA initialisieren
|
169 |
|
170 | ldi r19, LED2 ;LED2 AN
|
171 | out PORTC, r19
|
172 |
|
173 | ldi buffer,set_LCD ;setze LCD Funktion
|
174 | rcall write_instr
|
175 |
|
176 | ldi buffer,LCD_on ;schalte LCD ein
|
177 | rcall write_instr
|
178 |
|
179 | ldi buffer,clear_LCD ;loesche Anzeige
|
180 | rcall write_instr
|
181 |
|
182 | ldi buffer,entry_mode ;Eingabemodus
|
183 | rcall write_instr
|
184 |
|
185 | ldi r19, LED3 ;LED1 & 2 AN
|
186 | out PORTC, r19
|
187 |
|
188 | ;***************************************************************
|
189 | ;Holt den Text 'ATmega8535' aus der Tabelle und schreibt diesen
|
190 | ;in die erste Zeile der Anzeige
|
191 | ;***************************************************************
|
192 | ldi counter,10 ;Zeichenzaehler
|
193 | ldi ZL,LOW(Tabelle1*2) ;Low-Zeiger auf Tabellenanfang
|
194 | ldi ZH,HIGH(Tabelle1*2) ;High-Zeiger auf Tabellenanfang
|
195 |
|
196 | loop_msg1:
|
197 |
|
198 | lpm ;hole Zeichen aus Tabelle
|
199 | mov buffer,zeichen ;Zeichen uebergeben
|
200 | rcall write_data ;schreibe Zeichen in LCD
|
201 | adiw ZL,1 ;16-Bit Zeiger erhoehen
|
202 | dec counter ;alle Zeichen gesendet?
|
203 | brne loop_msg1 ;Nein! Sende naechstes Zeichen
|
204 |
|
205 | ;***************************************************************
|
206 | ;Holt den Text 'LCD-Routine' aus der Tabelle und schreibt diesen
|
207 | ;in die zweite Zeile der Anzeige
|
208 | ;***************************************************************
|
209 |
|
210 | ldi buffer,0b11000000 ;LCD-Startadresse 2.Zeile
|
211 | rcall write_instr ;sende Befehl
|
212 | ldi counter,11 ;Zeichenzaehler
|
213 | ldi ZL,LOW(Tabelle2*2) ;Low-Zeiger auf Tabellenanfang
|
214 | ldi ZH,HIGH(Tabelle2*2);High-Zeiger auf Tabellenanfang
|
215 |
|
216 | loop_msg2:
|
217 |
|
218 | lpm ;hole Zeichen aus Tabelle
|
219 | mov buffer,zeichen ;Zeichen uebergeben
|
220 | rcall write_data ;schreibe Zeichen in LCD
|
221 | adiw ZL,1 ;16-Bit Zeiger erhoehen
|
222 |
|
223 | no_carry2:
|
224 |
|
225 | dec counter ;alle Zeichen gesendet?
|
226 | brne loop_msg2 ;Nein! Sende naechstes Zeichen
|
227 |
|
228 |
|
229 |
|
230 | ;Endlosschleife. AVR zuruecksetzen, um Programm erneut zu starten
|
231 |
|
232 | loop: rjmp loop
|
233 |
|
234 | ;***************************************************************
|
235 | ;Tabelle 1 mit dem Text "ATmega8535", der in die 1.Zeile
|
236 | ;geschrieben werden soll
|
237 | ;***************************************************************
|
238 |
|
239 | Tabelle1: .DB "ATmega8"
|
240 |
|
241 | ;***************************************************************
|
242 | ;Tabelle 2 mit dem Text "LCD-Routine", der in die 2.Zeile
|
243 | ;geschrieben werden soll
|
244 | ;***************************************************************
|
245 |
|
246 | Tabelle2: .DB "LCD-Routine"
|
247 |
|
248 | .Exit
|