Код: Выделить всё
.equ LEDS1_DDR = DDRA
.equ LEDS1_PORT = PORTA
.equ LEDS2_DDR = DDRC
.equ LEDS2_PORT = PORTC
.equ QUANT_LEDS = 16
.equ BAM_SPEED = 1<<CS22 // | 1<<CS20
.equ PROC_BAM_TIME = 5
.def CNT_BAM_BITS = r5
.def BAM_OCR_VAL = r6
.def LED_REG_1 = r7
.def LED_REG_2 = r8
.def CNT_LEDS = r9
.def POINT_BAM_VAL_L = r14 // Указатель на текущий адрес таблицы эффектов.
.def POINT_BAM_VAL_H = r15 // Указатель на текущий адрес таблицы эффектов.
//==================
Def_Err_ID ERR_ID_PROC_BAM
//==================
.dseg
//==================
_PROC_BAM: // Состояние автомата.
.byte 1
.equ DISP_PROC_BAM = 0 // Смещение относительного начальнога адреса переменных.
EMPTY_BUF:
.byte 3
LEDS_BRIGHT_VAL_BUF: // Буфер состояния светодиодов (1 байт) и обрабатываемых в данный момент битов-состояния светодиодов (второй байт).
.byte QUANT_LEDS
LEDS_BAM_VAL:
.byte QUANT_LEDS
//==================
.cseg
//==================
Read_Prgm_Led_Bright_Val: // Подпрограмма считывания текущего значения яркости светодиодов.
movw ZH:ZL, r15:r14
clt
Read_Prgm_Led_Bright_Val_A:
ser r17
lpm r16, Z+
cp r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z+
cpc r16, r17
lpm r16, Z
cpc r16, r17
brne Read_Prgm_Led_Bright_Val_B
ldz Table_Proc_BAM*2
rjmp Read_Prgm_Led_Bright_Val_A
Read_Prgm_Led_Bright_Val_B:
sbiw ZL, 15
ldi CNT, QUANT_LEDS
ldx LEDS_BRIGHT_VAL_BUF
Read_Prgm_Led_Bright_Val_Cycle:
lpm r16, Z+
st X+, r16
dec CNT
brne Read_Prgm_Led_Bright_Val_Cycle
movw r15:r14, ZH:ZL
Read_Prgm_Led_Bright_Val_End:
ret
Out_Leds_State: // Подпрограмма вывода состояния светодиодов.
clr r17
clr LED_REG_1
clr LED_REG_2
clr r19 // Счетчик тиков BAM. 8
Out_Leds_State_Cycle_1:
ldi r16, QUANT_LEDS/8
mul r16, r19
movw ZH:ZL, r1:r0
subi ZL, LOW (-LEDS_BAM_VAL)
sbci ZH, HIGH (-LEDS_BAM_VAL)
ldx LEDS_BRIGHT_VAL_BUF
clr r18 // Кол-во светодиодов.
Out_Leds_State_Cycle_2:
ld r16, X // Считываем текущий бит состояния светодиодов.
sbrs r16, 7
rjmp Out_Leds_State_A
setb r17, 7
Out_Leds_State_A:
lsl r16 // Сдвиг.
st X+, r16 // Cледующий бит-состояние светодиодов.
lsl r17
rol LED_REG_1
rol LED_REG_2
inc r18
cpi r18, QUANT_LEDS
brlo Out_Leds_State_Cycle_2
st Z+, LED_REG_1
st Z, LED_REG_2
clr r17
clr LED_REG_1
clr LED_REG_2
inc r19
cpi r19, 8
brlo Out_Leds_State_Cycle_1
Out_Leds_State_End:
ldx LEDS_BAM_VAL
ld r16, X+
out LEDS1_PORT, r16
ld r16, X
out LEDS2_PORT, r16
ret
//==================
//==================
Proc_BAM_Save_Val:
std Y+DISP_PROC_BAM, FSM_STATE
ret
//==================
//==================
Proc_BAM:
pushiwl Proc_BAM_Save_Val // Стек на сохранение переменных
ldy _PROC_BAM // Указатель на переменные.
ldd FSM_STATE, Y+DISP_PROC_BAM // Считывание состояния автомата.
Proc_FSM Tab_FSM_PROC_BAM // Индексный переход. Состояние автомата - индекс обработчиков состояний.
Proc_BAM_Init:
clr r16
out LEDS1_PORT, r16
out LEDS2_PORT, r16
ser r16
out LEDS1_DDR, r16
out LEDS2_DDR, r16
ldi ZH, HIGH(Table_Proc_BAM*2) // Установка указателя на таблицу эффектов.
ldi ZL, LOW(Table_Proc_BAM*2)
movw r15:r14, ZH:ZL
rcall Read_Prgm_Led_Bright_Val // Считывание из таблицы значений яркости. Адрес в POINT_BAM_VAL.
clr r16
out TCNT2, r16 // Сброс счетчика.
in r16, TIMSK
setb r16, OCIE2 // Разрешение прерывания по совпадению.
out TIMSK, r16
ldi r16, 1
mov CNT_BAM_BITS, r16
ldi r16, 0b10000000
mov BAM_OCR_VAL, r16
out OCR2, BAM_OCR_VAL // Установка первого тика BAM.
// Примечание: так как это самое большое время (128) BAM, то вычисления нужно производить лучше в этот момент.
lsr BAM_OCR_VAL // Сдвиг. Следующий тик BAM (0x01000000).
in r16, TCCR2
sbr r16, BAM_SPEED
out TCCR2, r16
rcall Out_Leds_State // Вывод текущего состояния светодиодов.
Set_Timer Par_Tim_Proc_BAM // Установка таймера. PROC_BAM_TIME.
Set_State _PROC_BAM_RUN // Установка состояния.
Proc_BAM_Init_End:
ret
Proc_BAM_Run:
Proc_Timer Par_Tim_Proc_BAM // Обработчик таймера. Флаг SREG T=1 - время вышло.
brtc Proc_BAM_Run_End
in r16, TIMSK
clrb r16, OCIE2 // Отключаем прерывание, дабы не загадило следующее считываемое и записанное в ОЗУ значение яркости.
out TIMSK, r16
in r16, TCCR2
cbr r16, BAM_SPEED // Останавливаем счетчик
out TCCR2, r16
rcall Read_Prgm_Led_Bright_Val // Считывание из таблицы значений яркости. Адрес в POINT_BAM_VAL.
clr r16
out TCNT2, r16 // Сброс счетчика.
rcall Out_Leds_State // Вывод текущего состояния светодиодов.
ldi r16, 1<<OCF2 // Сброс флага прерывания по совпадению.
out TIFR, r16
in r16, TIMSK
setb r16, OCIE2 // Разрешение прерывания по совпадению.
out TIMSK, r16
ldi r16, 1
mov CNT_BAM_BITS, r16
ldi r16, 0b10000000
mov BAM_OCR_VAL, r16
out OCR2, BAM_OCR_VAL // Установка первого тика BAM.
// Примечание: так как это самое большое время (128) BAM, то вычисления нужно производить лучше в этот момент.
lsr BAM_OCR_VAL // Сдвиг. Следующий тик BAM (0x01000000).
in r16, TCCR2
sbr r16, BAM_SPEED
out TCCR2, r16
Set_Timer Par_Tim_Proc_BAM
Proc_BAM_Run_End:
ret
//==================
//==================
Proc_Int_BAM:
push r16
in r16, SREG
push r16
push XL
push XH
mov r16, CNT_BAM_BITS
cpi r16, 8
brlo Proc_Int_BAM_A // Если не нуль, то переход.
clr CNT_BAM_BITS
ldi r16, 0b10000000 // Установка первого тика BAM.
mov BAM_OCR_VAL, r16
Proc_Int_BAM_A:
ldi r16, QUANT_LEDS/8
mul r16, CNT_BAM_BITS
movw XH:XL, r1:r0
subi XL, LOW (-LEDS_BAM_VAL)
sbci XH, HIGH (-LEDS_BAM_VAL)
ld r16, X+
out LEDS1_PORT, r16
ld r16, X
out LEDS2_PORT, r16
clr r16
out TCNT2, r16
out OCR2, BAM_OCR_VAL
inc CNT_BAM_BITS
lsr BAM_OCR_VAL // Сдвиг от большего к малому тиков BAM.
Proc_Int_BAM_End:
pop XH
pop XL
pop r16
out SREG, r16
pop r16
reti
//==================
//==================
Tab_FSM_PROC_BAM:
.db tab_h(_PROC_BAM), MAX_FSM_PROC_BAM_STATES, tab_h(Tab_Jmp_PROC_BAM), ERR_ID_PROC_BAM
Tab_Jmp_PROC_BAM:
.equ MAX_FSM_PROC_BAM_STATES = 2 // Количество состояний автомата.
.equ _PROC_BAM_INIT = 0
.db tab_h(Proc_BAM_Init)
.equ _PROC_BAM_RUN = 1
.db tab_h(Proc_BAM_Run)
Par_Tim_Proc_BAM:
par_timer ST_PROC_BAM, 1<<ST_UNLOCK_FLG, PROC_BAM_TIME
//==================
//==================
//==================
//==================
Table_Proc_BAM:
end_array
end_array
end_array
end_array
end_array
end_array
end_array
end_array
//==================