# Лабораторная работа: DDS-стенд и исследование фильтров ## Электронные устройства мехатронных и робототехнических систем **Дисциплина:** Электронные устройства мехатронных и робототехнических систем, Б1.В.06 **Специальность:** 15.03.06 «Мехатроника и робототехника» **Семестр:** 5 · **Объём:** 4 часа **Стенд:** RP2040 (Raspberry Pi Pico) + макетная плата > Черновик. Требует проверки преподавателем перед выдачей студентам. --- ## 1. Зачем эта работа В мехатронном модуле сигнал датчика проходит аналоговую обработку: фильтрацию помех, интегрирование, выделение скорости (дифференцирование). Каждое такое звено описывается передаточной функцией, и от его параметров (K, τ) зависит поведение всей системы управления. Чтобы **проверить звено на железе**, нужен генератор с известной частотой и амплитудой. Готового лабораторного генератора со свипом под рукой не оказалось — поэтому в первой части работы вы **сами делаете стенд**: DDS-генератор на RP2040 и скрипт автоматического снятия АЧХ. Во второй части вы этим стендом **исследуете фильтры** — интегратор, дифференциатор и RC-фильтр — и сравниваете эксперимент с расчётом. ### Две части работы | Часть | Что делаем | Результат | |---|---|---| | **A. Стенд** | собираем и настраиваем DDS-генератор | работающий прибор: частота, амплитуда, свип | | **B. Исследование** | снимаем характеристики фильтров | АЧХ/ФЧХ, сравнение с расчётом | Часть A без части B бессмысленна: прибор делается, чтобы им измерять. Часть B без части A невозможна: нечем снимать АЧХ. --- ## 2. Теория кратко ### 2.1. Что должен делать генератор (часть A) **DDS** (Direct Digital Synthesis) — синтез сигнала из заранее посчитанного массива значений. Идея: 1. считаем один период нужной формы — например синуса — в массив из `m` точек; 2. подаём массив в PIO по кругу через DMA; 3. PIO выводит точки в порт с частотой `f_пио`; 4. частота выходного сигнала: `f_вых = f_пио / (CPC · m)`, где `CPC` — число тактов PIO на один сэмпл. Чем больше `m`, тем точнее форма и выше разрешение уровня, но тем ниже максимальная частота. ### 2.2. Точность уровня: битность ≠ разрешение - **Битность** `B` — сколько бит выводится в порт сразу (мгновенный код). - **Эффективная разрядность** — сколько уровней различает **среднее** после фильтра: `(2^B − 1)·m + 1`. При `B = 4` и `m = 256` порт даёт 4 бита, но среднее различает 3841 уровень (~11.9 бит). Так работает дельта-сигма: соседние коды чередуются во времени, а ФНЧ усредняет. ### 2.3. Интегратор на ОУ **Идеальный** (R1 на входе, C1 в ООС): ``` W(s) = −1 / (R1·C1·s) ``` На постоянном токе усиление бесконечно, поэтому **реальный** интегратор всегда содержит резистор утечки R2 параллельно C1 — это превращает его в **апериодическое звено первого порядка**: ``` W(s) = −R2 / (R1 · (1 + R2·C1·s)) = −K / (τ·s + 1) K = R2/R1, τ = R2·C1, f_c = 1/(2π·τ) ``` ### 2.4. Дифференциатор на ОУ C1 на входе, R1 в ООС: ``` W(s) = −R1·C1·s ``` На высоких частотах усиление растёт, поэтому на практике вход ограничивают резистором последовательно с C1. ### 2.5. RC-фильтр нижних частот Пассивный ФНЧ первого порядка: ``` K(f) = 1 / √(1 + (f/f_c)²), f_c = 1/(2π·R·C) наклон за f_c: −20 дБ/дек ``` ### 2.6. Многобитный вывод — это и есть ЦАП (лестница R-2R) Пока `B = 1`, генератор выдаёт один бит: либо 0, либо 1. Дробную точность даёт дельта-сигма (усреднение во времени). Но при `B > 1` вывод идёт **параллельно по нескольким пинам**, и это уже настоящий цифро-аналоговый преобразователь — только его надо собрать снаружи. Простейший вариант — **лестница R-2R**. Каждый узел цепочки соединён через `2R` со своим битом; на землю идёт только **один** `2R` — у младшего конца: ``` ВЫХОД ◄──┬────R────┬────R────┬────R────┬────2R─────┐ │ │ │ │ │ 2R 2R 2R 2R GND │ │ │ │ GP15 GP14 GP13 GP12 (MSB) (LSB) ``` (пример для 4 бит; при 8 битах колонок восемь — GP15…GP8) Ориентация важна: **выход берётся со стороны GP15**. Если взять выход с другого конца, старшинство битов перевернётся. Почему работает: каждый узел лестницы делит напряжение **ровно вдвое**, поэтому вклад пина в выход падает вдвое от старшего к младшему: | Пин | Вес в единицах младшего бита | Доля шкалы | |---|---|---| | GP15 (MSB) | 128 | 50 % | | GP14 | 64 | 25 % | | GP13 | 32 | 12,5 % | | GP12 | 16 | 6,25 % | | GP11 | 8 | 3,125 % | | GP10 | 4 | 1,5625 % | | GP9 | 2 | 0,781 % | | GP8 (LSB) | 1 | 0,391 % | То есть код `1000 0000` (единица только на GP15) даёт половину шкалы, `0100 0000` — четверть, и так далее. Отсюда `U_вых = U_пит · код / 256`. **Что важно для макета:** - **Номиналы.** Нужны резисторы R и 2R, причём в 2 раза точно. Удобно взять **R = 10 кОм, 2R = 20 кОм** (оба есть в ряду E24). Понадобится 7 резисторов R и 9 резисторов 2R для восьми бит. - **Точность.** Чтобы не терять биты, допуск резисторов должен быть меньше половины младшего бита: | Биты | Шаг шкалы | Нужен допуск лучше | |---|---|---| | 3 | 12,5 % | 6 % | | 4 | 6,25 % | 3 % | | 5 | 3,1 % | 1,5 % | | 6 | 1,56 % | 0,8 % | | 8 | 0,39 % | 0,2 % | Обычные резисторы 5 % дают надёжно **3–4 бита**, 1 % — **5–6 бит**. Для восьми бит нужны 0,1 % или калибровка каждого уровня. Это хороший повод обсудить со студентами, почему настоящие ЦАП стоят дорого. - **Выходное сопротивление** лестницы ≈ R. При R = 10 кОм это высокая нагрузка для входа АЦП и заметная погрешность при подключении нагрузки. Ставят **буфер на ОУ** (повторитель) между лестницей и АЦП. Он же убирает влияние сопротивления нагрузки на шкалу. - **Быстродействие.** Паразитная ёмкость макета (~10–20 пФ) вместе с R = 10 кОм даёт срез в сотни кГц. Для генератора до ~30 кГц этого хватает; на высоких частотах берут R = 1 кОм. - **Разрядность пинов.** Если `B < 8`, старшие биты всё равно на GP15 — то есть при `B = 4` работают GP15…GP12, и они занимают **старшие** входы лестницы. Выход при этом использует всю шкалу (выравнивание по старшему биту, см. §2.2). > **Ожидаемый результат.** При питании 3,3 В и 8 битах шаг ≈ 13 мВ. > Студент может ввести код прямо в отчёт и сравнить с расчётным > напряжением — это и есть «заглянуть внутрь ЦАП». --- ## 3. Часть A. Сборка и настройка стенда ### Задание A1 (0,5 ч). Прошивка генератора и первый запуск В папке `stub/` три варианта генератора — **выберите один**: | Файл | Платформа | Как формируется синус | |---|---|---| | `01-...ip2040.ino` | Arduino, **оба ядра** (earlephilhower и mbed) | программный DDS + ШИМ | | `01-...-circuitpython.py` | CircuitPython | программный DDS + ШИМ | | `04-dds-pio-rp2040.py` | CircuitPython | аппаратный PIO + DMA | | `04-dds-pio-rp2040.ino` | Arduino, **только earlephilhower** | аппаратный PIO + DMA | | `05-dds-audiopwm-rp2040.py` | CircuitPython | аудио-ШИМ (`audiopwmio`) + DMA; только до ~3 кГц | **Рекомендуется вариант на PIO** — точная частота, CPU свободен. Вариант 3 (`04-dds-pio-rp2040.py`) проверен на стенде: логическим анализатором снят цифровой выход, форма синуса верная. Вариант 5 — если интересно, как звук выводят штатными средствами ядра (`audiopwmio`); он ограничен сверху ~3 кГц, потому что частота сэмплирования не может быть выше 48 кГц. У `.ino`-варианта на PIO форма сигнала задаётся функцией `waveform(t)` **в коде** (перекомпилировать после правки) — в C++ нет разбора формул на лету, как в CircuitPython-версии. 1. Залейте файл на Pico (CircuitPython: переименовать в `code.py`). 2. Откройте консоль, введите `HELP` — увидите список команд. 3. Введите `I` — генератор покажет текущие настройки, включая **фактическую** частоту и потолок `f_max`. 4. Соберите внешний ФНЧ на выходе (схема — в `HELP`): ``` GP15 ──[R1 1к]──┬──[R2 1к]──┬──► выход │ │ [C1 47н] [C2 47н] │ │ GND GND ``` **Проверка:** подать `W S` (синус), `F 1000`, посмотреть осциллографом. Период должен быть ≈ 1 мс. ### Задание A2 (0,5 ч). Калибровка частоты Частота зависит от `CPC` — числа тактов PIO на сэмпл. Оно может отличаться на разных прошивках. 1. Поставьте `F 1000`, измерьте период осциллографом. 2. Если факт отличается от запроса — введите `CAL <измеренное_значение>`, например `CAL 500` при запросе 1000. Генератор подстроит `CPC` сам. 3. Повторите замер — теперь должно совпасть. 4. **Запишите** подобранное `CPC` (видно командой `I`) — оно нужно для расчёта погрешности в отчёте. > Если частота вообще не достижима, генератор скажет > `! ЗАПРОС ВЫШЕ ПОТОЛКА: факт ... Гц`. Это значит `m` слишком велико: > уменьшите `N` или `O`. ### Задание A3 (0,5 ч). Автоматическое снятие АЧХ 1. Соберите на макетной плате простой RC-фильтр (см. часть B, задание B3). 2. Подключите: выход генератора → вход фильтра; выход фильтра → вход измерения (ADC0, GP26). **Если сигнал больше 3,3 В — через делитель.** 3. Запустите хост-скрипт: ``` python 02-izmerenie-achh.py --port /dev/ttyACM0 \ --f0 10 --f1 100000 --n 25 --dwell 150 --uin 500 --out achh.csv --plot ``` 4. Получите CSV с точками «частота → амплитуда». Это ваш измерительный прибор на вторую часть работы. **Результат части A:** работающий стенд, калиброванная частота, скрипт, дающий АЧХ в CSV. --- ## 4. Часть B. Исследование фильтров Все три задания выполняются **одним и тем же стендом**, меняется только исследуемая схема. Для каждой схемы: 1. рассчитать параметры (K, τ или f_c) по формулам из п. 2; 2. собрать схему на макетной плате; 3. снять АЧХ стендом (частичный диапазон вокруг f_c, 8–12 точек); 4. наложить экспериментальные точки на расчётную кривую; 5. оценить расхождение и объяснить его. ### Задание B1 (1 ч). Интегратор на ОУ **Схема:** R1 = 10 кОм на вход, R2 = 100 кОм ‖ C1 = 0,1 мкФ в ООС. - Рассчитать: `K = R2/R1`, `τ = R2·C1`, `f_c = 1/(2π·τ)`. - Снять АЧХ в диапазоне **1 Гц … 10·f_c**. - Определить по графику плоский участок, частоту сопряжения, наклон. - **Проверить форму во времени:** подать прямоугольник, увидеть пилу. Размах пилы `U_m = U_вх·T/(2·R1·C1)`. **Контрольный вопрос:** почему `f_c` определяется `R2·C1`, а не `R1·C1`? ### Задание B2 (1 ч). Дифференциатор на ОУ **Схема:** C1 = 0,1 мкФ на вход, R1 = 10 кОм в ООС. - Рассчитать `W(s) = −R1·C1·s`, ожидаемый наклон **+20 дБ/дек**. - Снять АЧХ в диапазоне, где схема ещё устойчива. - **Проверить во времени:** подать пилу — увидеть импульсы в моменты перепада. Амплитуда `U_m = R1·C1·dU_вх/dt`. - Объяснить, почему реальный дифференциатор требует ограничения входа. **Контрольный вопрос:** чем отличается идеальный дифференциатор от реального и почему вход ограничивают резистором? ### Задание B3 (0,5 ч). Пассивный RC-фильтр **Схема:** R = 1 кОм, C = 0,1 мкФ (или по вашему варианту). - Рассчитать `f_c = 1/(2π·R·C)`, ожидаемый наклон −20 дБ/дек. - Снять АЧХ стендом в диапазоне **0,1·f_c … 100·f_c** (10–12 точек). - Наложить на расчётную кривую `K(f) = 1/√(1+(f/f_c)²)`. - Сравнить расхождение с допусками компонентов (±5 %). **Контрольный вопрос:** почему реальная АЧХ за `f_c` уходит круче −20 дБ/дек? (подсказка: паразитные параметры, вход ADC) ### Задание B4 (1 ч). Собрать ЦАП на лестнице R-2R Это самая «железная» часть: вы собираете настоящий цифро-аналоговый преобразователь и убеждаетесь, что многобитный вывод — это он и есть. **Схема** (8 бит, MSB на GP15; при `B=4` работают GP15…GP12). Каждый узел лестницы соединяется через `2R` **со своим битом**; на землю идёт **только один** `2R` — на дальнем конце (у LSB): ``` ВЫХОД ◄──┬────R────┬────R────┬────R────┬────R────┬────R────┬────R────┬────R────┬────2R─────┐ │ │ │ │ │ │ │ │ │ 2R 2R 2R 2R 2R 2R 2R 2R GND │ │ │ │ │ │ │ │ GP15 GP14 GP13 GP12 GP11 GP10 GP9 GP8 (MSB) (LSB) ``` `R = 10 кОм`, `2R = 20 кОм` (оба из ряда E24). Всего на 8 бит: **7 резисторов R** (цепочка) и **9 резисторов 2R** (8 к битам + 1 на землю). > Замечание по ориентации: выход берётся со стороны **GP15**. Если взять > выход с другого конца, биты поменяются старшинством (получится зеркало). **Порядок сборки:** 1. Собрать лестницу на макетной плате: **7 резисторов R** в цепочку, **8 резисторов 2R** — от каждого узла к соответствующему пину GP15…GP8, и **1 резистор 2R** — от крайнего узла (GP8) на землю. 2. Поставить **буфер-повторитель на ОУ** между выходом лестницы и АЦП (иначе выходное сопротивление ≈ R исказит измерения). 3. Проверить таблицу кодов. Подать на генератор прямоугольник с малой скважностью или использовать режим `D`, чтобы задавать отдельные коды, и измерить выход мультиметром: | Код | Ожидаемое U_вых (при 3,3 В) | Измерено | |---|---|---| | `0000 0001` (GP8) | 13 мВ | | | `0000 0010` (GP9) | 26 мВ | | | `0000 0100` (GP10) | 52 мВ | | | `1000 0000` (GP15) | 1,65 В | | | `1111 1111` | 3,28 В | | 4. **Оценить реальную разрядность.** Сравнить шаг с разбросом: если соседние коды неразличимы, бит потерян. Записать, сколько бит реально работает на ваших резисторах. 5. **Проверить форму сигнала.** Вернуть `B 8`, `W S`, подать синус и посмотреть выход лестницы осциллографом: сигнал будет ступенчатым — видно квантование по уровням. Это и есть работа ЦАП. **Контрольные вопросы:** - Почему в лестнице R-2R нужны ровно два номинала, а не восемь разных сопротивлений (по одному на каждый бит)? - Что произойдёт с точностью, если один из резисторов 2R окажется 20,5 кОм вместо 20 кОм? - Почему выходное сопротивление лестницы равно R и как это влияет на измерения через АЦП? ### Задание B5 (0,5 ч). Сравнение и отчёт Свести результаты четырёх схем в таблицу: | Схема | f_c расчёт | f_c опыт | Расхождение | Наклон расчёт | Наклон опыт | |---|---|---|---|---|---| | Интегратор | | | | −20 дБ/дек | | | Дифференциатор | | | | +20 дБ/дек | | | RC-фильтр | | | | −20 дБ/дек | | Отдельно — таблица кодов ЦАП (задание B4) и вывод о реальной разрядности. Сделать выводы: - какой разброс дали допуски компонентов; - где опыт расходится с расчётом сильнее всего и почему; - какую роль сыграла калибровка генератора (задание A2); - сколько бит реально дал самодельный ЦАП и почему не все восемь. --- ## 5. Оформление и оценивание Отчёт содержит: 1. Схемы: ФНЧ стенда, интегратор, дифференциатор, RC-фильтр, **лестница R-2R**. 2. Настройки генератора из `I` (включая `CPC` после калибровки). 3. Осциллограммы: синус с генератора, пила интегратора, импульсы дифференциатора, **ступенчатый синус с выхода ЦАП**. 4. Три графика АЧХ с наложенными расчётными кривыми. 5. **Таблицу кодов ЦАП** (задание B4) с расчётом и измерением. 6. Итоговую таблицу из задания B5. 7. Выводы по расхождениям и о реальной разрядности ЦАП. | Задание | Баллы | |---|---| | A1. Прошивка и первый запуск | 1,0 | | A2. Калибровка частоты | 1,0 | | A3. Автоснятие АЧХ | 2,0 | | B1. Интегратор | 2,0 | | B2. Дифференциатор | 2,0 | | B3. RC-фильтр | 1,0 | | B4. ЦАП на R-2R | 2,0 | | B5. Сводка и выводы | 1,0 | | **Итого** | **12** | Зачёт — при **7 и более** баллах (из 12). > Почему заданий стало больше. Сборка ЦАП — это отдельная практическая > работа, которая выросла из «многобитного вывода»: студент своими руками > делает преобразователь, без которого работа генератора остаётся > непонятной. Если времени мало — задание B4 можно вынести в СРС > (собрать дома и принести измерения). --- ## 6. Контрольные вопросы **По стенду (часть A):** 1. Чему равна частота выходного сигнала DDS и какие величины её задают? 2. Что такое `CPC` и почему его приходится калибровать? 3. Чем битность порта отличается от эффективной разрядности? 4. Почему для синуса нужен внешний ФНЧ после ШИМ? **По фильтрам (часть B):** 5. Чему равна передаточная функция идеального интегратора и почему без резистора утечки её нельзя реализовать? 6. Как по АЧХ отличить идеальный интегратор от апериодического звена? 7. Почему наклон АЧХ звена первого порядка равен −20 дБ/дек? 8. Как допуски R и C влияют на `f_c`? **По ЦАП (задание B4):** 9. Почему в лестнице R-2R достаточно двух номиналов резисторов? 10. Как связан код на пинах с выходным напряжением ЦАП? 11. Почему самодельный ЦАП на резисторах 5 % не даёт все 8 бит? 12. Зачем между лестницей и АЦП ставят буфер на ОУ? --- ## 7. Литература 1. Хоровиц П., Хилл У. Искусство схемотехники. 3-е изд. М.: Бином, 2014. Гл. 4 (ОУ в линейном режиме). 2. Титце У., Шенк К. Полупроводниковая схемотехника. 12-е изд. М.: ДМК Пресс, 2008. Т. 1, гл. 11 (частотные характеристики). 3. Бесекерский В.А., Попов Е.П. Теория систем автоматического регулирования. М.: Наука, 2010. Гл. 2 (типовые звенья). 4. LTSpice XVII User Guide. Analog Devices. 5. RP2040 Datasheet. Raspberry Pi Ltd (PIO, DMA, ADC). 6. LM358 / TL081 datasheet. Texas Instruments.