1 | .NOLIST ; List-Output unterdrücken
|
2 |
|
3 | ; .INCLUDE <m8def.inc>
|
4 | ; .include "C:\PROGRA~1\VMLAB\include\m8def.inc"
|
5 | ; .include "C:\PROGRA~1\AVR Tools\VMLAB\m8def.inc"
|
6 | .include "E:\Atmel\AVRStudio\m8def.inc"
|
7 |
|
8 | .equ F_CPU = 7372800 ; Systemtakt in Hz
|
9 |
|
10 | .def temp = r22
|
11 | .def temp1 = r23
|
12 | .def temp2 = r24
|
13 | .def temp3 = r25 ; für Interrupt
|
14 |
|
15 | .LIST ; List-Output wieder aufdrehen
|
16 | .CSEG ; was nun folgt, gehört in den FLASH-Speicher
|
17 |
|
18 | ;------------------------------------------------------
|
19 | ; Start Adresse 0000 /Interruptvektoren
|
20 | ;------------------------------------------------------
|
21 | .org 0x000
|
22 | rjmp Init ; Interruptvektoren überspringen
|
23 |
|
24 | ;------------------------------------------------------
|
25 | ; INITIALIZE
|
26 | ;------------------------------------------------------
|
27 | INIT:
|
28 | ;Stack Pointer setzen
|
29 | ldi temp,high(RAMEND)
|
30 | out SPH,temp
|
31 | ldi temp,low(RAMEND)
|
32 | out SPL,temp
|
33 |
|
34 |
|
35 | rcall lcd_init
|
36 |
|
37 |
|
38 | ;------------------------------------------------------
|
39 | ; HAUPTSCHLEIFE
|
40 | ;------------------------------------------------------
|
41 | Hauptschleife:
|
42 |
|
43 |
|
44 |
|
45 | rjmp Hauptschleife
|
46 |
|
47 |
|
48 | ;------------------------------------------------------
|
49 | ; Subroutinen / ISRs
|
50 | ;------------------------------------------------------
|
51 |
|
52 |
|
53 | ;****************************************************************
|
54 | ;* LCD Display Routinen Version 04 *
|
55 | ;****************************************************************
|
56 | ;* Intitialisiert Display mit KS0063 oder kompatiblen *
|
57 | ;* Controller und schreibt einen Text in das Display *
|
58 | ;* *
|
59 | ;* Controller: Mega8 @ 8Mhz (7,3...MHz) *
|
60 | ;* Display: LCD204B LED - Reichelt *
|
61 | ;* Das Programm steuert das LCD Display mit 4 BIT an!! *
|
62 | ;****************************************************************
|
63 | ;
|
64 | ;********************************************************************
|
65 | ;* Anschlussplan Display zum AVR *
|
66 | ;*------------------------------------------------------------------*
|
67 | ;* Pin Belegung Display : Pin Belegung RNMega8 *
|
68 | ;*------------------------------------------------------------------*
|
69 | ;* 1. GND : 01. GND *
|
70 | ;* 2. +5V : 02. +5V *
|
71 | ;* 3. Vo Contrast : 03. über 10k Poti auf +5V *
|
72 | ;* 4. RS Daten oder Code Input : 04. PC2 *
|
73 | ;* 5. R/W : 05. PD6 *
|
74 | ;* 6. Enable : 06. PC3 *
|
75 | ;* 7. DB0 : 07. PB0 *
|
76 | ;* 8. DB1 : 08. PB1 *
|
77 | ;* 9. DB2 : 09. PB2 *
|
78 | ;* 10. DB3 : 10. PB3 *
|
79 | ;* 11. DB4 : 11. PD2 (not used) *
|
80 | ;* 12. DB5 : 12. PD3 (not used) *
|
81 | ;* 13. DB6 : 13. PD4 (not used) *
|
82 | ;* 14. DB7 : 14. PD5 (not used) *
|
83 | ;* 15. Anode LED : 17. +5V über Vorwiderstand R14 *
|
84 | ;* 16. Katode LED : 18. GND *
|
85 | ;********************************************************************
|
86 |
|
87 | ;------------------------------------------------------
|
88 | ; Definierung der Steuerleitungen
|
89 | ;------------------------------------------------------
|
90 | .equ E = PC3 ; Enable Leitung
|
91 | .equ RW = PD6 ; Read / Write Leitung
|
92 | .equ RS = PC2 ; Befehlsleitung
|
93 | .equ Busy = PD5 ; Busy Leitung --> not available (4Bit-Modus)
|
94 |
|
95 |
|
96 | ;------------------------------------------------------------------------------------------
|
97 | ; Definierung der Befehle
|
98 | ;------------------------------------------------------------------------------------------
|
99 | .equ lcdcheck = 0b00110000 ; nur init; kein Konfigurationsbefehl
|
100 | .equ lcdon = 0b00001111 ; LCD einschalten
|
101 | .equ lcdfunction = 0b00101100 ; nur init; Busbreite/LCD-Größe definieren
|
102 | ; |||||+ reserviert
|
103 | ; ||||+- reserviert
|
104 | ; |||+-- F = 1: 5x10 dots ; F = 0: 5x8 dots
|
105 | ; ||+--- N = 1: 2 lines ; N = 0: 1 lines
|
106 | ; |+---- DL = 0: 4bits ; DL = 1: 8 bits
|
107 | ;
|
108 | ;.equ lcdshift = 0b00000000
|
109 | ; S/C = 1 Display shift; S/C = 0 Cursor move
|
110 | ; R/L = 1 shift right; R/L = 0 shift left
|
111 |
|
112 | .equ lcdclear = 0b00000001 ; LCD löschen
|
113 | .equ lcdentry = 0b00000110 ; bei Eingabe eines Zeichen den Cursor um 1 erhöhen
|
114 | .equ zeile2 = 0b11000000 ; Startadresse der zweiten Display Zeile
|
115 |
|
116 | ;------------------------------------------------------------------------
|
117 | ; Definition der Arbeitsregister
|
118 | ;------------------------------------------------------------------------
|
119 | .def up_temp1 = r16 ; Arbeitsregister 1
|
120 | .def up_temp2 = r17 ; Arbeitsregister 2
|
121 | .def up_temp3 = r20 ; Arbeitsregister 3
|
122 | .def up_temp4 = r21 ; Arbeitsregister 4
|
123 | .def tim1 = r18 ; Timerregister 1
|
124 | .def tim2 = r19 ; Timerregister 2
|
125 |
|
126 | ;------------------------------------------------------------------------
|
127 | ; Befehle an das LCD Display
|
128 | ;------------------------------------------------------------------------
|
129 |
|
130 | lcd_init: ;*** Initialisierung des Displays ***
|
131 |
|
132 | ldi up_temp1,0b11111111 ;
|
133 | out ddrb,up_temp1 ; Port B auf Ausgang setzten
|
134 | out ddrc,up_temp1 ; Port C auf Ausgang setzten
|
135 | out ddrd,up_temp1 ; Port D auf Ausgang setzten
|
136 |
|
137 | rcall wait15ms ; 15ms auf Display warten
|
138 |
|
139 | ldi up_temp1,lcdcheck ; LCD-check setzen (muß laut Hersteller 3x in das Steuerregister geschrieben werden )
|
140 | rcall Befehl_an_LCD ; Befehl senden
|
141 | rcall wait15ms ; 15ms+5ms warten
|
142 | ldi up_temp1,lcdcheck ; LCD-check setzen
|
143 | rcall Befehl_an_LCD ; Befehl senden
|
144 | ldi up_temp1,lcdcheck ; LCD-check setzen
|
145 | rcall Befehl_an_LCD ; Befehl senden
|
146 |
|
147 | rcall lcd_on ; Display einschalten
|
148 | rcall lcd_clear ; Display löschen
|
149 | rcall lcd_cursor_rechts ; Verhalten des Cursors festlegen
|
150 |
|
151 | rcall text1 ; Text 1 senden (Begrüßungstext)
|
152 | rcall text2 ; Text 2 senden (Begrüßungstext)
|
153 | ret
|
154 |
|
155 |
|
156 | lcd_on: ;*** LCD einschalten ***
|
157 | ldi up_temp1,lcdon ; LCD einschalten
|
158 | rcall Befehl_an_LCD ; Befehl senden
|
159 | ret
|
160 |
|
161 | lcd_clear: ;*** Löschen des Displays ***
|
162 | ldi up_temp1,lcdclear ; LCD löschen
|
163 | rcall Befehl_an_LCD ; Befehl senden
|
164 | ret
|
165 |
|
166 | lcd_cursor_rechts: ;*** Steuerung des Cursors ***
|
167 | ldi up_temp1,lcdentry ; Entrymode setzten
|
168 | rcall Befehl_an_LCD ; Befehl senden
|
169 | ret
|
170 |
|
171 | lcd_textausgabe: ;*** Sendet Text an das Display ***
|
172 | sbi portc,RS ; setzten BIT RS
|
173 | cbi portd,RW ; lösche BIT RW
|
174 | rcall sende_Daten ; Daten ausgeben
|
175 | rcall wait5ms
|
176 | ret
|
177 |
|
178 |
|
179 | ;------------------------------------------------------------------------
|
180 | ; Hilfsprogramme für das Senden von Befehlen und Daten ans Display
|
181 | ;------------------------------------------------------------------------
|
182 |
|
183 | Befehl_an_LCD: ;Sendet Befehle an das Display
|
184 | cbi portc,RS ; lösche BIT RS
|
185 | cbi portd,RW ; lösche BIT RW
|
186 | rcall sende_Daten ; Befehl ausgeben
|
187 | rcall wait5ms
|
188 | ret
|
189 |
|
190 |
|
191 | sende_Daten: ;UP für Befehle/Text versenden
|
192 | ;sende high Nibble
|
193 | mov up_temp3,up_temp1
|
194 | swap up_temp3
|
195 | andi up_temp3, 0b00001111
|
196 | out portD, up_temp3
|
197 |
|
198 | sbi portc,E ; setzten BIT E
|
199 | nop ; kein Operation (warten)
|
200 | nop
|
201 | nop
|
202 | cbi portc,E ; lösche BIT E
|
203 |
|
204 | ;sende low Nibble
|
205 | andi up_temp1,0b00001111
|
206 | out portD, up_temp1
|
207 |
|
208 | sbi portc,E ; setzen BIT E
|
209 | nop ; kein Operation (warten)
|
210 | nop
|
211 | nop
|
212 | cbi portc,E ; lösche BIT E
|
213 | ret
|
214 |
|
215 |
|
216 | ; **** Zeitschleifen ****
|
217 |
|
218 | wait50us:
|
219 | ldi tim1, (F_CPU * 50 / 3 / 1000000)
|
220 | wait51: ; Schleife benötigt 3 Taktzyklen
|
221 | dec tim1
|
222 | brne wait51
|
223 | ret
|
224 |
|
225 | wait150us:
|
226 | rcall wait50us
|
227 | rcall wait50us
|
228 | rcall wait50us
|
229 | ret
|
230 |
|
231 | wait5ms:
|
232 | ldi tim2,100
|
233 | wait5:
|
234 | rcall wait50us
|
235 | dec tim2
|
236 | brne wait5
|
237 | ret
|
238 |
|
239 | wait15ms:
|
240 | rcall wait5ms
|
241 | rcall wait5ms
|
242 | rcall wait5ms
|
243 | ret
|
244 |
|
245 |
|
246 | ; **** Definierung der Texte mit Position ****
|
247 | text1:
|
248 |
|
249 | ldi up_temp4,14 ; entspricht der Länge der ersten Zeichenkette in Tabelle1
|
250 | ldi zl,low(tabelle1*2) ; Zeige auf Z-Pointer Lowbyte von Tabelle1
|
251 | ldi zh,high(tabelle1*2) ; Zeige auf Z-Pointer Highbyte von Tabelle1
|
252 | loop_msg1:
|
253 | lpm ; lade R0 mit Wert auf der der Z-Pointer zeigt
|
254 | mov up_temp1,r0 ; kopiere R0 in up_temp1
|
255 | rcall lcd_textausgabe ; Daten senden
|
256 | ; adiw zl:zh,1 ; Z-Pointer + 1
|
257 | adiw zl,1 ; Z-Pointer + 1
|
258 | no_carry1:
|
259 | dec up_temp4 ; up_temp4 - 1
|
260 | brne loop_msg1 ; vergleiche auf Null, wenn nich springe
|
261 | ret
|
262 |
|
263 | text2:
|
264 | ldi up_temp1,zeile2 ; setzte Cursor in zweite Zeile (Anfang)
|
265 | rcall Befehl_an_LCD ; Befehl senden
|
266 |
|
267 | ldi up_temp4,16 ; entspricht der Länge der ersten Zeichenkette in Tabelle1
|
268 | ldi zl,low(tabelle2*2) ; Zeige auf Z-Pointer Lowbyte von Tabelle1
|
269 | ldi zh,high(tabelle2*2) ; Zeige auf Z-Pointer Highbyte von Tabelle1
|
270 | loop_msg2:
|
271 | lpm ; lade R0 mit Wert auf der der Z-Pointer zeigt
|
272 | mov up_temp1,r0 ; kopiere R0 in up_temp1
|
273 | rcall lcd_textausgabe ; Daten senden
|
274 | ; adiw zl:zh,1 ; Z-Pointer + 1
|
275 | adiw zl,1 ; Z-Pointer + 1
|
276 | no_carry2:
|
277 | dec up_temp4 ; up_temp4 - 1
|
278 | brne loop_msg2 ; vergleiche auf Null, wenn nicht springe
|
279 | ret
|
280 |
|
281 | tabelle1:
|
282 |
|
283 | .db "please wait..."
|
284 |
|
285 | tabelle2:
|
286 |
|
287 | .db "system coming up"
|