-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProject.asm
459 lines (383 loc) · 11.3 KB
/
Project.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
.org $000
JMP Start ; Указатель на начало программы
.org INT0addr
JMP EXT_INT0 ; Указатель на обработчик прерывания int0
.org INT1addr
JMP EXT_INT1 ; Указатель на обработчик прерывания int1
.def STEP = R28
.def VALUE1 = R29
.def VALUE2 = R30
.def VALUE3 = R31
.def LINE1 = R19
.def LINE2 = R20
.def LINE3 = R21
.def LINES_FIRST = R22 ; В регистре последние 3 бита - флаги использования линии в первый раз
.def LINE_COUNT = R23
; R23
; R24
; R25
; R26
; R27
JMP Start
; ---------- EEPROM --------------------------
EEPROM_read:
; Wait for completion of previous write
sbic EECR,EEWE ;skips the next command if eewe bit is clear
rjmp EEPROM_read
; Set up address (r18:r17) in address register eear
;It has two 8-bit registers EEARH and EEARL.
out EEARH, r26 ;EEARH contain last 9th bit of address
out EEARL, r25;EEARL contain first 8-bit of address
; Start eeprom read by writing EERE
sbi EECR,EERE
; Read data from data register
in STEP, EEDR
JMP Main_continue
EEPROM_write:
; Wait for completion of previous write
sbic EECR,EEWE
rjmp EEPROM_write
; Set up address (r18:r17) in address register
out EEARH, r26
out EEARL, r25
; Write data (r16) to data register
out EEDR, STEP
; Write logical one to EEMWE
sbi EECR,EEMWE
; Start eeprom write by setting EEWE
sbi EECR,EEWE
RET
; --------------------------------------------
; ---------- Прерывания ----------------------
EXT_INT0:
PUSH R18
IN R18, SREG
PUSH R18
MOV R17, STEP
ANDI R17, 0b00001000
BRNE STEP_NEGATIVE1 ; Переход, если значение шага отрицательное
CPI STEP, 4
BRNE STEP_LESS_4 ; Переход, если значение шага положительное, но меньше 4
LDI STEP, 0b00001100 ; Присваиваем шагу -4 (В 4-ех разрядном прямом коде)
JMP int0_next
STEP_NEGATIVE1: ; Значение шага отрицательное
SUBI STEP, 1
CPI STEP, 0b00001000
BRNE int0_next
LDI STEP, 0 ; Делаем из "отрицательного" нуля положительный
JMP int0_next
STEP_LESS_4: ; Значение шага положительное, меньше 4
INC STEP
int0_next: ; Сдвигаем значение шага, чтобы вывести на PD4-PD7
MOV R16, STEP
LSL R16
LSL R16
LSL R16
LSL R16
ANDI R16, 0b11110000
OR R16, LINE_COUNT
OUT PORTD, R16
CALL EEPROM_write
POP R18
OUT SREG, R18
POP R18
RETI
; --------------------------------------------
EXT_INT1:
PUSH R18
IN R18, SREG
PUSH R18
CPI LINE2, 25
BREQ add_line2 ; Добавляем линию 2
CPI LINE3, 25
BREQ add_line3 ; Добавляем линию 3
; Удаляем две последние линии
LDI LINE2, 25
LDI LINE3, 25
LDI LINE_COUNT, 1
JMP int1_next
add_line2:
LDI LINE2, 0
LDI LINE_COUNT, 2
JMP int1_next
add_line3:
LDI LINE3, 0
LDI LINE_COUNT, 3
int1_next:
MOV R16, STEP
LSL R16
LSL R16
LSL R16
LSL R16
ANDI R16, 0b11110000
OR R16, LINE_COUNT
OUT PORTD, R16
POP R18
OUT SREG, R18
POP R18
RETI
; --------------------------------------------
Change_line1:
MOV R16, STEP
MOV R17, STEP
ANDI R17, 0b00001000
BRNE step_neg1
ADD R16, LINE1
JMP divv1
step_neg1:
MOV R16, LINE1
MOV R17, STEP
ANDI R17, 0b00000111
SUB R16, R17
divv1: ; Находим остаток от деления суммы на 24
CPI R16, 24
BRLO change_value1
SUBI R16, 24
JMP divv1
JMP change_value1
change_value1:
MOV LINE1, R16
LDI R16, 1 ; Необходимо данный бит сдвинуть на величину шага
; в одном из трех регистров
CPI LINE1, 0 ; Если равно, ничего сдвигать не нужно. Выводим первый бит в VALUE1
BREQ line1_zero
MOV R18, LINE1
CPI R18, 8 ; Если значение меньше 8, меняем регистр 1
BRSH greater8_line1
;--- Регистр VALUE1 --------------
MOV R17, R18
compare_7_line1: ; Выставляем бит в регистре от 0 до 7
LSL R16 ; Циклически сдвигаем бит на нужную позицию
DEC R17
BRNE compare_7_line1
OR VALUE1, R16 ; Меняем регистр для порта A
JMP end_line1
;---------------------------------
;---------------------------------
greater8_line1:
CPI R18, 16 ; Если значение меньше 16, меняем регистр 2
BRSH greater16_line1
;--- Регистр VALUE2 --------------
SUBI R18, 8
MOV R17, R18
compare_15_line1: ; Выставляем бит в регистре от 8 до 15
LSL R16 ; Циклически сдвигаем бит на нужную позицию
DEC R17
BRNE compare_15_line1
OR VALUE2, R16 ; Меняем регистр для порта B
JMP end_line1
;---------------------------------
;--- Регистр VALUE3 --------------
greater16_line1: ; меняем регистр 3
SUBI R18, 16
MOV R17, R18
compare_23_line1:
LSL R16 ; Циклически сдвигаем бит на нужную позицию
DEC R17
BRNE compare_23_line1
OR VALUE3, R16 ; Меняем регистр для порта С
JMP end_line1
;---------------------------------
line1_zero:
ORI VALUE1, 0b00000001
end_line1:
JMP Compare_line2
; --------------------------------------------
Change_line2:
MOV R16, STEP
MOV R17, STEP
ANDI R17, 0b00001000
BRNE step_neg2
ADD R16, LINE2
JMP divv2
step_neg2:
MOV R16, LINE2
MOV R17, STEP
ANDI R17, 0b00000111
SUB R16, R17
divv2: ; Находим остаток от деления суммы на 24
CPI R16, 24
BRLO change_value2
SUBI R16, 24
JMP divv2
JMP change_value2
change_value2:
MOV LINE2, R16
LDI R16, 1 ; Необходимо данный бит сдвинуть на величину шага
; в одном из трех регистров
CPI LINE2, 0 ; Если равно, ничего сдвигать не нужно. Выводим первый бит в VALUE1
BREQ line2_zero
MOV R18, LINE2
CPI R18, 8 ; Если значение меньше 8, меняем регистр 1
BRSH greater8_line2
;--- Регистр VALUE1 --------------
MOV R17, R18
compare_7_line2: ; Выставляем бит в регистре от 0 до 7
LSL R16 ; Циклически сдвигаем бит на нужную позицию
DEC R17
BRNE compare_7_line2
OR VALUE1, R16 ; Меняем регистр для порта A
JMP end_line2
;---------------------------------
;---------------------------------
greater8_line2:
CPI R18, 16 ; Если значение меньше 16, меняем регистр 2
BRSH greater16_line2
;--- Регистр VALUE2 --------------
SUBI R18, 8
MOV R17, R18
compare_15_line2: ; Выставляем бит в регистре от 8 до 15
LSL R16 ; Циклически сдвигаем бит на нужную позицию
DEC R17
BRNE compare_15_line2
OR VALUE2, R16 ; Меняем регистр для порта B
JMP end_line2
;---------------------------------
;--- Регистр VALUE3 --------------
greater16_line2: ; меняем регистр 3
SUBI R18, 16
MOV R17, R18
compare_23_line2:
LSL R16 ; Циклически сдвигаем бит на нужную позицию
DEC R17
BRNE compare_23_line2
OR VALUE3, R16 ; Меняем регистр для порта С
JMP end_line2
;---------------------------------
line2_zero:
ORI VALUE1, 0b00000001
end_line2:
JMP Compare_line3
; --------------------------------------------
Change_line3:
MOV R16, STEP
MOV R17, STEP
ANDI R17, 0b00001000
BRNE step_neg3
ADD R16, LINE3
JMP divv3
step_neg3:
MOV R16, LINE3
MOV R17, STEP
ANDI R17, 0b00000111
SUB R16, R17
divv3: ; Находим остаток от деления суммы на 24
CPI R16, 24
BRLO change_value3
SUBI R16, 24
JMP divv3
JMP change_value3
change_value3:
MOV LINE3, R16
LDI R16, 1 ; Необходимо данный бит сдвинуть на величину шага
; в одном из трех регистров
CPI LINE3, 0 ; Если равно, ничего сдвигать не нужно. Выводим первый бит в VALUE1
BREQ line3_zero
MOV R18, LINE3
CPI R18, 8 ; Если значение меньше 8, меняем регистр 1
BRSH greater8_line3
;--- Регистр VALUE1 --------------
MOV R17, R18
compare_7_line3: ; Выставляем бит в регистре от 0 до 7
LSL R16 ; Циклически сдвигаем бит на нужную позицию
DEC R17
BRNE compare_7_line3
OR VALUE1, R16 ; Меняем регистр для порта A
JMP end_line3
;---------------------------------
;---------------------------------
greater8_line3:
CPI R18, 16 ; Если значение меньше 16, меняем регистр 2
BRSH greater16_line3
;--- Регистр VALUE2 --------------
SUBI R18, 8
MOV R17, R18
compare_15_line3: ; Выставляем бит в регистре от 8 до 15
LSL R16 ; Циклически сдвигаем бит на нужную позицию
DEC R17
BRNE compare_15_line3
OR VALUE2, R16 ; Меняем регистр для порта B
JMP end_line3
;---------------------------------
;--- Регистр VALUE3 --------------
greater16_line3: ; меняем регистр 3
SUBI R18, 16
MOV R17, R18
compare_23_line3:
LSL R16 ; Циклически сдвигаем бит на нужную позицию
DEC R17
BRNE compare_23_line3
OR VALUE3, R16 ; Меняем регистр для порта С
JMP end_line3
;---------------------------------
line3_zero:
ORI VALUE1, 0b00000001
end_line3:
JMP Ports_write
; --------------------------------------------
Start:
LDI LINE_COUNT, 1
LDI LINE1, 0
LDI LINE2, 25
LDI LINE3, 25
LDI LINES_FIRST, 0b00000111
SEI ; Включаем прерывания
LDI R16, 0x0F
OUT MCUCR, R16
LDI R16, 0xC0
OUT GICR, R16
LDI R16, 0x01
OUT PORTD, R16
LDI R16, 0xFF
OUT DDRA, R16
OUT DDRB, R16
OUT DDRC, R16
LDI R16, 0xF3
OUT DDRD, R16
JMP EEPROM_read
;LDI STEP, 0b00000100
Main_continue:
MOV R16, STEP
LSL R16
LSL R16
LSL R16
LSL R16
ANDI R16, 0b11110000
OR R16, LINE_COUNT
OUT PORTD, R16
Cycle: ; --------------------------- Цикл ---------------------------
LDI VALUE1, 0
LDI VALUE2, 0
LDI VALUE3, 0
CPI LINE1, 25
BREQ Compare_line2
JMP Change_line1
Compare_line2:
CPI LINE2, 25
BREQ Compare_line3
JMP Change_line2
Compare_line3:
CPI LINE3, 25
BREQ Ports_write
JMP Change_line3
Ports_write:
OUT PORTA, VALUE1
OUT PORTB, VALUE2
OUT PORTC, VALUE3
LDI R18, 0xFF
LDI R17, 0xFF
LDI R16, 20
Delay_ms:
DEC R18
BRNE Delay_ms
LDI R18, 0xFF
DEC R17
BRNE Delay_ms
LDI R17, 0xFF
DEC R16
BRNE Delay_ms
OUT PORTA, R18
OUT PORTB, R18
OUT PORTC, R18
JMP Cycle
; -------------------------------------------------------------------