-
Notifications
You must be signed in to change notification settings - Fork 1
/
lcdAlarmClock.asm
487 lines (428 loc) · 7.55 KB
/
lcdAlarmClock.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
;Author: NEELMANI GAUTAM
;Interfaced 16x2 LCD display in 4-bit mode using sufficient delay with ATMega328P
.include "/usr/share/avra/m328Pdef.inc"
.equ LCD_DATA = PORTD
.equ LCD_DATA_DIR = DDRD
.equ LCD_CTRL = PORTB
.equ LCD_CTRL_DIR = DDRB
.equ LCD_RS = 0
.equ LCD_RW = 1
.equ LCD_E = 2
.equ pushBT1 = 3 ;yes, increment, PORTB
.equ pushBT2 = 4 ;no, enter, PORTB
.equ Buzzer = 2 ;PORTD
.equ LCD_FUNCTION_SET = 0x38
.equ LCD_FUNCTION_SET_4BIT = 0x28
.equ LCD_DISPLAY_OFF = 0x08
.equ LCD_DISPLAY_ON = 0x0C
.equ LCD_DISPLAY_CLEAR = 0x01
.equ LCD_ENTRY_MODE_SET = 0x06
.equ LCD_CURSOR_HOME = 0x02
.equ LCD_LINE1_ADDR = 0x80
.equ LCD_LINE2_ADDR = 0xC0
.def lcdData = r16
.def waitTemp1 = r17
.def waitTemp2 = r18
.def waitTemp3 = r19
.def HRS_ONES = r20
.def HRS_TENS = r21
.def MIN_ONES = r22
.def MIN_TENS = r23
.def SEC_ONES = r24
.def SEC_TENS = r25
.def AHT = r26
.def AHO = r27
.def AMT = r28
.def AMO = r29
.macro strobe
sbi LCD_CTRL, LCD_E
cbi LCD_CTRL, LCD_E
.endmacro
.macro rwLow
cbi LCD_CTRL, LCD_RW
.endmacro
.macro rwHigh
cbi LCD_CTRL, LCD_RW
.endmacro
.macro rsLow
cbi LCD_CTRL, LCD_RS
.endmacro
.macro rsHigh
sbi LCD_CTRL, LCD_RS
.endmacro
.macro lcdCommand ;lcdCommand C executes command C to control lcd
rsLow
ldi lcdData, @0
rcall lcdOutNibble
swap lcdData
rcall lcdOutNibble
.endmacro
.macro lcdChar ;lcdChar print lcdData
rsHigh
rcall lcdOutNibble
swap lcdData
rcall lcdOutNibble
.endmacro
.macro printStr
ldi ZH, high(@0*2)
ldi ZL, low(@0*2)
lcdCommand @1
string_loop:
lpm lcdData, Z+
tst lcdData
breq end
lcdChar
rjmp string_loop
end: nop
.endmacro
.macro set_Time
lcdCommand LCD_DISPLAY_CLEAR
lcdCommand LCD_CURSOR_HOME
printStr HT, LCD_LINE1_ADDR
H10:lcdCommand $C7
call wait100ms
IN lcdData, PINB
SBRC lcdData, pushBT1
INC @0
CPI @0, 3
BRNE HR10
LDI @0, 0
HR10: mov waitTemp1, @0
call dec2str
lcdChar
IN lcdData, PINB
SBRS lcdData, pushBT2
JMP H10
lcdCommand LCD_DISPLAY_CLEAR
lcdCommand LCD_CURSOR_HOME
printStr HO, LCD_LINE1_ADDR
H1: lcdCommand $C7
call wait100ms
IN lcdData, PINB
SBRC lcdData, pushBT1
INC @1
CPI @1, 10
BRNE HR1
LDI @1, 0
HR1: mov waitTemp1, @1
call dec2str
lcdChar
IN lcdData, PINB
SBRS lcdData, pushBT2
JMP H1
lcdCommand LCD_DISPLAY_CLEAR
lcdCommand LCD_CURSOR_HOME
printStr MT, LCD_LINE1_ADDR
M10:lcdCommand $C7
call wait100ms
IN lcdData, PINB
SBRC lcdData, pushBT1
INC @2
CPI @2, 6
BRNE MN10
LDI @2, 0
MN10: mov waitTemp1, @2
call dec2str
lcdChar
IN lcdData, PINB
SBRS lcdData, pushBT2
JMP M10
lcdCommand LCD_DISPLAY_CLEAR
lcdCommand LCD_CURSOR_HOME
printStr MO, LCD_LINE1_ADDR
M1: lcdCommand $C7
call wait100ms
IN lcdData, PINB
SBRC lcdData, pushBT1
INC @3
CPI @3, 10
BRNE MN1
LDI @3, 0
MN1: mov waitTemp1, @3
call dec2str
lcdChar
IN lcdData, PINB
SBRS lcdData, pushBT2
JMP M1
Break: nop
.endmacro
;====================================================================
.org 0
rjmp reset
reset:
ldi HRS_TENS, 0
ldi MIN_ONES, 0
ldi MIN_TENS, 0
ldi SEC_ONES, 0
ldi SEC_TENS, 0
ldi AHT, 0
ldi AHO, 0
ldi AMT, 0
ldi AMO, 0
ldi R16, $00
OUT PORTD, R16
OUT PORTB, R16
ldi R16, low(RAMEND)
out SPL, R16
ldi R16, high(RAMEND)
out SPH, R16
ldi R16, $00
OUT LCD_CTRL_DIR, R16
ldi R16, $04
OUT LCD_DATA_DIR, R16
in waitTemp2, LCD_DATA_DIR
ori waitTemp2, $F0
out LCD_DATA_DIR, waitTemp2
in waitTemp2, LCD_CTRL_DIR
ori waitTemp2, ((1<<LCD_RS)|(1<<LCD_RW)|(1<<LCD_E))
out LCD_CTRL_DIR, waitTemp2
LCD_INIT:
rwLow
rsLow
ldi lcdData,LCD_FUNCTION_SET
call wait5ms
rcall lcdOutNibble
rcall wait100us
rcall lcdOutNibble
rcall wait100us
rcall lcdOutNibble
ldi lcdData,LCD_FUNCTION_SET_4BIT
rcall wait100us
rcall lcdOutNibble
lcdCommand LCD_FUNCTION_SET_4BIT
lcdCommand LCD_ENTRY_MODE_SET
lcdCommand LCD_DISPLAY_ON
lcdCommand LCD_DISPLAY_CLEAR
lcdCommand LCD_CURSOR_HOME
Main:
Call Alarm_Set
Call Time_Set
lcdCommand LCD_DISPLAY_CLEAR
lcdCommand LCD_CURSOR_HOME
printStr Tlabel, $86
JMP RESET_SEC_TENS
RESET_HRS_TENS:
CLR HRS_TENS
RESET_HRS_ONES:
CLR HRS_ONES
RESET_MIN_TENS:
CLR MIN_TENS
RESET_MIN_ONES:
CLR MIN_ONES
RESET_SEC_TENS:
CLR SEC_TENS
RESET_SEC_ONES:
CLR SEC_ONES
CLOCK_LOOP:
CP HRS_TENS, AHT
BREQ IF1
EL: CALL display_time
INC SEC_ONES
CPI SEC_ONES, 10
BRNE CLOCK_LOOP
INC SEC_TENS
CPI SEC_TENS, 6
BRNE RESET_SEC_ONES
INC MIN_ONES
CBI PORTD, Buzzer ;To turn off alarm
CPI MIN_ONES, 10
BRNE RESET_SEC_TENS
INC MIN_TENS
CPI MIN_TENS, 6
BRNE RESET_MIN_ONES
INC HRS_ONES
CPI HRS_TENS, 2
BRNE CD2
CD1:
CPI HRS_ONES, 4
BRNE RESET_MIN_TENS
JMP CD3
CD2:
CPI HRS_ONES, 10
BRNE RESET_MIN_TENS
JMP CD3
CD3:
INC HRS_TENS
CPI HRS_TENS, 3
BRNE RESET_HRS_ONES
SER HRS_ONES
JMP RESET_HRS_TENS
IF1:
CP HRS_ONES, AHO
BREQ IF2
JMP EL
IF2:
CP MIN_TENS, AMT
BREQ IF3
JMP EL
IF3:
CP MIN_ONES, AMO
BREQ Bz
JMP EL
Bz: SBI PORTD, Buzzer
JMP EL
;====================================================================
Alarm_Set:
lcdCommand LCD_DISPLAY_CLEAR
lcdCommand LCD_CURSOR_HOME
printStr Alabel1, LCD_LINE1_ADDR
printStr Alabel2, LCD_LINE2_ADDR
A0: IN waitTemp1, PINB
SBRC waitTemp1, pushBT2
RET
SBRC waitTemp1, pushBT1
JMP A1
JMP A0
A1: set_Time AHT, AHO, AMT, AMO
RET
Time_Set:
lcdCommand LCD_DISPLAY_CLEAR
lcdCommand LCD_CURSOR_HOME
printStr Tsetlabel1, LCD_LINE1_ADDR
printStr Tsetlabel2, LCD_LINE2_ADDR
TS0: IN waitTemp1, PINB
SBRC waitTemp1, pushBT1
JMP TS1
SBRC waitTemp1, pushBT2
JMP TS1
JMP TS0
TS1: set_Time HRS_TENS, HRS_ONES, MIN_TENS, MIN_ONES
RET
display_time:
lcdCommand $C4
mov waitTemp1, HRS_TENS
call dec2str
lcdChar
mov waitTemp1, HRS_ONES
call dec2str
lcdChar
LDI lcdData, ':'
lcdChar
mov waitTemp1, MIN_TENS
call dec2str
lcdChar
mov waitTemp1, MIN_ONES
call dec2str
lcdChar
LDI lcdData, ':'
lcdChar
mov waitTemp1, SEC_TENS
call dec2str
lcdChar
mov waitTemp1, SEC_ONES
call dec2str
lcdChar
call wait1sec
RET
dec2str:
CPI waitTemp1, 0
breq t0
CPI waitTemp1, 1
breq t1
CPI waitTemp1, 2
breq t2
CPI waitTemp1, 3
breq t3
CPI waitTemp1, 4
breq t4
CPI waitTemp1, 5
breq t5
CPI waitTemp1, 6
breq t6
CPI waitTemp1, 7
breq t7
CPI waitTemp1, 8
breq t8
CPI waitTemp1, 9
breq t9
t0: ldi lcdData, '0'
ret
t1: ldi lcdData, '1'
ret
t2: ldi lcdData, '2'
ret
t3: ldi lcdData, '3'
ret
t4: ldi lcdData, '4'
ret
t5: ldi lcdData, '5'
ret
t6: ldi lcdData, '6'
ret
t7: ldi lcdData, '7'
ret
t8: ldi lcdData, '8'
ret
t9: ldi lcdData, '9'
ret
wait100us:
ldi waitTemp1, 0x00
ldi waitTemp2, 0x02
w100us:
dec waitTemp1
brne w100us
dec waitTemp2
brne w100us
ret
wait5ms:
ldi waitTemp1, $00
ldi waitTemp2, $00
w5ms:
dec waitTemp1
brne w5ms
dec waitTemp2
brne w5ms
ret
wait100ms:
ldi waitTemp3, 0x10
ldi waitTemp2, 0x00
ldi waitTemp1, 0x00
w100ms:
dec waitTemp1
brne w100ms
dec waitTemp2
brne w100ms
dec waitTemp3
brne w100ms
ret
wait1sec:
ldi waitTemp3, 53
ldi waitTemp2, 0x00
ldi waitTemp1, 0x00
w1sec:
dec waitTemp1
brne w1sec
dec waitTemp2
brne w1sec
dec waitTemp3
brne w1sec
ret
lcdOutNibble: ;Send out high nibble of lcdData in upper data lines
rcall wait5ms
mov waitTemp2,lcdData
andi waitTemp2, 0xF0
in waitTemp1, LCD_DATA
andi waitTemp1, 0x0F
or waitTemp2, waitTemp1
out LCD_DATA, waitTemp2
strobe
ret
;====================================================================
Tlabel:
.db "TIME", 0, 0
Tsetlabel1:
.db "PRESS ANY KEY TO", 0, 0
Tsetlabel2:
.db " SET TIME ", 0, 0
Alabel1:
.db " DO YOU WANT TO ", 0, 0
Alabel2:
.db " SET ALARM? ", 0, 0
HO:
.db "HOUR ONES PLACE", 0
HT:
.db "HOUR TENS PLACE", 0
MO:
.db "MIN. ONES PLACE", 0
MT:
.db "MIN. TENS PLACE", 0