leoniv (leoniv) wrote,
leoniv
leoniv

Category:

Знакомый незнакомый PWM



Решил добавить в новый генератор цифровую калибровку смещения нуля в каналах задания амплитуды и смещения.



Для задания амплитуды и смещения используются каналы PWM, реализованные внутри FPGA. Ранее ничего не калибровалось, использовались PWM с величиной кванта, равной шагу перестройки (10 мВ). Всего 1500 квантов. Теперь же понадобилось увеличить разрешение PWM, чтобы получить запас для калибровки. Увеличил число квантов до 6000. И тут возникли проблемы. Частота PWM упала, фильтры первого порядка, заложенные для фильтрации PWM, уже не справлялись, на выходе появились заметные пульсации. Изменить номиналы фильтра затруднительно, неполярные керамические конденсаторы и так самые большие, какие только есть в доме (2.2 мкФ), а увеличение резисторов приведет к увеличению погрешностей по причине входных токов ОУ. Да и время установления уже некуда дальше увеличивать.

Было решено изменить способ формирования PWM. В запасе был метод, основанный на алгоритме Брезенхема. Этот алгоритм обычно используется для рисования наклонных отрезков в растровой графике. Вообще, он более универсален и позволяет равномерно распределить Y каких-либо вещей на отрезке длиной X. В задаче формирования PWM он способен равномерно распределить установленное количество импульсов по всему периоду PWM, а не группировать их в начале периода, как это происходит в обычном PWM. Сказано - сделано. Поскольку ноль шкалы генератора находится почти посередине шкалы PWM, на выходе PWM получился почти меандр частотой 50 МГц. Мало того, что буфер 74HCT04, запитанный от Vref не справлялся, так и выходные ОУ раскалились так, что за них не взяться. Те остатки ВЧ-напряжения, которые просочились сквозь ФНЧ, ввергли низкочастотный ОУ в полное микросхемное отчаяние. Решение, с самого начала казавшееся сомнительным, на практике оказалось непригодным.

Тут вспомнились картинки, которые я видел, бродя щупом осциллографа внутри старых телевизоров. А именно способ формирования напряжения настройки процессорами телевизоров, такими как PCA84C640. На выходе PWM ЦАП-а настройки там был не просто PWM, а еще и небольшой дрожащий хвостик за каждым импульсом. Вероятность появления этого хвостика определялась кодом в младших разрядах PWM. Найденная документация весьма смутно описывала внутренности телевизионного процессора. Видно только, что PWM ЦАП разбит на две части, грубую и точную.



Самое простое, что можно предположить, это формирование за импульсом грубой части PWM еще одного импульса единичной длительности, который появляется один раз в N периодов. Например, грубая часть формирует импульс, ширина которого кодирует число 10. Если каждый десятый период этот импульс будет удлинен на один квант, то представленное число будет 10.1. Если два импульса на десять периодов - то 10.2. Оказывается, дополнительные импульсы формируются не подряд.



От этой временной диаграммы повеяло чем-то знакомым. Дополнительные импульсы равномерно распределены по всему интервалу! Именно это делает алгоритм Брезенхема. Но чтобы избежать переноса всей энергии спектра в слишком уж высокочастотную область (оказывается, это тоже может быть вредным!), брезенхемовский PWM (точную часть) можно скомбинировать с обычным PWM (грубой частью). Меняя соотношение разрядностей грубой и точной части, можно разместить основную энергию PWM-сигнала на любой желаемой частоте.

В итоге так было и сделано. Грубую часть PWM (250 квантов) дополнил точной брезенхемовской частью (60 квантов). В итоге получил PWM с количеством квантов 15000, это примерно соответствует 14-разрядному PWM. Но при этом у него основная спектральная составляющая лежит на такой же частоте, как у 8-разрядного PWM. Визуально пульсации заметно снизились, а точность установки улучшилась и составила 1 мВ. На самом первом фото виден выходной сигнал генератора амплитудой 10 мВ (и это при отключенном аттенюаторе!).

Как пример, код такого комбинированного PWM (10 квантов грубой и 10 квантов точной части, эквивалентная разрядность около 7 бит) на AHDL:

CONSTANT PWM_TOP_F = 10; -- PWM TOP fine
CONSTANT PWM_TOP_C = 10; -- PWM TOP coarse

SUBDESIGN S2PWM
(
	Clk					: INPUT;
	PwmFine[3..0]		: INPUT;
	PwmCoarse[3..0]		: INPUT;
	PWM					: OUTPUT;
)
VARIABLE
    CntC[3..0]       	: DFFE;
    CntF[4..0]       	: DFFE;
	PWMC, PWMF			: NODE;
BEGIN
	CntC[].(clk, ena) = (Clk, vcc);
	CntF[].clk = Clk; PWMF = CntF[4];

	IF CntC[] == PWM_TOP_C - 1
		THEN CntC[] = 0; CntF[].ena = vcc;
		ELSE CntC[] = CntC[] + 1; CntF[].ena = gnd;
	END IF;

	IF(PWMF)
 		THEN CntF[] = CntF[] + (0,PwmFine[]) - PWM_TOP_F;
	         PWMC = PwmCoarse[] + 1 > CntC[];

		ELSE CntF[] = CntF[] + (0,PwmFine[]);
	         PWMC = PwmCoarse[] > CntC[];
	END IF;

	PWM = DFF(PWMC, Clk, , );

END;


При повышении PWM_TOP_F нужно учитывать, что это число в представлении счетчика CntF должно быть положительным, т.е. не достигать старшего разряда этого счетчика.

Subscribe

  • Измеритель уровня V0.1

    Сделал первую версию прошивки нового измерителя уровня для магнитофона "Электроника-004". Все еще очень-очень сырое, но уже полоски как-то…

  • Sharp GF-777

    Попал тут ко мне Sharp GF-777. Без преувеличения можно сказать, что это легенда. Обладать таким аппаратом могли лишь избранные. Стоил он когда-то…

  • JVC TD-V662

    Когда просят посмотреть кассетную деку, говорят удивительные вещи. Что не могут найти мастера, который за это бы взялся. Но ведь аналоговая…

  • Post a new comment

    Error

    default userpic
    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 21 comments

  • Измеритель уровня V0.1

    Сделал первую версию прошивки нового измерителя уровня для магнитофона "Электроника-004". Все еще очень-очень сырое, но уже полоски как-то…

  • Sharp GF-777

    Попал тут ко мне Sharp GF-777. Без преувеличения можно сказать, что это легенда. Обладать таким аппаратом могли лишь избранные. Стоил он когда-то…

  • JVC TD-V662

    Когда просят посмотреть кассетную деку, говорят удивительные вещи. Что не могут найти мастера, который за это бы взялся. Но ведь аналоговая…