23.10.2005, 18:34
общий
это ответ
Здравствуйте, Pettimm!
Насколько я понимаю, такого количество таймеров в контроллере нет? Тогда частоты необходимо синтезировать. Формула синусоиды:
y = a*sin (2*pi*f*t), где
y - выходной сигнал,
a - амплитуда,
f - частота,
t - время.
Дальше создается цикл, который выводит на каждую ногу контроллера (а там цапы стоят?) выходной сигнал ("у" в формуле) и увеличивает значение времени t. Чем больше раз в секунду данный цикл сможет выполняться, чем больше будет частота дискретизации, а значит синусоиды получатся более качественными. Для синтеза частоты 1700 гц более менее синусоидальной формы необходимо, чтобы цикл мог выполняться хотя бы по 8 раз на один период сигнала (т.е. 1700*8 раз в секунду).
Естественно, что считать синус "на лету" слишком долго, поэтому на практике создают в памяти таблицу синуса. Удобно, чтобы ее размер был равен 2^n, где n - какое либо число, например 8. Формулу в приведенном мной виде опять же использовать нецелесообразно, т.к. всех этих умножений можно избежать. Вот пример на асме х86, под контроллер переведешь сам (см. приложение).
В программе используется 256-ти байтная таблица синуса, каждый байт которой представляет отдельное значение. переменная sin1pos содержит "позицию" первого генератора. Старшие 8 бит позиции отражают реальную позицию в таблице синуса, а младшие 24 используются для повышения точности синтезируемой частоты. Скорость sin1spd определяет выходную частоту и рассчитывается исходя из того, сколько раз в секунду будет выполняться данный цикл (на контроллере можно либо повесить его на прерывание, которое вызывать с заданной частотой по таймеру, либо просто рассчитать скорость выполнения исходя из количества тактов требуемых для каждой команды и тактовой частоты (на спектруме можно было применять только второй вариант)). Если, например, ты хотел бы синтезировать частоту 1 Гц, а цикл выполнялся бы у тебя 256 раз в секунду, то скорость должна была бы быть равна 0х01000000. Если бы 512 раз в секунду - то 0х00800000 и т.п.
Приложение:
sintbl db ..... ; sinus table is defined heresin1pos dd 0 ; current position of the first generatorsin1spd dd ? ; speed of the first generator...cycle: mov eax, [sin1pos] add eax, [sin1spd] mov [sin1pos], eax shr eax, 24 mov al, [offset sintbl + eax] ; here al = output level ... jmp cycle