Код: Выделить всё
.nolist
;Пpогpамма "Вибро-таймер"
;Пpоцессоp ATtyny12L(V) Используется внутренний генератор на внешнем кварце 32 КГц
;Для данного устройства использован микроконтроллер:
;ATtyny12L(V)
;
;Биты конфигурации:
;Lock2 = Programmed (0)
;Lock1 = Programmed (0)
;
;SPIEN = Programmed (0)
;RSTDISBL = Unprogrammed (1) (!)
;BODLEVEL = Programmed (0)
;BODEN = Programmed (0)
;CKSEL3 = Unprogrammed (1)
;CKSEL2 = Programmed (0)
;CKSEL1 = Programmed (0)
;CKSEL0 = Unprogrammed (1)
;CKSEL для прошивки 1111 (для прошивки глючного МК)
;* биты конфигурации прошиваются после записи самой прошивки
; Сигналы:
; PB0 - вибратор
; PB1 - кнопка
; PB2 - светодиод
; PB3 - кварц
; PB4 - кварц
;Y - системный таймер (инкрементируется 16 раз в секунду)
;r15 - настройка интервала времени (0-5мин., 1-10, 2-20, 3-30, 4-40, 5-60)
;r14 - флаг о том что надо включить оповещение (0-нет, 1-да)
;r10 - всегда ноль
;r11 - всегда 1
;r24 - служкбный в прерывании
;r25 - служкбный в прерывании
;r13 - для выбора режима мигания в прерывании (FF-выключено, 0-мигает дежурно, n-мигает n/2 вспышек)
;r8 - буфер для SREG
.include "tn12def.inc"
.CSEG
.org $0000
rjmp start
rjmp intt0 ;INT0addr = 0x0001 ; External Interrupt 0
reti ;PCI0addr = 0x0002 ; External Interrupt Request 0
rjmp timer ;OVF0addr = 0x0003 ; Timer/Counter0 Overflow
reti ;ERDYaddr = 0x0004 ; EEPROM Ready
reti ;ACIaddr = 0x0005 ; Analog Comparator
start: ldi r16,3 ;установка 30 мин. при подаче питания
mov r15,r16
agein: cli ;запрет прерываний
clr r10
ldi r16,1
mov r11,r16
sbi ACSR,ACD ;отключить аналоговый компаратор
ldi r16,0b00000101 ;настройка порта ввода-вывода
out DDRb,r16
ldi r16,0b00000010
out PORTb,r16
wdr
ldi r16,0b00010110 ;запуск собачьего таймера
out WDTCR,r16
ldi r16,0b00011110
out WDTCR,r16
ldi r16,0b00000000 ;выключить внешнее прерывание по низкому уровню
out GIMSK,r16
ldi r16,0b00110000 ;настройка работы прерывания и выбор режима SLEEP
out MCUCR,r16
ldi r16,0b00000010 ;запуск таймера на 16 Гц
out TCCR0,r16 ;прерывания при переполнении
ldi r16,0b00000010
out TIMSK,r16 ;включить от него прерывание
clr YL
clr YH
clr r14
ser r16
mov r13,r16
sei
sbi PORTb,0 ;включаем светодиод и вибро
sbi PORTb,2
ldi r17,70 ;1.5сек.
on6: wdr
rcall delay
dec r17
brne on6
cbi PORTb,0 ;выключаем светодиод и вибро
cbi PORTb,2
mov r16,r15 ;даём команду промигать число в зависимости от установленного интервала
inc r16
mov r13,r16
res_b1: ldi r17,10 ;ожидаем отпускание кнопки
wait2: wdr
rcall delay
in r16,PINb
andi r16,0b00000010
breq res_b1
dec r17
brne wait2
ser r18
main: wdr ;основной цикл
tst r14
brne alarm
rcall delay
in r16,PINb
andi r16,0b00000010
brne rst_b1
dec r18
brne main
rjmp pwroff
rst_b1: cpi r18,123 ;время после которого считается что кнопка была нажата
brlo press
ldi r18,125 ;время ожидания удержания кнопки для выключения
rjmp main
press: inc r15
mov r16,r15
cpi r16,6
brlo skip
clr r15
skip: rjmp agein ;изменяем режим и перезапускаемся
alarm: clr r14 ;процедура оповещения
ser r16
mov r13,r16
sbi PORTb,0 ;включаем светодиод и вибро
sbi PORTb,2
ldi r17,45 ;1сек.
on1: wdr
rcall delay
dec r17
brne on1
cbi PORTb,0 ;выключаем светодиод и вибро
cbi PORTb,2
ldi r17,45 ;1сек.
on2: wdr
rcall delay
dec r17
brne on2
sbi PORTb,0 ;включаем светодиод и вибро
sbi PORTb,2
ldi r17,45 ;1сек.
on3: wdr
rcall delay
dec r17
brne on3
cbi PORTb,0 ;выключаем светодиод и вибро
cbi PORTb,2
clr r13
rjmp main
delay: clr r16
del1: dec r16
brne del1
ret
pwroff: clr r14 ;процедура выключения питания
ser r16
mov r13,r16
sbi PORTb,0 ;включаем светодиод и вибро
sbi PORTb,2
ldi r17,25 ;0.5сек.
on5: wdr
rcall delay
dec r17
brne on5
cbi PORTb,0 ;выключаем светодиод и вибро
cbi PORTb,2
res_c1: ldi r17,10 ;ожидаем отпускание кнопки
wait5: wdr
rcall delay
in r16,PINb
andi r16,0b00000010
breq res_c1
dec r17
brne wait5
no_on: ldi r16,0b00000000 ;выключить таймер
out TCCR0,r16
wdr
ldi r16,0b00011110 ;остановка собачьего таймера
out WDTCR,r16
ldi r16,0b00000110
out WDTCR,r16
cli
ldi r16,0b01000000 ;включить внешнее прерывание по низкому уровню
out GIMSK,r16
ldi r16,0b01100000
out GIFR,r16
sei
sleep ;спим, батарейки не жрать!
ldi r17,100 ;ожидаем достаточного удержания кнопки
wait6: rcall delay
in r16,PINb
andi r16,0b00000010
brne no_on
dec r17
brne wait6
rjmp agein
intt0: ldi r24,0b00000000 ;выключить внешнее прерывание по низкому уровню
out GIMSK,r24
reti
timer: in r8,SREG
mov r24,r13 ;обработка прерывания от таймера (инкремент системного таймера) (16 раз в сек.)
cpi r24,$FF
brne led
ser r25
rjmp time
led: tst r24
breq stanby
cpi r25,$FF ;индикация режима
breq of_ld2
dec r25
brne time
in r24,PORTb
andi r24,0b00000100
breq on_ld2
of_ld2: ldi r25,8 ;время погашенного светодиода
cbi PORTb,2
dec r13
brne time
ser r25
rjmp time
on_ld2: ldi r25,5 ;время включенного светодиода
sbi PORTb,2
rjmp time
stanby: cpi r25,$FF
breq of_ld1
dec r25
brne time
in r24,PORTb
andi r24,0b00000100
breq on_ld1
of_ld1: ldi r25,48 ;время погашенного светодиода в режиме работы
cbi PORTb,2
rjmp time
on_ld1: ldi r25,1 ;время включенного светодиода в режиме работы
sbi PORTb,2
time: add YL,r11
adc YH,r10
mov r24,r15
cpi r24,1
breq min10
cpi r24,2
breq min20
cpi r24,3
breq min30
cpi r24,4
breq min40
cpi r24,5
breq min60
min5: cpi YH,high(4800)
brne end_i
cpi YL,low(4800)
brne end_i
rjmp zero
min10: cpi YH,high(9600)
brne end_i
cpi YL,low(9600)
brne end_i
rjmp zero
min20: cpi YH,high(19200)
brne end_i
cpi YL,low(19200)
brne end_i
rjmp zero
min30: cpi YH,high(28800)
brne end_i
cpi YL,low(28800)
brne end_i
rjmp zero
min40: cpi YH,high(38400)
brne end_i
cpi YL,low(38400)
brne end_i
rjmp zero
min60: cpi YH,high(57600)
brne end_i
cpi YL,low(57600)
brne end_i
rjmp zero
end_i: out SREG,r8
reti
zero: clr YL
clr YH
ldi r24,1
mov r14,r24
out SREG,r8
reti
Это из расчетов что 5 мин. = 4800, 1 мин.= 960, соответственно 24 мин.* 960 = 23040 . Этого изменения будет достаточно чтобы вместо 20 мин., он откликался на 24 мин.?
Спасибо.