ADC_Test.asm


1
;*-------------------------------------------------
2
;* Analog-Digital-Wandlung
3
;* mit Analog-Komparator
4
;* - - - - - - - - - - - - - - - - - - - - - - - -
5
;* Port B Bit 0 RC-Glied 1uF/10 kOhm
6
;* Port B Bit 1 Mess-Spannung
7
;* Port B Bit 3 Timer-PWM-Ausgang
8
;* MCU ATTiny4313, Takt 4 MHz
9
;* PortD LCD Ausgabe:   R/W=GND
10
;* PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0
11
;* n/a LED ena rs  D7  D6  D5  D4
12
;* Adapter auf LCD-Port:
13
;* PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0
14
;*  D7  D6  D5  D4  LED n/a ena rs
15
; ATtiny4313 memory use summary [bytes]:
16
; Segment   Begin    End  Code Data Used Size  Use%
17
;--------------------------------------------------
18
;[.cseg] 0x000000 0x0002a6 650   28  678 4096 16.6%
19
;[.dseg] 0x000060 0x000060   0    0    0  256  0.0%
20
;[.eseg] 0x000000 0x000000   0    0    0  256  0.0%
21
;Assembly complete, 0 errors. 0 warnings
22
;--------------------------------------------------  
23
;
24
.nolist
25
.include "tn4313def.inc"
26
.list
27
;
28
.def  temp = r16  ; Temporaerregister 1
29
.def  temp1 = r17  ; Temporaerregister 2
30
.def  temp2 = r18  ; Temporaerregister 3 
31
.def  temp3 = r19  ; Temporaerregister 4 
32
.equ daten = portd  ; PortD nur 7 Bit Breite, Bit 7 fehlt
33
.equ rs = 4      ; 0bn00x0000 Portbit Register Select
34
.equ ena = 5    ; 0bn0x00000 Portbit Enable
35
.equ licht = 6      ; 0bnx000000 Portbit LCD-Beleuchtung
36
.equ zeit0 = 200    ; Zeitschleifen Ladewerte
37
.equ zeit1 = 65535
38
.cseg
39
.org  0x0000
40
rjmp main      ; zum Hauptprogramm
41
;
42
main:
43
ldi  temp,  low(ramend)  ; Stackpointer initialisieren
44
out  spl,  temp       
45
ldi  temp,  high(ramend) 
46
out  sph,  temp      ; 
47
ldi  temp,  0xFF    ; Ports einrichten 
48
out  ddrb,  temp    ; PortB A/D 
49
out portb,   temp    ; Pullups setzen
50
out ddrd,   temp    ; PortD Ausgabe LCD
51
out portd,  temp    ; Pullups setzen  
52
rcall lcdinit
53
ldi  temp,  0x18    ; Watchdog enable (1<<WDCE)|(1<<WDE);=dec24 change-ena/+enable
54
out  WDTCR,  temp
55
ori  temp,  (1<<WDE)|(1<<WDP2)|(1<<WDP1);0x0E; Prescaler Set (1<<WDE)|(1<<WDP2)|(1<<WDP1)
56
out  WDTCR,  temp    ; ca. 1 sec timeout ;=dec30
57
wdr
58
; 
59
rcall  ad_init      ; A/D-Konverter initialisieren
60
rcall legende1
61
rcall legende2
62
rjmp  endlos1
63
;
64
endlos1:
65
wdr
66
rcall  adc_on1
67
lsr  temp
68
push  temp1
69
push  temp
70
ldi temp, 0x8D
71
rcall comd2lcd
72
pop temp
73
mov  temp1,  temp
74
rol temp1    ; Max. Anzeige 255 statt 127
75
rcall  bin2dec
76
push  temp
77
ldi temp, 0xCD
78
rcall comd2lcd
79
pop temp
80
mov  temp1,  temp
81
rol temp1    ; Max. Anzeige 255 statt 127
82
rcall  bin2dec
83
mov  temp1,  temp
84
pop  temp1
85
clr  temp
86
rjmp endlos1
87
;
88
legende1:      ; Festtext: "Messwert_1 ="
89
ldi  temp,  0x80    ; Positionierung Anfang
90
rcall  comd2lcd    ; Zeile 1, Spalte 1
91
rcall  wait2
92
ldi  ZL,  LOW(text1*2)  ; Adresse des Strings in den
93
ldi  ZH,  HIGH(text1*2)  ; Z-Pointer laden
94
rcall  print      ; Funktion print aufrufen
95
rcall  wait3
96
ret        
97
;
98
print:
99
lpm        ; erstes Byte des Strings nach R0 lesen
100
mov temp, r0      ; R0 auf 0 testen
101
cpi temp, 0x00  ; alternativer Befehl
102
breq  print_end    ; wenn 0, dann zu print_end
103
mov temp1, temp    ; Datenausgabe hier nur ueber temp1
104
rcall  char2lcd
105
adiw  ZL:ZH,  1    ; Adresse des Z-Pointers um 1 erhoehen
106
rjmp  print      ; zum Anfang springen, um naechstes 
107
;        ; Byte aus dem cseg-Label text1;zu holen
108
print_end:
109
rcall  wait3
110
ret
111
;
112
text1:
113
.db "Messwert_1 = ",0
114
;
115
legende2:      ; Festtext: "Messwert_2 ="
116
ldi  temp,  0xC0    ; Positionierung Anfang
117
rcall  comd2lcd    ; Zeile 1, Spalte 1
118
rcall  wait2
119
ldi  ZL,  LOW(text2*2)  ; Adresse des Strings in den
120
ldi  ZH,  HIGH(text2*2)  ; Z-Pointer laden
121
rcall  print1      ; Funktion print aufrufen
122
rcall  wait3
123
ret        
124
;
125
print1:
126
lpm  temp, Z+      ; erstes Byte des Strings nach temp lesen
127
tst temp        ; temp auf 0 testen
128
breq  print_end    ; wenn 0, dann zu print_end
129
mov temp1, temp    ; Datenausgabe hier nur ueber temp1
130
rcall  char2lcd
131
rjmp  print1      ; zum Anfang springen, um naechstes 
132
;        ; Byte aus dem cseg-Label text1;zu holen
133
text2:
134
.db "Messwert_2 = ",0
135
;
136
ad_init:
137
wdr
138
push   temp
139
;ldi temp, 0x00
140
;out ddrb, temp
141
cbi  ddrb, 0
142
;out portb, temp
143
cbi  portb,  0
144
cbi  ddrb,  1
145
cbi  portb,  1
146
;ldi temp, 0b00001000
147
;out ddrb,temp
148
sbi  ddrb,  3
149
clr  temp
150
out  OCR1AH,  temp
151
out  OCR1AL,  temp
152
ldi  temp,  0x81
153
out  TCCR1A,  temp
154
ldi  temp,  0x01
155
out  TCCR1B,  temp
156
ldi  temp,  0x13
157
out  ACSR,  temp
158
pop  temp
159
ret
160
;
161
adc_on1:
162
wdr
163
push  temp1
164
push  temp2
165
clr  temp1
166
out  OCR1AH,  temp1
167
out  OCR1AL,  temp1
168
cbi  portb,  0
169
sbi  ddrb,  0
170
clr  temp
171
rjmp  pause_
172
;
173
pause_:
174
wdr
175
nop
176
dec   temp
177
brne  pause_
178
cbi  ddrb,  0
179
ldi  temp,  0x00
180
rjmp  adc_on2
181
;
182
adc_on2:
183
wdr
184
in  temp2,  TIFR
185
sbrs  temp2,  7
186
rjmp  adc_on2
187
ori  temp2,  0x80
188
out  TIFR,  temp2
189
out  OCR1AH,  temp1
190
out  OCR1AL,  temp
191
sbic  ACSR, ACO
192
rjmp  adc_on3
193
cpi  temp,  0xFF
194
breq  adc_on3
195
inc  temp
196
rjmp  adc_on2
197
;
198
adc_on3:
199
wdr
200
out  OCR1AH,  temp1
201
out  OCR1AL,  temp1
202
pop  temp2
203
pop  temp1
204
ret
205
;
206
;**LCD-Initialisierung - LCD - Ausgabe-Routinen**
207
lcdinit:
208
rcall wait1      ; LCD Power On Self Reset abwarten
209
push temp      ; Sicherung Temporaer- und     
210
push temp1      ; Statusregister auf Stapel
211
in temp1,SREG
212
push temp1
213
rcall lcd_reset    ; LCD-Bus-Reset
214
rcall lcd_achtbit  ; LCD-Init: acht Bit  
215
rcall lcd_acht_vier  ; LCD-Init: acht zu vier Bit
216
rcall lcd_vier_zwei  ; LCD-Init: vier Bit, zwei Zeilen
217
rcall lcd_on_off  ; LCD-Init: Displaypuffer aus
218
rcall lcd_clear    ; LCD-Init: Anzeige löschen  
219
rcall lcd_entrymode  ; LCD-Init: Entry Mode Set
220
pop temp1      ; Wiederherstellung Temporaer-
221
out SREG,temp1    ; und Statusregister
222
pop temp1
223
pop temp
224
ret
225
;
226
lcd_reset:      ; LCD-Bus Reset
227
push temp      ; Temporaerregister auf Stack retten
228
cbi daten, rs    ; RS=0
229
ldi temp,0x00    ; Reset des LCD-Ausgabeports  
230
out daten,temp
231
rcall enable    ; Enable-Impuls toggeln
232
rcall wait3
233
pop temp      ; Temporaerregister wiederherstellen
234
ret
235
;
236
lcd_achtbit:    ; Acht-Bit-Init
237
push temp      ; an folgende Portbelegung angepasst:
238
;          ; PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0
239
;          ; n/a LED ena rs D7  D6  D5  D4
240
ldi temp,0x03    ; dreimal hex 0x03
241
cbi daten, rs    ; RS=0
242
out daten,temp    ; immer notwendig, wenn
243
rcall enable    ; einmal 8/4-Bit-Modus
244
rcall wait3      ; gewechselt wurde, dabei 
245
ldi temp, 0x03    ; jedesmal      
246
cbi daten, rs    ; RS=0
247
out daten,temp    ; auf Port ausgeben
248
rcall enable    ; Enable-Impuls senden, dann 
249
rcall wait3      ; Pausen folgen lassen
250
ldi temp, 0x03    
251
cbi daten, rs
252
out daten,temp
253
rcall enable
254
rcall wait3
255
pop temp
256
ret
257
;
258
lcd_acht_vier:    ; Acht-zu-Vier-Bit-Modus-Wechsel
259
push temp
260
cbi daten, rs    ; RS=0
261
ldi temp,0x02    ; zunaechst nur 4-Bit-Modus
262
out daten,temp    ; obere vier Bit werden
263
rcall enable    ; ignoriert, aber immer noch
264
rcall wait3      ; 8-Bit-Befehlsbreite
265
pop temp
266
ret
267
;
268
lcd_vier_zwei:    ; Vier-Bit_modus, zwei Zeilen
269
push temp
270
cbi daten,rs    ; RS=0
271
ldi temp,0x28    ; dann Vier-Bit-Modus, zweizeilig
272
rcall comd2lcd    ; ab hier werden Steuerbefehle
273
rcall wait3      ; auch im Vier-Bit-Modus ueber
274
pop temp      ; Unterprogramm "comd2lcd" gesendet
275
ret      
276
;
277
lcd_on_off:      ; On-off-Control
278
push temp      ; Displaypuffer ein-, ausschalten
279
cbi daten, rs    ; RS=0
280
ldi temp, 0x08    ; Displaypuffer aus, Blinken aus, 
281
rcall comd2lcd    ; kein Cursor
282
rcall wait3
283
pop temp
284
ret
285
;
286
lcd_clear:      ; Anzeige loeschen
287
push temp
288
cbi daten, rs    ; RS=0
289
ldi temp,0x01    ; Anzeige wird im Space-Modus
290
rcall comd2lcd    ; geloescht, dauert laenger... 
291
rcall wait3      ; ... Pause laenger
292
rcall wait3
293
pop temp
294
ret
295
;
296
lcd_entrymode:    ; Entry/Shift Mode Set
297
push temp
298
cbi daten, rs    ; RS=0
299
ldi temp,0x06    ; Cursor von rechts nach links
300
rcall comd2lcd    ; kein Schieben
301
rcall wait3
302
cbi daten, rs    ; RS=0
303
ldi temp,0x10    ; kein Schieben, Cursorbewegung 
304
rcall comd2lcd    ; nach rechts
305
rcall wait3
306
cbi daten, rs    ; RS=0
307
ldi temp,0x0C    ; Anzeige wieder einschalten
308
rcall comd2lcd    ; Cursor aus, Blinken aus
309
rcall wait3
310
cbi daten, rs    ; RS=0
311
ldi temp,0x01    ; Anzeige nochmals loeschen
312
rcall comd2lcd
313
rcall wait3
314
pop temp
315
ret
316
;
317
char2lcd:      ; gibt Charakter auf "temp" ueber LCD aus
318
cbi daten,licht    ; LCD-Hintergrundbeleuchtung aus
319
push temp      ; rettet temps auf Stapel
320
push temp1
321
mov temp, temp1
322
mov temp1, temp    ; Kopie fuer Nachfolge-Operation
323
andi temp, 0xF0    ; unteres Daten-Nibble ausblenden
324
swap temp      ; an Portbelegung anpassen...
325
andi temp, 0x0F    ; oberes Portbit-Nibble ausblenden
326
ori temp, 0b00010000 ; RS=high
327
out daten,temp    ; Ausgabe D4-D7-Daten-Nibble auf Port D0-D3
328
rcall enable    ; Enableimpuls 
329
andi temp1, 0x0F  ; oberes Portbit-Nibble ausblenden  
330
ori temp1, 0b00010000 ; RS=high
331
out daten,temp1    ; Ausgabe D0-D3-Daten-Nibble auf D0-D3
332
rcall enable    ; Enableimpuls
333
sbi daten,licht    ; Hintergrundbeleuchtung ein
334
pop temp1      ; Zurueckholen von temps
335
pop temp
336
rcall wait2      ; Verarbeitungszeit LCD abwarten
337
ret
338
;
339
comd2lcd:      ; sendet Steuerzeichen auf "temp" an LCD
340
push temp      ; rettet "temps" auf Stapel
341
push temp1
342
mov temp1,temp    ; Kopie fuer Nachfolge-Operation
343
andi temp, 0xF0    ; unteres Daten-Nibble ausblenden
344
swap temp      ; an Portbelegung anpassen...
345
andi temp, 0x0F    ; oberes Portbit-Nibble ausblenden; RS=0
346
out daten,temp    ; Ausgabe D4-D7-Daten-Nibble auf Port D0-D3
347
rcall enable    ; Enableimpuls 
348
andi temp1, 0x0F  ; oberes Portbit-Nibble ausblenden; RS=0
349
out daten,temp1    ; Ausgabe D0-D3-Daten-Nibble auf D0-D3
350
rcall enable    ; Enableimpuls senden
351
pop temp1      ; Zurueckholen von temps
352
pop temp
353
rcall wait2      ; Verarbeitungszeit LCD abwarten
354
ret
355
;
356
enable:        ; Enableimpuls-Generierung
357
nop
358
sbi daten, ena    ; Portbit "Enable" auf high
359
nop          ; Zeitverzoegerung mindestens
360
nop          ; 1000 ns laut Datenblatt LCD
361
nop
362
nop
363
nop
364
nop
365
cbi daten, ena    ; Portbit "Enable" auf low zuruecksetzen
366
nop
367
ret
368
;
369
bin2dec:      ; Umwandlung "temp1" 8 bit binaer auf  
370
wdr          ; ASCII dezimal, 3 Stellen mit fuehrenden
371
push  temp    ; Nullen
372
push  temp1
373
push  temp2
374
mov  temp2,  temp1  ; Anzahl Hunderter abzaehlen
375
ldi  temp1,  0x30  ; ASCII "Ziffer Null" vorladen
376
rjmp  num_1
377
;
378
num_1:
379
subi  temp2,  100  ; zieht Wert 100 von temp2 ab
380
brcs  num_2    ; springt zur Ausgabe, wenn negativer
381
inc  temp1      ; Uebertrag entstanden
382
rjmp  num_1    ; Ausgabe Anzahl Schleifendurchlaeufe
383
;
384
num_2:
385
rcall  char2lcd
386
subi  temp2,  -100; zaehlt 100 wieder dazu, da die
387
ldi  temp1, 0x30    ; Schleife davor 100 zuviel abzog
388
;          ; Anzahl Zehner abzaehlen
389
num_3:
390
subi  temp2,  10  ; zieht Wert 10 ab
391
brcs  num_4    ; springt zur Ausgabe, wenn negativer
392
inc  temp1      ; Uebertrag entstanden
393
rjmp  num_3    ; Ausgabe Anzahl Schleifendurchlaeufe
394
;
395
num_4:
396
rcall  char2lcd
397
subi  temp2,  -10  ; zaehlt 10 wieder dazu, da die
398
;          ; Schleife davor 10 zuviel abzog
399
ldi  temp1, 0x30    ; addiert ASCII-Code zu Einer hinzu
400
add  temp1,  temp2
401
rcall  char2lcd   ; Ausgabe Einer
402
pop  temp2
403
pop  temp1
404
pop  temp    
405
ret
406
;
407
wait1:      ; Verzoegerungsschleifen fuer LCD
408
rcall wait3
409
rcall wait3
410
rcall wait3
411
ret
412
;
413
wait2:      ;Verzoegerungsschleife 2
414
push xl
415
push xh
416
push temp      ;Register sichern auf Stapel
417
push temp1      ;Sicherung von Temporaerregistern
418
in temp1, SREG    ;und Statusregister auf Stapel
419
push temp1      ;bei Interrupts notwendig
420
ldi xl, low(zeit0)  ;laedt Zaehlregisterpaar mit
421
ldi xh, high(zeit0)  ;oben deklariertem Wert "Zeit0"
422
rjmp repeatx
423
;
424
wait3:      ;Verzoegerungsschleife 3
425
push xl
426
push xh
427
push temp      ;Register sichern auf Stapel
428
push temp1      ;Sicherung von Temporaerregistern
429
in temp1, SREG    ;und Statusregister auf Stapel
430
push temp1      ;bei Interrupts notwendig
431
ldi xl, low(zeit1)  ;laedt Zaehlregisterpaar mit
432
ldi xh, high(zeit1)  ;oben deklariertem Wert "Zeit1"
433
rjmp repeatx
434
;
435
repeatx:      ;16-Bit-Subtraktionsschleife:
436
sbiw xl:xh, 1    ;decrementiert Doppelregister
437
brne repeatx    ;zaehlt bis Null
438
pop temp1      ;Wiederherstellung von
439
out SREG, temp1    ;geretteten"Registern
440
pop temp1
441
pop temp
442
pop xh
443
pop xl
444
ret
445
;