1 | /*
|
2 | * LCDTEST5.asm
|
3 | *
|
4 | * Created: 20.04.2014 16:14:50
|
5 | * Author: Fritz
|
6 | */
|
7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
8 | ;;Steureung eines LCD
|
9 | ;;
|
10 | ;;PortD ausgang:
|
11 | ;;0 - Db0
|
12 | ;;1 - Db1
|
13 | ;;2 - Db2
|
14 | ;;3 - Db3
|
15 | ;;4 - Db4
|
16 | ;;5 - Db5
|
17 | ;;6 - Db6
|
18 | ;;7 - Db7
|
19 | ;;
|
20 | ;;PortB ausgang:
|
21 | ;;0 - RS
|
22 | ;;1 - E
|
23 | ;;2 - Kontroll LED1
|
24 | ;;3 - Leer
|
25 | ;;4 - Leer
|
26 | ;;5 - Leer
|
27 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
28 |
|
29 |
|
30 | ;;;;;;;;;;;;AVRinit;;;;;;;;;;;;
|
31 | .include "m8adef.inc"
|
32 |
|
33 |
|
34 |
|
35 | ;Reset and Interrupt vector ;VNr. Beschreibung
|
36 | rjmp main ;1 POWER ON RESET
|
37 | reti ;2 Int0-Interrupt
|
38 | reti ;3 Int1-Interrupt
|
39 | reti ;4 TC2 Compare Match
|
40 | reti ;5 TC2 Overflow
|
41 | reti ;6 TC1 Capture
|
42 | reti ;7 TC1 Compare Match A
|
43 | reti ;8 TC1 Compare Match B
|
44 | reti ;9 TC1 Overflow
|
45 | reti ;10 TC0 Overflow
|
46 | reti ;11 SPI, STC Serial Transfer Complete
|
47 | reti ;12 UART Rx Complete
|
48 | reti ;13 UART Data Register Empty
|
49 | reti ;14 UART Tx Complete
|
50 | reti ;15 ADC Conversion Complete
|
51 | reti ;16 EEPROM Ready
|
52 | reti ;17 Analog Comparator
|
53 | reti ;18 TWI (I²C) Serial Interface
|
54 | reti ;19 Store Program Memory Ready
|
55 | ;------------------------------------------------------------------------
|
56 |
|
57 | main:
|
58 |
|
59 | ldi r16, LOW(RAMEND) ;Stackinit
|
60 | out SPL, r16
|
61 | ldi r16, HIGH(RAMEND)
|
62 | out SPH, r16
|
63 |
|
64 | ldi r16,0b00000101
|
65 | out DDRC,r16
|
66 | out PORTC,r16
|
67 | .def temp = r16
|
68 | .def temp2 = r20
|
69 | .def temp3 = r21
|
70 | .def DHTmaske = r22
|
71 | .equ LCD_PORT = PORTD
|
72 | .equ LCD_DDR = DDRD
|
73 | .equ LCDS_PORT = PORTD
|
74 | .equ LCDS_DDR = DDRD
|
75 | .equ LCD_RS = 1
|
76 | .equ LCD_RW = 2
|
77 | .equ LCD_E = 3
|
78 | .equ RH_H =0x0060
|
79 | .equ RH_2 =0x0065
|
80 | ;.equ RH_L =0x0061
|
81 | ;.equ Temp_H =0x0062
|
82 | ;.equ Temp_L =0x0063
|
83 | ;.equ checksumme =0x0064
|
84 | .equ sensor1 =0x45
|
85 | .equ sensor2 =0x19
|
86 |
|
87 |
|
88 | .def arg = r17 ;argument for calling subroutines
|
89 | .def arg2 = r18 ;argument for mathematics
|
90 | .def return = r19 ;return value from subroutines
|
91 | .def byte = r25
|
92 |
|
93 |
|
94 | ;;;;;;LCDinit;;;;;;
|
95 |
|
96 | ;wartezeit zur initialisirung des
|
97 | ldi temp,200
|
98 | rcall waitMs
|
99 | rcall LCD_init
|
100 |
|
101 |
|
102 | ldi ZL,LOW(text*2)
|
103 | ldi ZH,HIGH(text*2)
|
104 | ldi arg,0x00
|
105 | rcall LCD4ZTxt
|
106 |
|
107 | ldi YH,HIGH(RH_2)
|
108 | ldi YL,LOW(RH_2)
|
109 | ldi DHTmaske,0x01
|
110 | ldi arg,0x46
|
111 | rcall LCD_pos
|
112 | rcall DHT_lesen
|
113 |
|
114 | rcall wait2s
|
115 |
|
116 | ldi DHTmaske,0x04
|
117 | ; out DDRC,DHTmaske
|
118 | ; out PORTC,DHTmaske
|
119 | ldi YH,HIGH(RH_H)
|
120 | ldi YL,LOW(RH_H)
|
121 |
|
122 | ldi arg,0x1a
|
123 | rcall LCD_pos
|
124 | rcall DHT_lesen
|
125 |
|
126 |
|
127 |
|
128 |
|
129 | ; ldi temp,1
|
130 | ; rcall waitMs
|
131 |
|
132 |
|
133 |
|
134 | ; mov arg,byte
|
135 | ; rcall LCD_number
|
136 | ; ldi arg,0x40
|
137 | ; rcall LCD_pos
|
138 | ; mov arg,byte
|
139 | ; rcall LCD_alsBit
|
140 | ; ldi arg,0x14
|
141 | ; rcall LCD_pos
|
142 | ; ldi arg,0x43
|
143 | ; rcall LCD_alsBit
|
144 |
|
145 | ; rcall DHT_lesen
|
146 |
|
147 |
|
148 | ;;;;;;Main;;;;;;
|
149 | ;durch diese Routine
|
150 |
|
151 | Auto: ;takt das nächste zeichen auf dem display
|
152 |
|
153 | ;rcall LCD_clear ;zu sehen sein
|
154 |
|
155 | ;inc LCDtoSend
|
156 | wdr
|
157 |
|
158 |
|
159 | rjmp Auto
|
160 |
|
161 |
|
162 |
|
163 | ;;;;;;Routinen;;;;;;
|
164 |
|
165 |
|
166 | ;***********************************************************************************
|
167 | ; the following source is from AVRbeginners.net .great work- well documented
|
168 | ; the advantage of read the busyflag in 4-bit mode is, no delay's needed
|
169 | ;***********************************************************************************
|
170 | LCD_command8: ;used for init (we need some 8-bit commands to switch to 4-bit mode!)
|
171 | in temp, LCD_DDR ;we need to set the high nibble of DDRD while leaving
|
172 | ;the other bits untouched. Using temp for that.
|
173 | sbr temp, 0b11110000 ;set high nibble in temp
|
174 | out LCD_DDR, temp ;write value to DDRD again
|
175 | in temp, LCD_PORT ;then get the port value
|
176 | cbr temp, 0b11110000 ;and clear the data bits
|
177 | cbr arg, 0b00001111 ;then clear the low nibble of the arg
|
178 | ;so that no control line bits are overwritten
|
179 | or temp, arg ;then set the data bits (from the arg) in the
|
180 | ;Port value
|
181 | out LCD_PORT, temp ;and write the port value.
|
182 | sbi LCDS_PORT, LCD_E ;now strobe E
|
183 | nop
|
184 | nop
|
185 | nop
|
186 | cbi LCDS_PORT, LCD_E
|
187 | in temp, LCD_DDR ;get DDRD to make the data lines input again
|
188 | cbr temp, 0b11110000 ;clear data line direction bits
|
189 | out LCD_DDR, temp ;and write to DDRD
|
190 | ret
|
191 |
|
192 | LCD_putchar:
|
193 | push arg ;save the argmuent (it's destroyed in between)
|
194 | in temp, LCD_DDR ;get data direction bits
|
195 | sbr temp, 0b11110000 ;set the data lines to output
|
196 | out LCD_DDR, temp ;write value to DDRD
|
197 | in temp, LCD_PORT ;then get the data from PortD
|
198 |
|
199 | ;.if LCDS_DDR == LCD_DDR ;if the same port
|
200 |
|
201 | cbr temp, 0b11111110 ;clear ALL LCD lines (data and control!)
|
202 | ;.else
|
203 | ; cbr temp, 0b11110000
|
204 | ;.endif
|
205 | ;cbr temp, 0b11111110 ;clear ALL LCD lines (data and control!)
|
206 |
|
207 | cbr arg, 0b00001111 ;we have to write the high nibble of our arg first
|
208 | ;so mask off the low nibble
|
209 | or temp, arg ;now set the arg bits in the Port value
|
210 | out LCD_PORT, temp ;and write the port value
|
211 | sbi LCDS_PORT, LCD_RS ;now take RS high for LCD char data register access
|
212 | sbi LCDS_PORT, LCD_E ;strobe Enable
|
213 | nop
|
214 | nop
|
215 | nop
|
216 | cbi LCDS_PORT, LCD_E
|
217 | pop arg ;restore the arg, we need the low nibble now...
|
218 | cbr temp, 0b11110000 ;clear the data bits of our port value
|
219 | swap arg ;we want to write the LOW nibble of the argument to
|
220 | ;the LCD data lines, which are the HIGH port nibble!
|
221 | cbr arg, 0b00001111 ;clear unused bits in argument
|
222 | or temp, arg ;and set the required argument bits in the port value
|
223 | out LCD_PORT, temp ;write data to port
|
224 | sbi LCDS_PORT, LCD_RS ;again, set RS
|
225 | sbi LCDS_PORT, LCD_E ;strobe Enable
|
226 | nop
|
227 | nop
|
228 | nop
|
229 | cbi LCDS_PORT, LCD_E
|
230 | cbi LCDS_PORT, LCD_RS
|
231 | in temp, LCD_DDR
|
232 | cbr temp, 0b11110000 ;data lines are input again
|
233 | out LCD_DDR, temp
|
234 | ret
|
235 |
|
236 | LCD_command: ;same as LCD_putchar, but with RS low!
|
237 | push arg
|
238 | in temp, LCD_DDR
|
239 | sbr temp, 0b11110000
|
240 | out LCD_DDR, temp
|
241 | in temp, LCD_PORT
|
242 | ;cbr temp, 0b11111110
|
243 | ;.if LCDS_DDR == LCD_DDR ;if the same port then
|
244 | cbr temp, 0b11111110 ;clear ALL LCD lines (data and control!)
|
245 | ;.else
|
246 | ; cbr temp, 0b11110000
|
247 | ;.endif
|
248 | cbr arg, 0b00001111
|
249 | or temp, arg
|
250 |
|
251 | out LCD_PORT, temp
|
252 | sbi LCDS_PORT, LCD_E
|
253 | nop
|
254 | nop
|
255 | nop
|
256 | cbi LCDS_PORT, LCD_E
|
257 | pop arg
|
258 | cbr temp, 0b11110000
|
259 | swap arg
|
260 | cbr arg, 0b00001111
|
261 | or temp, arg
|
262 | out LCD_PORT, temp
|
263 | sbi LCDS_PORT, LCD_E
|
264 | nop
|
265 | nop
|
266 | nop
|
267 | cbi LCDS_PORT, LCD_E
|
268 | in temp, LCD_DDR
|
269 | cbr temp, 0b11110000
|
270 | out LCD_DDR, temp
|
271 | ret
|
272 |
|
273 | LCD_getchar:
|
274 | in temp, LCD_DDR ;make sure the data lines are inputs
|
275 | andi temp, 0b00001111 ;so clear their DDR bits
|
276 | out LCD_DDR, temp
|
277 | sbi LCDS_PORT, LCD_RS ;we want to access the char data register, so RS high
|
278 | sbi LCDS_PORT, LCD_RW ;we also want to read from the LCD -> RW high
|
279 | sbi LCDS_PORT, LCD_E ;while E is high
|
280 | nop
|
281 | in temp, PinD ;we need to fetch the HIGH nibble
|
282 | andi temp, 0b11110000 ;mask off the control line data
|
283 | mov return, temp ;and copy the HIGH nibble to return
|
284 | cbi LCDS_PORT, LCD_E ;now take E low again
|
285 | nop ;wait a bit before strobing E again
|
286 | nop
|
287 | sbi LCDS_PORT, LCD_E ;same as above, now we're reading the low nibble
|
288 | nop
|
289 | in temp, PinD ;get the data
|
290 | andi temp, 0b11110000 ;and again mask off the control line bits
|
291 | swap temp ;temp HIGH nibble contains data LOW nibble! so swap
|
292 | or return, temp ;and combine with previously read high nibble
|
293 | cbi LCDS_PORT, LCD_E ;take all control lines low again
|
294 | cbi LCDS_PORT, LCD_RS
|
295 | cbi LCDS_PORT, LCD_RW
|
296 | ret ;the character read from the LCD is now in return
|
297 |
|
298 | LCD_getaddr: ;works just like LCD_getchar, but with RS low, return.7 is the busy flag
|
299 | in temp, LCD_DDR
|
300 | andi temp, 0b00001111
|
301 | out LCD_DDR, temp
|
302 | cbi LCDS_PORT, LCD_RS
|
303 | sbi LCDS_PORT, LCD_RW
|
304 | sbi LCDS_PORT, LCD_E
|
305 | nop
|
306 | in temp, PinD
|
307 | andi temp, 0b11110000
|
308 | mov return, temp
|
309 | cbi LCDS_PORT, LCD_E
|
310 | nop
|
311 | nop
|
312 | sbi LCDS_PORT, LCD_E
|
313 | nop
|
314 | in temp, PinD
|
315 | andi temp, 0b11110000
|
316 | swap temp
|
317 | or return, temp
|
318 | cbi LCDS_PORT, LCD_E
|
319 | cbi LCDS_PORT, LCD_RW
|
320 | ret
|
321 |
|
322 | LCD_wait: ;read address and busy flag until busy flag cleared
|
323 |
|
324 | rcall LCD_getaddr
|
325 | andi return, 0x80
|
326 | brne LCD_wait
|
327 | ret
|
328 |
|
329 |
|
330 | LCD_delay:
|
331 | clr r2
|
332 | LCD_delay_outer:
|
333 | clr r3
|
334 | LCD_delay_inner:
|
335 | dec r3
|
336 | brne LCD_delay_inner
|
337 | dec r2
|
338 | brne LCD_delay_outer
|
339 | ret
|
340 |
|
341 | LCD_init:
|
342 | ;**** for the most LCD you must write 3times a dummy command before you change to 4Bit***
|
343 | ;this is corrected by www.bellibot.com :-)) - before !you have only one LineLCD ***
|
344 |
|
345 | ldi temp, 0b00001110 ;control lines are output, rest is input
|
346 | in temp,LCD_DDR
|
347 | andi temp,0b00001111 ;LCD pins input
|
348 | out LCD_DDR,temp
|
349 | in temp,LCDS_DDR
|
350 | ori temp, (1<<LCD_RS)|(1<<LCD_RW)|(1<<LCD_E) ;controllpins output
|
351 | out LCDS_DDR, temp
|
352 |
|
353 | rcall LCD_delay ;
|
354 | ldi arg, 0x30 ;
|
355 | rcall LCD_command8
|
356 |
|
357 | rcall LCD_delay
|
358 | ldi arg, 0x30 ;NOW: 2 lines, 5*7 font, 4-BIT MODE! ** DUMMY ***
|
359 | rcall LCD_command8 ;
|
360 |
|
361 |
|
362 | rcall LCD_delay
|
363 | ldi arg, 0x30
|
364 | rcall LCD_command8
|
365 |
|
366 | rcall LCD_delay ;first, we'll tell the LCD that we want to use it
|
367 | ldi arg, 0x20 ;in 4-bit mode.
|
368 | rcall LCD_command8 ;LCD is still in 8-BIT MODE while writing this command!!!
|
369 |
|
370 |
|
371 | rcall LCD_delay
|
372 | ldi arg, 0x28 ;NOW: 2 lines, 5*7 font, 4-BIT MODE! ** this change to 4bit 2 lines **
|
373 | rcall LCD_command ;after this point you don't can change anything 'show HD44780 Datasheet'
|
374 |
|
375 | rcall LCD_wait
|
376 | ldi arg, 0x0F ;now proceed as usual: Display on, cursor on, blinking
|
377 | rcall LCD_command
|
378 |
|
379 | rcall LCD_wait
|
380 | ldi arg, 0x01 ;clear display, cursor -> home
|
381 | rcall LCD_command
|
382 |
|
383 | rcall LCD_wait
|
384 | ldi arg, 0x06 ;auto-inc cursor
|
385 | rcall LCD_command
|
386 | ret
|
387 |
|
388 | ;******************************************
|
389 | ; clear Displays
|
390 | LCD_clear:
|
391 | push arg
|
392 | ldi arg, 0b00000001 ; Display clear
|
393 | rcall LCD_command
|
394 | rcall LCD_wait
|
395 | pop arg
|
396 | ret
|
397 |
|
398 | ; Cursor Home
|
399 | LCD_home:
|
400 | push arg
|
401 | ldi arg, 0b00000010 ; Cursor Home
|
402 | rcall LCD_command
|
403 | rcall LCD_wait
|
404 | pop arg
|
405 | ret
|
406 |
|
407 | ;set cursor pos
|
408 | ;Start Adresse für ein 4 x 20 Zeichen Display
|
409 | ;Zeile 1: 0x00
|
410 | ;Zeile 2: 0x40
|
411 | ;Zeile 3: 0x14
|
412 | ;Zeile 4: 0x54
|
413 | LCD_pos:
|
414 | sbr arg,0b10000000 ; Set DD-RAM-Adress
|
415 | rcall LCD_command
|
416 | rcall LCD_wait
|
417 | ret
|
418 |
|
419 | ;*****************************************************
|
420 | ; Display at the position in arg the string starting at Z (null-term.)
|
421 | ;
|
422 | LCD4ZTxt:
|
423 | sbr arg,0b10000000 ; Set DD-RAM-Adress
|
424 | rcall LCD_command
|
425 | rcall LCD_wait
|
426 | LCD4ZTxt1:
|
427 | lpm ; Get a char
|
428 | tst R0 ; Null-Char?
|
429 | breq LCD4ZTxtR
|
430 | mov arg,R0
|
431 | rcall LCD_putchar ; display the cahr
|
432 | rcall LCD_wait
|
433 | adiw ZL,1 ; next char
|
434 | rjmp LCD4ZTxt1 ; do it again
|
435 | LCD4ZTxtR:
|
436 | ret
|
437 | ;**********************************************************************
|
438 | ;
|
439 | ; Eine 8 Bit Zahl ohne Vorzeichen hexadezimal ausgeben
|
440 | ;
|
441 | ; Übergabe: Zahl im Register arg
|
442 | ; veränderte Register: keine
|
443 | ;
|
444 | lcd_number_hex:
|
445 | swap arg
|
446 | rcall lcd_number_hex_digit
|
447 | swap arg
|
448 |
|
449 | lcd_number_hex_digit:
|
450 | push arg
|
451 |
|
452 | andi arg, $0F
|
453 | cpi arg, 10
|
454 | brlt lcd_number_hex_digit_1
|
455 | subi arg, -( 'A' - '9' - 1 ) ; es wird subi mit negativer Konstante verwendet, weil es kein addi gibt
|
456 | lcd_number_hex_digit_1:
|
457 | subi arg, -'0' ; ditto
|
458 | rcall lcd_putchar
|
459 | rcall LCD_wait
|
460 | pop arg
|
461 | ret
|
462 | ;*********************************************************************
|
463 | ;
|
464 | ; Eine 8 Bit Zahl dezimal ohne Vorzeichen ausgeben
|
465 | ;
|
466 | ; Übergabe: Zahl im Register arg
|
467 | ; veränderte Register: keine
|
468 | ;
|
469 | lcd_number:
|
470 | push temp ; die Funktion verändert temp2, also sichern
|
471 | ; wir den Inhalt, um ihn am Ende wieder
|
472 | ; herstellen zu können
|
473 |
|
474 | mov arg2,arg ; das Register temp1 frei machen
|
475 | ; abzählen wieviele Hunderter
|
476 | ; in der Zahl enthalten sind
|
477 | ldi arg, '0'
|
478 | lcd_number_1:
|
479 | subi arg2, 100 ; 100 abziehen
|
480 | brcs lcd_number_2 ; ist dadurch ein Unterlauf entstanden?
|
481 | inc arg ; Nein: 1 Hunderter mehr ...
|
482 | rjmp lcd_number_1 ; ... und ab zur nächsten Runde
|
483 | ;
|
484 | ; die Hunderterstelle ausgeben
|
485 | lcd_number_2:
|
486 | rcall LCD_putchar
|
487 | rcall LCD_wait
|
488 | subi arg2, -100 ; 100 wieder dazuzählen, da die
|
489 | ; vorherhgehende Schleife 100 zuviel
|
490 | ; abgezogen hat
|
491 |
|
492 | ; abzählen wieviele Zehner in
|
493 | ; der Zahl enthalten sind
|
494 | ldi arg, '0'
|
495 | lcd_number_3:
|
496 | subi arg2, 10 ; 10 abziehen
|
497 | brcs lcd_number_4 ; ist dadurch ein Unterlauf enstanden?
|
498 | inc arg ; Nein: 1 Zehner mehr ...
|
499 | rjmp lcd_number_3 ; ... und ab zur nächsten Runde
|
500 |
|
501 | ; die Zehnerstelle ausgeben
|
502 | lcd_number_4:
|
503 | rcall LCD_putchar
|
504 | rcall LCD_wait
|
505 | subi arg2, -10 ; 10 wieder dazuzählen, da die
|
506 | ; vorhergehende Schleife 10 zuviel
|
507 | ; abgezogen hat
|
508 |
|
509 | ; die übrig gebliebenen Einer
|
510 | ; noch ausgeben
|
511 | ldi arg, '0' ; die Zahl in temp2 ist jetzt im Bereich
|
512 | add arg, arg2 ; 0 bis 9. Einfach nur den ASCII Code für
|
513 | rcall LCD_putchar ; '0' dazu addieren und wir erhalten dierekt
|
514 | rcall LCD_wait ; den ASCII Code für die Ziffer
|
515 |
|
516 | pop temp ; den gesicherten Inhalt von temp2 wieder herstellen
|
517 | ret ; und zurück
|
518 |
|
519 | ;**********************************************************************
|
520 | ;
|
521 | ; Eine 8 Bit Zahl ohne Vorzeichen binär ausgeben
|
522 | ;
|
523 | ; Übergabe: Zahl im Register temp1
|
524 | ; veränderte Register: keine
|
525 |
|
526 | ; eine Zahl aus dem Register temp1 binär ausgeben
|
527 | LCD_alsBit:
|
528 | push arg ; temp1 gesichert
|
529 | push temp2
|
530 | push temp3
|
531 |
|
532 | mov temp2, arg;
|
533 |
|
534 | ldi temp3, 8; ; 8 Bits werden ausgelesen
|
535 | lcd_number_loop:
|
536 | dec temp3;
|
537 | rol temp2; ; Datenbits ins Carry geschoben ...
|
538 | brcc lcd_number_bit_carryset_0;
|
539 | brcs lcd_number_bit_carryset_1;
|
540 | rjmp lcd_number_loop;
|
541 |
|
542 | lcd_number_bit_carryset_0:
|
543 | ldi arg, '0' ; Bit low ausgeben
|
544 | rcall LCD_putchar
|
545 | tst temp3;
|
546 | breq lcd_number_ende;
|
547 | rjmp lcd_number_loop;
|
548 |
|
549 | lcd_number_bit_carryset_1:
|
550 | ldi arg, '1' ; Bit high ausgeben
|
551 | rcall LCD_putchar
|
552 | tst temp3;
|
553 | breq lcd_number_ende;
|
554 | rjmp lcd_number_loop;
|
555 |
|
556 | lcd_number_ende:
|
557 | pop temp3
|
558 | pop temp2
|
559 | pop arg
|
560 | ret
|
561 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
562 | ; Ab hier Routinen zum auslesen und verarbeiten
|
563 | ; des Sensors DHT22 (AM2302)
|
564 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
565 |
|
566 |
|
567 | text:
|
568 | .db "Temperatur / Rel.FeuOut:",0
|
569 | ok:
|
570 | .db "ok",0
|
571 | fehler:
|
572 | .db "Fehler! ",0
|
573 |
|
574 | fehlender_Sensor:
|
575 | .db "kein Sensor",0
|
576 |
|
577 |
|
578 | WAIT_40us: ;selbserklärend
|
579 | push r16
|
580 | ldi r16,35
|
581 | loop1: dec r16
|
582 | nop
|
583 | nop
|
584 | brne loop1
|
585 | pop r16
|
586 | ret
|
587 | wait2s:
|
588 | push r16
|
589 | push r17
|
590 | push r18
|
591 | ldi r16,250
|
592 | lo_p: ldi r17,220
|
593 | lo__p: ldi r18,12
|
594 | lo___p: dec r18
|
595 | brne lo___p
|
596 | dec r17
|
597 | brne lo__p
|
598 | dec r16
|
599 | brne lo_p
|
600 | pop r18
|
601 | pop r17
|
602 | pop r16
|
603 | ret
|
604 |
|
605 |
|
606 | waitMs: push r16 ;r16 retten
|
607 | push r17 ;r17 retten
|
608 | push r18 ;r18 retten
|
609 | ; ldi r16,1 ;Laufvariable ca x ms bei 3,6MHz
|
610 | lop1: ldi r17,0x38 ;Laufvariable loop1
|
611 | loop2: ldi r18,5 ;Laufvariable loop3
|
612 | loop3: dec r18 ;Zähler 3 -1, hier Kalibrierung auf MCU Takt
|
613 | brne loop3 ;Solange nicht NULL
|
614 | dec r17 ;Zähler 2 -1
|
615 | brne loop2 ;Solange nicht NULL
|
616 | dec r16 ;Zähler1 -1
|
617 | brne lop1 ;Solange nicht NULL
|
618 | pop r18 ;r18 wiederherstellen
|
619 | pop r17 ;r17 wiederherstellen
|
620 | pop r16 ;r16 wiederherstellen
|
621 | ret ;Rücksprung
|
622 |
|
623 | DHT_lesen:
|
624 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
625 | ; Initialisieren der Startsequenz
|
626 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
627 |
|
628 | nop
|
629 | nop
|
630 | nop
|
631 | ldi temp,0x00
|
632 | ldi arg,0x00
|
633 | out PORTC,arg
|
634 | ldi r16,6 ;6 mS
|
635 | rcall waitMs ;min 1ms warten
|
636 | ; ldi arg,13 ;40 µs warten
|
637 | ;lo_:
|
638 | ; dec arg
|
639 | ; brne lo_
|
640 |
|
641 | out PortC,DHTmaske ;über DHT auf 1 setzen (ist Pin an dem der Sensor hängt)
|
642 | ldi arg,8
|
643 | lo__: ;20 µs warten
|
644 | dec arg
|
645 | brne lo__
|
646 | ldi arg,0x00
|
647 | ; cbi PORTC,2
|
648 | out DDRC,arg ;SensorPin auf eingang schalten
|
649 | low1: ; hier wird auf ein Nullsignal des Sensors gewartet
|
650 | in arg,PINC
|
651 | inc temp
|
652 | ; breq KeinSensor
|
653 | and arg,DHTmaske
|
654 | breq low1
|
655 | high1:
|
656 | in arg,PINC
|
657 | and arg,DHTmaske
|
658 | brne high1
|
659 | low2: ; hier wird auf das 2te Nullsignal des Sensors gewartet
|
660 | in arg,PINC
|
661 | and arg,DHTmaske
|
662 | breq low2
|
663 | high2:
|
664 | in arg,PINC
|
665 | and arg,DHTmaske
|
666 | brne high2
|
667 | low3: ; hier wird auf das 3te Nullsignal des Sensors gewartet
|
668 | in arg,PINC
|
669 | and arg,DHTmaske
|
670 | breq low3 ;ab hier beginnen die Daten
|
671 |
|
672 | rcall DHT_bytlesen
|
673 | std y+0, byte
|
674 | rcall DHT_bytlesen
|
675 | std y+1,byte
|
676 | rcall DHT_bytlesen
|
677 | std y+2,byte
|
678 | rcall DHT_bytlesen
|
679 | std y+3,byte
|
680 | rcall DHT_bytlesen
|
681 | std y+4,byte
|
682 |
|
683 |
|
684 |
|
685 | ; mov r21,return
|
686 | ; ldi arg,0x00
|
687 | ; rcall LCD_pos
|
688 | ; LDd arg,y+0
|
689 | ; rcall LCD_alsBit
|
690 | ; ldi arg,0x40
|
691 | ; rcall LCD_pos
|
692 | ; LDd arg,y+1
|
693 | ; rcall LCD_alsBit
|
694 | ;ldi arg,0x14
|
695 | ; rcall LCD_pos
|
696 | ; LDd arg,y+2
|
697 | ; rcall LCD_alsBit
|
698 | ;ldi arg,0x54
|
699 | ; rcall LCD_pos
|
700 | ; LDd arg,y+3
|
701 | ; rcall LCD_alsBit
|
702 | ;ldi arg,0x0a
|
703 | ; rcall LCD_pos
|
704 | ; LDd arg,y+4
|
705 | ; rcall LCD_alsBit
|
706 | ; ldi arg,0x1e
|
707 | ; rcall LCD_pos
|
708 |
|
709 |
|
710 | ;Checksumme überprüfen
|
711 | ; rcall LCD_pos
|
712 | ldd arg,y+0
|
713 | ldd arg2,y+1
|
714 | add arg,arg2
|
715 | ldd arg2,y+2
|
716 | add arg,arg2
|
717 | ldd arg,y+3
|
718 | add arg,arg2
|
719 | ldd arg2,y+4
|
720 | cp arg,arg2
|
721 | breq fehler_
|
722 | ; ldi ZH,HIGH(ok*2)
|
723 | ; ldi ZL,LOW(ok*2)
|
724 | ; ldi arg,0x4a
|
725 | ; rcall LCD4ZTxt
|
726 | rjmp weitt
|
727 | fehler_:
|
728 | ldi ZH,HIGH(fehler*2)
|
729 | ldi ZL,LOW(fehler*2)
|
730 | ; ldi arg,0x4a
|
731 | rcall LCD4ZTxt
|
732 |
|
733 | weitt:
|
734 | ; ldi arg,0x1d
|
735 | ; rcall LCD_pos ;Position für die Luftfeuchte
|
736 | rcall umwandeln
|
737 | ldi arg,0x25 ;% und "RH" anfügen
|
738 | rcall LCD_putchar
|
739 | rcall LCD_wait
|
740 | ldi arg,' '
|
741 | rcall LCD_putchar
|
742 | rcall LCD_wait
|
743 | ldi arg,' '
|
744 | rcall LCD_putchar
|
745 | rcall LCD_wait
|
746 |
|
747 |
|
748 | ; ldi arg,0x5d
|
749 | ; rcall LCD_pos ;Position für die Temperatur
|
750 | inc r28
|
751 | inc r28
|
752 | ldi r29,0x00
|
753 | rcall umwandeln
|
754 | ldi arg,0xdf ;grad zeichen
|
755 | rcall LCD_putchar
|
756 | rcall LCD_wait
|
757 | ldi arg,0x43 ;grosses C
|
758 | rcall LCD_putchar
|
759 | rcall LCD_wait
|
760 | ret
|
761 |
|
762 |
|
763 | ;Routine zum erkennen der steigenden Flanke ohne Interrupt
|
764 | steigendeFlanke:
|
765 | CLT
|
766 | ldi return,0x00
|
767 | anf:
|
768 | in arg,PINC
|
769 | inc return
|
770 | andi arg,0x04
|
771 | breq anf
|
772 | brtc keinTflag
|
773 | ret ;rücksprung nach 2ten mal 1 geunden
|
774 | keinTflag:
|
775 | SET ;hier wird das T Flag verwendet umzu
|
776 | rjmp anf ;ob im zweiten durchlauf die 1 immer noch anliegt
|
777 |
|
778 | fallendeFlanke:
|
779 | CLT
|
780 | ldi return,0x00
|
781 | anf_:
|
782 | in arg,PINC
|
783 | inc return
|
784 | andi arg,0x04
|
785 | brne anf_
|
786 | brtc keinTflag_
|
787 | ret ;rücksprung nach 2ten mal 1 geunden
|
788 | keinTflag_:
|
789 | SET ;hier wird das T Flag verwendet umzu
|
790 | rjmp anf_ ;ob im zweiten durchlauf die 1 immer noch anliegt
|
791 |
|
792 |
|
793 | ;;;;;;;;;;;Byte lesen;;;;;;;;;;;;;;;;
|
794 | DHT_bytlesen:
|
795 |
|
796 | ldi temp,0x08
|
797 | ldi byte,00
|
798 | ; mov temp2,DHTmaske ;Pin an dem der DHT22 haengt
|
799 | runde: ;erkennen der Steigenden Flanke
|
800 | in arg,PINC
|
801 | and arg,DHTmaske ;Pin an dem der DHT22 haengt
|
802 | breq runde
|
803 | ldi arg,14 ;40us warten
|
804 | wart:
|
805 | dec arg
|
806 | brne wart
|
807 | in arg,PINC
|
808 | and arg,DHTmaske ;Pin an dem der DHT22 haengt
|
809 | brbs 1, c_null
|
810 | sec
|
811 | c_null:
|
812 | ldi arg,0x00
|
813 | rol byte ;
|
814 | adc byte,arg ;addiert null bei Z=0 und 1 bei z=1 ueber Carry
|
815 | nulltest: ;Hier wird wieder auf das naechste Low gewartet
|
816 | in arg,PINC
|
817 | and arg,DHTmaske ;Pin an dem der DHT22 haengt
|
818 | brne nulltest
|
819 | dec temp
|
820 | brne runde
|
821 | ret
|
822 |
|
823 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
824 | ; Weerte als dezimal Zahl ausgeben
|
825 | ; in Register Y (r28/r29) steht die Adresse für das erste
|
826 | ; umzuwandelnde Byte (High Byte)
|
827 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
828 |
|
829 | umwandeln:
|
830 | ; ldi arg,0x1e
|
831 | ; rcall LCD_pos
|
832 | ldi temp,$00 ;hunderter
|
833 | ldi temp2,0x00 ;rest
|
834 | ldi arg,0x00
|
835 | ldd arg2,y+0
|
836 | ; ldi arg,0x5e
|
837 | ; rcall LCD_pos
|
838 | ; ldd arg,y+1
|
839 | ; rcall LCD_alsBit
|
840 | ; ldi arg,0x00
|
841 | ror arg2 ;bit 9 auf 1 testen
|
842 | brcc nicht_gesetzt
|
843 | ldi arg,0x02
|
844 | add temp,arg
|
845 | ldi temp2,0x38 ;56 zum Rest addieren(von 256)
|
846 | nicht_gesetzt:
|
847 | ror arg2 ; Bit 10 überprüfen
|
848 | brcc nicht_gesetzt2
|
849 | ldi arg,0x05
|
850 | add temp,arg
|
851 | ldi arg,0x0c ;12 (von 512) zum Rest addieren
|
852 | add temp2,arg
|
853 | nicht_gesetzt2:
|
854 | ldd arg2,y+1
|
855 | rol arg2
|
856 | brcc nicht_gesetzt3
|
857 | inc temp
|
858 | ldi arg,28 ;Rest von 1(28) addieren
|
859 | add temp2,arg
|
860 | nicht_gesetzt3:
|
861 | rol arg2
|
862 | brcc nicht_gesetzt4
|
863 | ldi arg,64
|
864 | add temp2,arg
|
865 | nicht_gesetzt4:
|
866 | rol arg2
|
867 | brcc nicht_gesetzt5
|
868 | ldi arg,32
|
869 | add temp2,arg
|
870 | nicht_gesetzt5:
|
871 | rol arg2
|
872 | brcc nicht_gesetzt6
|
873 | ldi arg,16
|
874 | add temp2,arg
|
875 | nicht_gesetzt6:
|
876 | rol arg2
|
877 | brcc nicht_gesetzt7
|
878 | ldi arg,8
|
879 | add temp2,arg
|
880 | nicht_gesetzt7:
|
881 | rol arg2
|
882 | brcc nicht_gesetzt8
|
883 | ldi arg,4
|
884 | add temp2,arg
|
885 | nicht_gesetzt8:
|
886 | rol arg2
|
887 | brcc nicht_gesetzt9
|
888 | ldi arg,2
|
889 | add temp2,arg
|
890 | nicht_gesetzt9:
|
891 | rol arg2
|
892 | brcc nicht_gesetzt0
|
893 | inc temp2
|
894 | nicht_gesetzt0:
|
895 | subi temp2,100 ; 100 abziehen
|
896 | brcs dht_number_2 ; ist dadurch ein Unterlauf entstanden?
|
897 | inc temp ; Nein: 1 Hunderter mehr ...
|
898 | rjmp nicht_gesetzt0 ; ... und ab zur nächsten Runde
|
899 | ; die Hunderterstelle ausgeben
|
900 |
|
901 |
|
902 | dht_number_2:
|
903 |
|
904 | ldi arg,48
|
905 | add arg,temp
|
906 | rcall LCD_putchar
|
907 | rcall LCD_wait
|
908 | subi temp2, -100 ; 100 wieder dazuzählen, da die
|
909 | ; vorherhgehende Schleife 100 zuviel
|
910 | ; abgezogen hat
|
911 |
|
912 | ; abzählen wieviele Zehner in
|
913 | ; der Zahl enthalten sind
|
914 | ldi arg, '0'
|
915 | dht_number_3:
|
916 | subi temp2, 10 ; 10 abziehen
|
917 | brcs dht_number_4 ; ist dadurch ein Unterlauf enstanden?
|
918 | inc arg ; Nein: 1 Zehner mehr ...
|
919 | rjmp dht_number_3 ; ... und ab zur nächsten Runde
|
920 |
|
921 | ; die Zehnerstelle ausgeben
|
922 | dht_number_4:
|
923 | rcall LCD_putchar
|
924 | rcall LCD_wait
|
925 | subi temp2, -10 ; 10 wieder dazuzählen, da die
|
926 | ; vorhergehende Schleife 10 zuviel
|
927 | ; abgezogen hat
|
928 | ldi arg,0x2e ; Punkt einfügen
|
929 | rcall LCD_putchar
|
930 | rcall LCD_wait
|
931 |
|
932 | ; die übrig gebliebenen Einer
|
933 | ; noch ausgeben
|
934 | ldi arg, '0' ; die Zahl in temp2 ist jetzt im Bereich
|
935 | add arg, temp2 ; 0 bis 9. Einfach nur den ASCII Code für
|
936 | rcall LCD_putchar ; '0' dazu addieren und wir erhalten dierekt
|
937 | rcall LCD_wait ; den ASCII Code für die Ziffer
|
938 |
|
939 |
|
940 |
|
941 |
|
942 |
|
943 | ret
|