Суммирование прямоугольных сигналов

Обсуждаем контроллеры компании Atmel.
kas1830
Открыл глаза
Сообщения: 46
Зарегистрирован: Ср янв 04, 2017 14:32:28

Суммирование прямоугольных сигналов

Сообщение kas1830 »

И снова здравствуйте!

Ранее экспериментировал с синтезом звука на AVR. По итогу сделал музыкальную шкатулку на ATTiny2313, где задействовал два таймера Т0 и Т1 в режиме СТС для вывода основной мелодии и бас-партии. Динамик, соответственно, смешивал все это хозяйство. Получилось неплохо.
Продолжая эту историю, заинтересовался, как технически суммируются прямоугольные импульсы? И можно ли обойтись в принципе одной ногой таймера в коде для вывода двух (и более нот) одновременно? Примерно, как на картинке ниже:

Изображение

Наглядный пример:



Буду благодарен за разъяснения и направление, куда копать дальше!
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25153
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Суммирование прямоугольных сигналов

Сообщение КРАМ »

[uquote="kas1830",url="/forum/viewtopic.php?p=4444709#p4444709"]как технически суммируются прямоугольные импульсы?[/uquote]
Так же, как и непрямоугольные и не импульсы - аналоговым сумматором. Простейший - резистивный. Можно сделать сумматор на ОУ.
veso74
Поставщик валерьянки для Кота
Сообщения: 1905
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Суммирование прямоугольных сигналов

Сообщение veso74 »

Для тонов с частотами в сотые доли герца нужна другая вычислительная мощность и ресурс. С AVR и указанным способом будет всего каких-то два тона. Рассмотрите как идею напр. NCO генератор, или два внешних генератора DDS. Будет легче.
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: Суммирование прямоугольных сигналов

Сообщение Jack_A »

[uquote="veso74",url="/forum/viewtopic.php?p=4444727#p4444727"]Для тонов с частотами в сотые доли герца[/uquote]
Сотые доли Герца можно сгенерировать на самом медленном оборудовании, даже на реле :)) Ну если период - десятки секунд - это даже арифмометр "Феликс" осилит :shock: Но музыку в диапазоне инфразвука оценит разве что осьминог.
СпойлерУ нас НИИ сдавало тему - простейшая цикловая схема управления роботом. Для демонстрации подобрали и подключили к выходам несколько пускателей разных габаритов. При срабатывнии они издавали щелчок разной тональности - зависит от массы якоря. Программа исполняла "Чижик-пыжик" :))
------------------------
Как-то в институте на скучной лекции я взялся посчитать - с какой частотой я получаю стипендию. Оказалоь 3,8 * 10^-7 Гц :)
Изображение
veso74
Поставщик валерьянки для Кота
Сообщения: 1905
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Суммирование прямоугольных сигналов

Сообщение veso74 »

Видимо переводчик БГ-РУ неправильно перевел мысль, но вы поняли. Я писал для 261,63 и 277,18 Hz.
kas1830
Открыл глаза
Сообщения: 46
Зарегистрирован: Ср янв 04, 2017 14:32:28

Re: Суммирование прямоугольных сигналов

Сообщение kas1830 »

Товарищи, спасибо всем, кто уже откликнулся.

В крайности уходить не стоит. Перефразирую вопрос проще: как на МК сгенерить одновременное звучание двух и более нот разной частоты? Типа аккорда. Какие есть технические варианты?
Аватара пользователя
Starichok51
Модератор
Сообщения: 19043
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Суммирование прямоугольных сигналов

Сообщение Starichok51 »

kas1830, тебе уже ответили - сложить сигналы обычным сумматором.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
kas1830
Открыл глаза
Сообщения: 46
Зарегистрирован: Ср янв 04, 2017 14:32:28

Re: Суммирование прямоугольных сигналов

Сообщение kas1830 »

Похожий пост по теме:
https://forum.cxem.net/index.php?/topic ... %B8%D1%8E/

Цитата:
...в памяти прописывается массив, отражающий форму элементарного сигнала, а затем делается выборка, сложение с выборкой другой(-ими) ноты, одновременно звучащей, и результирующий код (8 и более бит) подается на R2R, ЦАП, или ШИМ.
Как раз то, что я ищу. У меня записан массив нот в памяти.
Поделитесь пжл примером кода, если у кого есть, как производится сложение выборок, чтобы выводить полифонию
Аватара пользователя
Starichok51
Модератор
Сообщения: 19043
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Суммирование прямоугольных сигналов

Сообщение Starichok51 »

