Вопрос про шим на attiny

Обсуждаем контроллеры компании Atmel.
Ответить
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Starichok51 писал(а):ссылка про 768 светодиодов на обычной атмеге не работает
ссылка гуглится и выводит на ютуб: https://www.youtube.com/watch?v=IDSIjb1AUuU
Там не 768, а поменьше, но все равно впечатляет. Сдвиговый регистр типа 74HC595 позволяет сделать по методу BAM регулирование ШИМа для светодиодов. Частота ШИМ получается невысокой, зато многоканальной. Светодиоду и 100 Гц хватит.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Это не хвост, это антенна
Сообщения: 1492
Зарегистрирован: Ср июн 25, 2008 15:19:44

Сообщение Demiurg »

Starichok51 писал(а):так, все-таки, как подключить много светодиодов с помощью ВАМ?
Я 16 светодиодов подключал. 32 уже лень было... Видео. Асм. Несколько лет назад. На си не переделывал.
Спойлер

Код: Выделить всё

.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
//==================

Вложения
Конструктор BAM.xls
(1.06 МБ) 157 скачиваний
Контактная информация:
Реклама
Встал на лапы
Сообщения: 122
Зарегистрирован: Ср фев 01, 2017 17:57:15

Сообщение IDok »

а не подскажете, какой МК выбрать? нужно 5-6 каналов аппаратного ШИМ и плюс свободный таймер для программного ШИМа. ну и портов вывода не меньше 15
урезаю осетра до 4 аппаратных ШИМ. Атмега-88 мне в руки, да?
Это не хвост, это антенна
Сообщения: 1492
Зарегистрирован: Ср июн 25, 2008 15:19:44

Сообщение Demiurg »

Целевое устройство проекта?
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Сообщения: 122
Зарегистрирован: Ср фев 01, 2017 17:57:15

Сообщение IDok »

управление кучей светодиодов. 4 канала на аппаратном ШИМе (оно красивее получается) и 9 каналов на программном (там и так сойдет). ШИМы будут работать по очереди, не одновременно
Реклама
Это не хвост, это антенна
Сообщения: 1492
Зарегистрирован: Ср июн 25, 2008 15:19:44

Сообщение Demiurg »

Выше видеопример управлением 16-ю светодиодами. Можно было и 32 замутить. Но мне стало лень паять. Вдобавок для 32 светодиодов еще нужно править конструктор таблицы в Excel.
Контактная информация:
Реклама
Встал на лапы
Сообщения: 122
Зарегистрирован: Ср фев 01, 2017 17:57:15

Сообщение IDok »

видео - это офигенно. но нет ли куска кода на баскоме? ну, для понимания.
ну и все таки по моему вопросу - Атмега88 имеет 3 таймера и 6 каналов ШИМ. я могу 2 таймера использовать под аппаратный ШИМ и один оставить для программного, верно?
Это не хвост, это антенна
Сообщения: 1492
Зарегистрирован: Ср июн 25, 2008 15:19:44

Сообщение Demiurg »

На баскоме вы навряд ли что-то готовое найдете. Поэтому только изучать алгоритмы. Правильно составленный алгоритм - вот что главное. Вам останется только программу по нему накидать.
Думаете у меня были готовые примеры? Отнюдь, писал с нуля на ассемблере. Главное мне было понятно. Как работает BAM.
Контактная информация:
Ответить

Вернуться в «AVR»