-
Notifications
You must be signed in to change notification settings - Fork 0
/
CLOCK.asm
148 lines (106 loc) · 7.8 KB
/
CLOCK.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
ORG 0h
JMP START ;прыжок на адрес 8100h - начало программы
ORG 000Bh
JMP INT_0 ;прыжок при прерывании по таймеру 0
ORG 8100h
START:
SETB RS1 ;устанавливаем 3 банк регистров
SETB RS0 ;устанавливаем 3 банк регистров
MOV R0, #0 ;устанавливаем начальные значения R0
MOV R1, #0 ;устанавливаем начальные значения R1
MOV R2, #0 ;устанавливаем начальные значения R2
MOV R3, #0 ;устанавливаем начальные значения R3
MOV R4, #0 ;устанавливаем начальные значения R4
MOV DPTR, #03h ;Настраиваем режим работы портов, устанавливаем доступ к управляющему байту
MOV A, #10000010b ;Заносим константу 82h (порт А - запись, порт B - чтение, порт C - запись) в аккумулятор
MOVX @DPTR, A ;Заносим константу в управляющий байт
SETB EA ;разрешаем прерывания
SETB ET0 ;разрешаем прерывания по таймеру 0
MOV A, TMOD ;помещаем в аккумулятор содержимое TMOD
ORL A, #00000001b ;настраиваем режим работы таймера 0 на режим 1 (16битный последовательный)
MOV TMOD, A ;помещаем новую константу таймера в TMOD
;11,059 * (1/12) = 0,9216
;0,9216 * 1000000 = 921600
;921600 / 20 = 46080
;65536 - 46080 = 19456
MOV TH0, #04Ch ;Загружаем начальное значение таймера 19456
MOV TL0, #00h ;Загружаем начальное значение таймера 19456
SETB TR0 ;Запуск таймера
LOOP:
JMP INT_1 ;Отображение на индикаторе
LOOP_START:
NOP ;пропускаем 1 такт
MOV A, #17d ;делаем задержку в 17 мс (каждая лампа обновляется по 60 раз в сек)
LOOP_1:
DEC A ;вычитаем 1 для цикла
CJNE A, #0, LOOP_1 ;если не ноль ожидаем
JMP LOOP ;запускаем цикл заново до бесконечности
SJMP $
INT_0:
INC R0 ;Увеличиваем R0 на 1
MOV TH0, #04Ch ;Снова заносим таймерную константу 19456
MOV TL0, #00h ;Снова заносим таймерную константу 19456
CJNE R0, #20, EXIT_INT_0 ;Если не отсчитали R0 20 раз выходим
MOV R0, #0 ;Сбрасываем R0
INC R1 ;Увеличиваем R1 (количество секунд) на 1
CJNE R1, #60d, EXIT_INT_0 ;Если не отсчитали 60 секунд выходим
MOV R1, #0 ;Сбрасываем R1 (количество секунд)
INC R2 ;Увеличиваем R2 (количество минут) на 1
CJNE R2, #60d, EXIT_INT_0 ;Если не отсчитали 60 минут выходим
MOV R2, #0 ;Сбрасываем R2 (количество минут)
INC R3 ;Увеличиваем R3 (количество часов) на 1
CJNE R3, #24d, EXIT_INT_0 ;Если не отсчитали 24 часа выходим
MOV R3, #0 ;Сбрасываем R3 (количество часов)
EXIT_INT_0:
RETI ;Выход из прерывания
INT_1:
MOV DPTR, #02h ;Заносим константу 2 для доступа к порту C
HOURS_HIGH:
CJNE R4, #0, HOURS_LOW ;Если не 0 значит не этот индикатор
MOV A, R3 ;Помещаем в аккумулятор количество часов
MOV B, #10 ;Помещаем в доп. аккумулятор число 10
DIV AB ;Делим часы на 10 и теперь в A - старшая цифра, в B - младшая
ORL A, #00010000b ;Выбираем индикатор старшей цифры часа
MOVX @DPTR, A ;Помещаем на порт C значение из аккумулятора
JMP NEXT_INDICATOR ;Следующий индикатор
HOURS_LOW:
CJNE R4, #1, MINUTES_HIGH ;Если не 1 значит не этот индикатор
MOV A, R3 ;Помещаем в аккумулятор количество часов
MOV B, #10 ;Помещаем в доп. аккумулятор число 10
DIV AB ;Делим часы на 10 и теперь в A - старшая цифра, в B - младшая
MOV A, B ;Помещаем в A младшую цифру часа
ORL A, #00100000b ;Выбираем индикатор младшей цифры часа
MOVX @DPTR, A ;Помещаем на порт C значение из аккумулятора
JMP NEXT_INDICATOR ;Следующий индикатор
MINUTES_HIGH:
CJNE R4, #2, MINUTES_LOW ;Если не 2 значит не этот индикатор
MOV A, R1 ;Помещаем в аккумулятор количество секунд
MOV B, #2 ;Помещаем в доп. аккумулятор число 2
DIV AB ;Делим секунды на 2 и теперь в A - частное, в B - остаток
MOV A, B ;Помещаем в A остаток от деления
CJNE A, #0, NEXT_INDICATOR ;Если остаток не 0 выключаем индикатор и переходим к следующему
MOV A, R2 ;Помещаем в аккумулятор количество минут
MOV B, #10 ;Помещаем в доп. аккумулятор число 10
DIV AB ;Делим минуты на 10 и теперь в A - старшая цифра, в B - младшая
ORL A, #01000000b ;Выбираем индикатор старшей цифры минуты
MOVX @DPTR, A ;Помещаем на порт C значение из аккумулятора
JMP NEXT_INDICATOR ;Следующий индикатор
MINUTES_LOW:
MOV A, R1 ;Помещаем в аккумулятор количество секунд
MOV B, #2 ;Помещаем в доп. аккумулятор число 2
DIV AB ;Делим секунды на 2 и теперь в A - частное, в B - остаток
MOV A, B ;Помещаем в A остаток от деления
CJNE A, #0, NEXT_INDICATOR ;Если остаток не 0 выключаем индикатор и переходим к следующему
MOV A, R2 ;Помещаем в аккумулятор количество минут
MOV B, #10 ;Помещаем в доп. аккумулятор число 10
DIV AB ;Делим минуты на 10 и теперь в A - старшая цифра, в B - младшая
MOV A, B ;Помещаем в A младшую цифру минут
ORL A, #10000000b ;Выбираем индикатор младшей цифры минуты
MOVX @DPTR, A ;Помещаем на порт C значение из аккумулятора
NEXT_INDICATOR:
INC R4 ;Увеличиваем R4, т.е. переход к следующему индикатору
CJNE R4, #4, EXIT_INT_1 ;Если не больше 4 (индексация от 0) то выходим
MOV R4, #0 ;Сбрасываем R4, начиная от первого индикатора
EXIT_INT_1:
JMP LOOP_START ;Переходим к началу цикла вывода
END