кроме массива нот нужен массив частот этих нот. и складываются частоты, а не ноты.

Добавлено after 10 minutes 30 seconds:
для лучшего понимания прочитай эту статью https://www.radiokot.ru/circuit/digital/game/51/
а также запусти поиск по фразе "синтез мелодий на AVR", и найдешь уйму информации по синтезу мелодий.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3868
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Суммирование прямоугольных сигналов

Сообщение Engineer_Keen »

Для складывания двух и более звуков, если используется AVR и ШИМ 8-10 бит, достаточно их все тупо сложить (с учетом знака) и при выходе за пределы разрядности тупо ограничить, т.е. если сумма для 8 бит>255, то результат будет 255, если меньше 0, то 0.
Да, при сложении может произойти искажение (перегрузка), ее можно обойти, заранее поделив громкость на количество одновременно складываемых звуков, но в этом скорее всего не будет необходимости, учитывая условия.
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
kas1830
Открыл глаза
Сообщения: 46
Зарегистрирован: Ср янв 04, 2017 14:32:28

Re: Суммирование прямоугольных сигналов

Сообщение kas1830 »

Спасибо за ответ.
[uquote="Engineer_Keen",url="/forum/viewtopic.php?p=4445419#p4445419"]...если используется AVR и ШИМ 8-10 бит[/uquote]
Тут у меня как раз не ШИМ, а СТС режим. Будет аналогично или есть особенности?
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15549
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Суммирование прямоугольных сигналов

Сообщение BOB51 »

ГЫММ...
В данном случае похоже не сумматор, а смеситель нужен...
https://ru.wikipedia.org/wiki/Смеситель_(электроника)
:roll:
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3868
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Суммирование прямоугольных сигналов

Сообщение Engineer_Keen »

[uquote="kas1830",url="/forum/viewtopic.php?p=4445437#p4445437"]Тут у меня как раз не ШИМ, а СТС режим. Будет аналогично или
есть особенности?[/uquote]

Э погодите-ка, тут есть варианты...
Если вы генирируете звук при помощи сложения разных меандров, т.е. используете режим CTC для задания частот именно самих звуковых волн и ЭТИ волны надо микшировать, то действительно, это проще сделать внешним смесителем. Кстати, можно использовать один железный таймер, а частоты меандров синтезировать программно, используя вариант ниже.

А вот если режим CTC нужен для задания частоты квантования и по этой частоте вы бы через ШИМ выводили семплы, то суммировать их можно методом, который я описал выше.

Кстати, и для задачи частоты квантования и для ШИМ (даже стерео) можно использовать всего ОДИН таймер, причем частоту квантования можно задавать в широких пределах, в том числе близкую к стандартным 11-22-44кГц. Для этого таймер настраивается в режим CTС со сравнением с ICR, в ICR заносится нужное для заданной частоты квантования значение. А семплы нормируются с учетом этого значения и выводятся в OCRA и OCRB в прерывании по переполнению.
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Аватара пользователя
Asmodey
Друг Кота
Сообщения: 6164
Зарегистрирован: Сб янв 28, 2006 22:47:24

Re: Суммирование прямоугольных сигналов

Сообщение Asmodey »

В некоторых моделях PIC микроконтроллеров присутствует периферийный модуль DATA SIGNAL MODULATOR. Возможно подойдет для поставленных топикстартером целей.
Астролябия-сама меряет, было бы что мерять!!!
veso74
Поставщик валерьянки для Кота
Сообщения: 1905
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Суммирование прямоугольных сигналов

Сообщение veso74 »

Или с тремя NCO генераторами (напр. PIC18F25Q43), но отклоняемся от темы.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15549
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Суммирование прямоугольных сигналов

Сообщение BOB51 »

Модулятор и в старших АВРках есть...
:roll:
Аватара пользователя
Asmodey
Друг Кота
Сообщения: 6164
Зарегистрирован: Сб янв 28, 2006 22:47:24

Re: Суммирование прямоугольных сигналов

Сообщение Asmodey »

Ну так то в старших, а у PIC в копеечных младших имеются.
Астролябия-сама меряет, было бы что мерять!!!
kas1830
Открыл глаза
Сообщения: 46
Зарегистрирован: Ср янв 04, 2017 14:32:28

Re: Суммирование прямоугольных сигналов

Сообщение kas1830 »

Э погодите-ка, тут есть варианты...
Если вы генерируете звук при помощи сложения разных меандров, т.е. используете режим CTC для задания частот именно самих звуковых волн и ЭТИ волны надо микшировать, то действительно, это проще сделать внешним смесителем. Кстати, можно использовать один железный таймер, а частоты меандров синтезировать программно, используя вариант ниже.

