-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.asm
More file actions
347 lines (292 loc) · 7.75 KB
/
main.asm
File metadata and controls
347 lines (292 loc) · 7.75 KB
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
;
; TouchT4.asm
;
; Created: 01.02.2018 17:32:58
; Author : Poppy
;
.device ATtiny4
.include "tn4def.inc"
.def TMP = r16 ; Рабочий регистр
.def TMPL = r17 ; Рабочий регистр
.def COUNT = r18 ; Счётчик циклов WDT
.def FLAG = r19 ; Регистр флагов
.def PWML = r20 ; Текущее значение ШИМ
.def PWMH = r21
.def SPWML = r22 ; Интенсивность зрительного ощущения яркости
.def SPWMH = r23
.def TMPH = r24
#define mc16uL XL ;multiplicand low byte
#define mc16uH XH ;multiplicand high byte
#define mp16uL YL ;multiplier low byte
#define mp16uH YH ;multiplier high byte
#define m16u0 YL ;result byte 0 (LSB)
#define m16u1 YH ;result byte 1
.def m16u2 =r25 ;result byte 2
#define m16u3 ZL ;result byte 3 (MSB)
#define mcnt16u ZH ;loop counter
; Биты флагового регистра
.equ ON_OFF = 0 ; Состояние светильника (0-выключен, 1-включен)
.equ UP_DOWN = 1 ; Направление изменения яркости
.equ WDT_F = 2 ; Флаг WDT
.equ FFADE = 3 ; Нужно изменять яркость
.equ BORDER = 4 ; Достигнута границы регулировки
.equ BORDER_OK = 5 ; Вибра сработала
.equ PIN_SENSOR = PINB0 ; Вход сенсора
.equ PIN_PWM = PINB1 ; Выход ШИМ
.equ PIN_V = PINB2 ; Выход на вибру
.equ DREBEZG = 2 ; Число циклов WDT для устранения помех и дребезга
.equ LONG_PRESS = 28 ; Число циклов WDT для длинного нажатия
.equ STEP_PWM = 15 ; Шаг регулировки ШИМ
.equ MIN_SPWM = 0x2000 ; Минимальное значение яркости (real)
.equ MAX_PWM = 0x01FFF ; Максимальное значение ШИМ
.cseg
.org 0
; Таблица векторов прерываний
rjmp RESET ; RESET External Pin, Power-on Reset, VLM Reset and Watchdog Reset
reti ; INT0 External Interrupt Request 0
reti ; PCINT0 Pin Change Interrupt Request 0
reti ; TIM0_CAPT Timer/Counter0 Capture
;.org OVF0addr
rjmp TIM0_OVF ; TIM0_OVF Timer/Counter0 Overflow
reti ; TIM0_COMPA Timer/Counter0 Compare Match A
reti ; TIM0_COMPB Timer/Counter0 Compare Match B
reti ; ANA_COMP Analog Comparator
rjmp WDT ; WDT Watchdog Time-out Interrupt
reti ; VLM VCC Voltage Level Monitor
#if defined(__ATtiny5__) || defined(__ATtiny10__)
reti ; ADC ADC Conversion Complete (The ADC is only available in ATtiny5/10)
#endif
.org INT_VECTORS_SIZE
RESET:
; Запрещаем прерывания
cli
; Настраиваем тактирование (выключаем предделитель на 8)
ldi TMP, 0xD8
out CCP, TMP
clr TMP
out CLKPSR, TMP
; Установить указатель стэка в конец оперативной памяти
ldi TMP, low(RAMEND)
out SPL, TMP
ldi TMP, high(RAMEND)
out SPH, TMP
; Настраиваем Watchdog Timer (32ms)
ldi TMP, 0xD8
out CCP, TMP
ldi TMP, (1<<WDIE)|(1<<WDP0)
out WDTCSR, TMP
; Разрешаем прерывания
sei
; Выключаем лишнюю переферию (для ATtiny5/10)
#if defined(__ATtiny5__) || defined(__ATtiny10__)
ldi TMP, (1<<PRADC)
out PRR, TMP
#endif
; Настраиваем порт на выход
ldi TMP, (1<<PIN_PWM)|(1<<PIN_V)
out DDRB, TMP
cbi PORTB, PIN_PWM
cbi PORTB, PIN_V
; Начальные значения
ser PWMH
ser PWML
ser SPWML
ser SPWMH
ldi TMP, high(MAX_PWM)
out OCR0AH, TMP
ldi TMP, low(MAX_PWM)
out OCR0AL, TMP
ldi COUNT, 0x00
ldi FLAG, 0x00
; Основная программа
MAIN:
sbis PINB, PIN_SENSOR
rjmp UN_PRESS
cpi COUNT, LONG_PRESS
brge FADE
inc COUNT
rjmp END
; Меняем яркость
FADE:
; Если свет выключен, то включаем на полную
sbrc FLAG, ON_OFF
rjmp FADE_ON
ser SPWMH
ser SPWML
sbr FLAG, (1<<UP_DOWN)|(1<<ON_OFF)
rcall TIMER_ON
rjmp END
FADE_ON:
sbr FLAG, (1<<FFADE)
rjmp END
UN_PRESS:
; Проверка на слишком короткое нажатие
cpi COUNT, DREBEZG
brlt END_MAIN
; Проверка на короткое нажатие
cpi COUNT, LONG_PRESS
brge END_FADE
; Нажатие было короткое
sbrc FLAG, ON_OFF
rjmp SHORT_OFF
; Включить свет
rcall TIMER_ON
sbr FLAG, (1<<ON_OFF)
rjmp END_MAIN
; Выключить свет
SHORT_OFF:
rcall TIMER_OFF
cbr FLAG, (1<<ON_OFF)
rjmp END_MAIN
; Меняем направление изменения яркости, если свет включен
END_FADE:
cbr FLAG, (1<<FFADE)
ldi TMP, (1<<UP_DOWN)
eor FLAG , TMP
; Конец главного цикла
END_MAIN:
clr COUNT
cbr FLAG, (1<<BORDER)|(1<<BORDER_OK)
END:
rcall IDLE
rjmp MAIN
; *******************************************
; *-------------- ПОДПРОГРАММЫ -------------*
; *******************************************
; Уход в спячку и выход только по WDT
IDLE:
ldi TMP, (1<<SE)
sbrs FLAG, ON_OFF
sbr TMP, (1<<SM1)
out SMCR, TMP
sleep
sbrs FLAG, WDT_F
rjmp IDLE
cbr FLAG, (1<<WDT_F)
ret
; Запуск таймера и ШИМ
TIMER_ON:
; Настраиваем таймер (clk, 16 бит, Fast PWM, TOP OCR0A)
out OCR0BH, PWMH
out OCR0BL, PWML
clr TMP
out TCNT0H, TMP
out TCNT0L, TMP
ldi TMP, (1<<COM0B1)|(1<<WGM00)|(1<<WGM01)
out TCCR0A, TMP
ldi TMP, (1<<CS00)|(1<<WGM02)|(1<<WGM03)
out TCCR0B, TMP
ldi TMP, (1<<TOIE0)
out TIMSK0 , TMP
ret
; Остановка таймера
TIMER_OFF:
clr TMP
out TCCR0B, TMP
out TCCR0A, TMP
out TIMSK0 , TMP
cbi PORTB, PIN_PWM
ret
; *******************************************
; *---------- ОБРАБОТКА ПРЕРЫВАНИЙ ---------*
; *******************************************
; Прерывание по переполнению таймера
TIM0_OVF:
; Сохраняем SREG
in TMPL, SREG
push TMPL
; Сразу меняем скважность
out OCR0BH, PWMH
out OCR0BL, PWML
; Проверяем нужно ли менять яркость
sbrs FLAG, FFADE
rjmp TIM0_OVF_END
; В какую сторону менять яркость?
sbrc FLAG, UP_DOWN
rjmp FADE_UP
; Уменьшаем яркость
ldi TMPL, low(STEP_PWM)
ldi TMPH, high(STEP_PWM)
sub SPWML, TMPL
sbc SPWMH, TMPH
ldi TMPL, low(MIN_SPWM)
ldi TMPH, high(MIN_SPWM)
cp SPWML, TMPL
cpc SPWMH, TMPH
brcc NEW_PWM
mov SPWML, TMPL
mov SPWMH, TMPH
sbr FLAG, (1<<BORDER)
rjmp NEW_PWM
; Увеличиваем яркость
FADE_UP:
ldi TMPL, low(STEP_PWM)
ldi TMPH, high(STEP_PWM)
add SPWML, TMPL
adc SPWMH, TMPH
brcc NEW_PWM
ser SPWMH
ser SPWML
ldi PWMH, high(MAX_PWM)
ldi PWML, low(MAX_PWM)
; ser PWML
; ser PWMH
sbr FLAG, (1<<BORDER)
rjmp TIM0_OVF_END
NEW_PWM:
; Вычисляем новое значение ШИМ
mov mc16uL, SPWML
mov mc16uH, SPWMH
mov mp16uL, SPWML
mov mp16uH, SPWMH
rcall mpy16u
mov mc16uL, SPWML
mov mc16uH, SPWMH
mov mp16uL, m16u2
mov mp16uH, m16u3
rcall mpy16u
mov PWML, m16u2
mov PWMH, m16u3
ror PWMH
ror PWML
ror PWMH
ror PWML
ror PWMH
ror PWML
cbr PWMH, 0b11100000
TIM0_OVF_END:
; Возвращаем SREG
pop TMPL
out SREG, TMPL
reti
; Прерывание Watchdog таймера
WDT:
cbi PORTB, PIN_V
sbrs FLAG, BORDER
rjmp WDTI_END
sbrc FLAG, BORDER_OK
rjmp WDTI_END
sbi PORTB, PIN_V
sbr FLAG, (1<<BORDER_OK)
WDTI_END:
sbr FLAG, (1<<WDT_F)
reti
; AVR(200)
mpy16u:
clr m16u3
clr m16u2
ldi mcnt16u, 16
lsr mp16uH
ror mp16uL
m16u_1:
brcc noad8
add m16u2, mc16uL
adc m16u3, mc16uH
noad8:
ror m16u3
ror m16u2
ror m16u1
ror m16u0
dec mcnt16u
brne m16u_1
ret