А вот если режим CTC нужен для задания частоты квантования и по этой частоте вы бы через ШИМ выводили семплы, то суммировать их можно методом, который я описал выше.
Спасибо, а можно поподробнее (или пример)? Пока непонятно. что с чем складывать.
У меня два таймера Т0 и Т1 тикают независимо в режиме СТС, далее в прерывании каждый дергает свою ногу, с частотой, заданной регистром сравнения.
Динамик соединен с двумя выводами МК и делает всю работу по смешению за меня.
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3868
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Суммирование прямоугольных сигналов

Сообщение Engineer_Keen »

Ну вот так, например...
Код для суммирования 4х меандров (2 отключил чтобы понятнее сумма выглядела). Тактовая для Mega88 - 8МГц, частота семплов 22кГц, использован один 16 разрядный таймер, и одно его прерывание, 20 байт ОЗУ, и 270 флеша, загрузка контроллера ~45%.
Спойлер

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

;программа сложения 4х прямоугольных сигналов с произвольными частотами

	.include	"m88def.inc"				;определения для Mega88
	.include	"MacroAVR.asm"				;макросы для упрощения кода

	.equ	F_CPU=8000000					;частота контроллера

	.equ	SND_SAMPLE_FREQ		=22050			;частота выборок
	.equ	SND_OCR_VALUE		=F_CPU/SND_SAMPLE_FREQ	;расчет значения для режима CTC
	.equ	SND_MID_VALUE		=SND_OCR_VALUE/2	;половина выходного сигнала
	.equ	NUMBER_OF_SIGNALS	=4			;количество смешиваемых сигналов

	.equ	FREQ0	=261		;C4			;частоты сигналов
	.equ	FREQ1	=311		;D#4
	.equ	FREQ2	=110		;A2
	.equ	FREQ3	=61		;B1

	.equ	DIV0	=SND_SAMPLE_FREQ/FREQ0/2		;расчет делителей
	.equ	DIV1	=SND_SAMPLE_FREQ/FREQ1/2		;для частоты каждого сигнала
	.equ	DIV2	=SND_SAMPLE_FREQ/FREQ2/2
	.equ	DIV3	=SND_SAMPLE_FREQ/FREQ3/2

	.def	ZERO	=R2					;для ускорения арифметики
	.def	STR	=R3					;для ускорения вх/вых в прерывание

			;структура данных для одного сигнала
	.equ	PH_OFFSET	=0				;фаза
	.equ	DIV_OFFSET	=2				;делитель
	.equ	OUT_OFFSET	=4				;значение на выходе
	.equ	SIGNAL_SIZE	=2+2+1				;ее размер

	.dseg		;сегмент данных
SIG:		.byte	SIGNAL_SIZE*NUMBER_OF_SIGNALS		;данных сигналов

	.cseg		;сегмент кода
	.org	0
	RJMP	RESET

	.org	OVF1addr
	RJMP	SAMPLE_OUT	;прерывание для расчета и вывода семпла

DIVS:
	.dw	DIV0,DIV3,0,0	;рассчитанная таблица частот сигналов (0-отключено для наглядности)
;	.dw	DIV0,DIV1,DIV2,DIV3

RESET:	SETSTACK			;установка стека
	OUTI	CLKPR,(1<<CLKPCE)	;сброс делителя тактовой
	STS	CLKPR,ZERO
	OUTI	DDRC,(1<<PC4)|(1<<PC3)|(1<<PC2)|(1<<PC1)|(1<<PC0);тестовые выходы 
	OUTI	TCCR1A,(1<<COM1A1)|(1<<WGM11)|(0<<WGM10)	;настройка таймера CTC, TOP=ICR
	OUTI	TCCR1B,(1<<WGM12)|(1<<WGM13)|(1<<CS10)
	OUTI	ICR1H,High(SND_OCR_VALUE)		;период квантования
	OUTI	ICR1L,Low(SND_OCR_VALUE)
	OUTI	OCR1AH,High(SND_MID_VALUE)		;в ШИМ - половина уровня
	OUTI	OCR1AL,Low(SND_MID_VALUE)
	LDS	R16,TIMSK1				;вкл. прерывания OVF1
	ORI	R16,(1<<TOIE1)
	STS	TIMSK1,R16
	SBI	DDRB,PB1				;включить вывод ШИМ
	SETZ	DIVS*2					;копирование таблицы из флеша
	SETY	SIG					;в структуру сигнала
	LDI	R17,NUMBER_OF_SIGNALS
DLOOP:	LPM	XL,Z+					;чтение делителя
	LPM	XH,Z+
	STD	Y+PH_OFFSET+0,XH			;запись начального значения фазы
	STD	Y+PH_OFFSET+1,XL
	STD	Y+DIV_OFFSET+0,XH			;и это же значение в делитель
	STD	Y+DIV_OFFSET+1,XL
	STD	Y+OUT_OFFSET,ZERO			;значение функции изначально=0
	ADIW	YL,SIGNAL_SIZE			;переход к следюущему 
	DJNZ	R17,DLOOP				
	SEI						;вкл. глобальных прерываний

LOOP:	SETX	SIG+OUT_OFFSET				;основной цикл
	LDI	R17,NUMBER_OF_SIGNALS			;просто вывод
	CLR	R18					;значения функций на выходы
OLOOP:	LD	R16,X					;для наглядности
	BST	R16,7
	BLD	R18,4
	LSR	R18
	ADIW	XL,SIGNAL_SIZE
	DJNZ	R17,OLOOP
	IN	R16,PORTC
	ANDI	R16,0xF0
	OR	R16,R18
	OUT	PORTC,R16
	RJMP	LOOP

			;процедура вывода семпла
SAMPLE_OUT:
	SBI	PORTC,PC4	;вывод загрузки контроллера процедурой
	IN	STR,SREG	;сохранение SREG и регистров
	PUSH	R17
	PUSH	R16
	PUSHX
	PUSHY
	PUSHZ
	LDI	ZL,0x08		;начальное значение суммы сигналов
	LDI	R17,NUMBER_OF_SIGNALS
	SETY	SIG		;установка на структуру первого сигнала
SLOOP:	LDD	XH,Y+PH_OFFSET+0	;чтение фазы
	LDD	XL,Y+PH_OFFSET+1
	CP	XL,ZERO
	CPC	XH,ZERO
	BREQ	SKIP			;если 0, про сигнал не обрабатывать
	LDD	R16,Y+OUT_OFFSET	;чтение значения на выходе
	SBIW	XL,1			;уменьшаем фазу
	BRNE	NO_INVERT		;если не 0, переход к сохранению
	COM	R16			;если 0, инвертируем выход
	STD	Y+OUT_OFFSET,R16	;сохраняем значение на выходе
	LDD	XH,Y+DIV_OFFSET+0	;перезагружаем значение фазы
	LDD	XL,Y+DIV_OFFSET+1
NO_INVERT:
	STD	Y+PH_OFFSET+0,XH	;сохраняем фазу
	STD	Y+PH_OFFSET+1,XL
	SBRC	R16,7			;суммируем значения на выходах
	INC	ZL			
	SBRS	R16,7
	DEC	ZL
SKIP:	ADIW	YL,SIGNAL_SIZE		;переход к следующему
	DJNZ	R17,SLOOP

	CJNE	ZL,0x08,NO_HALF		;проверка суммы значений и преобразование в ШИМ
	SETZ	SND_MID_VALUE		;если сумма=0, выводим половину в ШИМ
	RJMP	OCR_SET
NO_HALF:CJLO	ZL,0x08,OUT_MIN		;если сумма<0, выводим в ШИМ 0
	SETZ	SND_OCR_VALUE-1		;если сумма>0, выводим в ШИМ максимальное значение
	RJMP	OCR_SET
OUT_MIN:SETZ	0
OCR_SET:
	STS	OCR1AH,ZH		;вывод в регистры ШИМ
	STS	OCR1AL,ZL
	POPZ				;восстановление регистров
	POPY
	POPX
	POP	R16
	POP	R17
	OUT	SREG,STR
	CBI	PORTC,PC4
	RETI
Результат. Зеленый (после RC-цепочки) = желтый+синий. Нижний осциллограф - ШИМ, и загрузка контроллера.
СпойлерИзображение

PS: О, зацените игрушку :idea:
всего 146 байт флеша и 14 ОЗУ, работает от встроенного RC на 8МГц, 7 кнопок, можно все сразу нажать, будет 7 меандров на выходе и еще 66% процессорного времени свободно. Можно прикрутить читалку нот по таймеру и готова музыкальная шкатулка :))) :facepalm:
SYNTH_TEST.rar
(47.78 КБ) 67 скачиваний
Вложения
SUM4.PNG
(38.45 КБ) 185 скачиваний
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Суммирование прямоугольных сигналов

Сообщение Аlex »

http://www.pic24.ru/doku.php/osa/articles/pk2_osa_piano
Сделано на каком-то дубовом камне.
Ответить

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