ai: репозиторий переименован в eumirts5-dds; задание разделено на часть A (сборка DDS-стенда) и B (исследование интегратора, дифференциатора, RC-фильтра); stub синхронизирован с РПД (добавлен PIO-генератор); README с расшифровкой названия и картой пинов

This commit is contained in:
mss
2026-10-27 20:23:07 +04:00
parent 5087d1b348
commit 2c81de5d76
6 changed files with 1685 additions and 250 deletions
+56 -4
View File
@@ -30,7 +30,7 @@
# M <0..127> — амплитуда синуса (127 = максимум)
# A — однократно измерить размах на ADC0 -> "A <мВ>"
# SWEEP <f0> <f1> <n> <dwell_ms>
# — логарифмический свип; "P <Гц> <мВ>" + импульс на GP14
# — логарифмический свип; "P <Гц> <мВ>" + импульс на GP16
# STOP — прервать свип
#
# ─── СХЕМА СИНУСА (обязательна: ШИМ даёт меандр, а не синус) ───
@@ -55,7 +55,10 @@ import pwmio
import supervisor
PIN_OUT = board.GP15 # выход сигнала (синус — через RC-фильтр)
PIN_TRIG = board.GP14 # синхроимпульс (для осциллографа)
PIN_TRIG = board.GP16 # синхроимпульс. НЕ GP14: он входит в
# диапазон PIO (GP8..GP15) в варианте
# 04-dds-pio-rp2040.py; GP16 — единая
# разводка стенда для всех трёх вариантов
PIN_ADC = board.GP26 # ADC0 = A0 — вход измерения (через делителем)
CARRIER_HZ = 125000 # несущая ШИМ — много выше f_s, биений нет
@@ -221,6 +224,52 @@ def trigger_pulse():
trig.value = False
def print_help():
"""Подробная справка по командам с форматами и примерами."""
lines = [
"# ─────────── DDS-генератор: команды ───────────",
"# Обозначения: <..> — обязательный аргумент.",
"# Команда вводится строкой, Enter — конец строки.",
"#",
"# РЕЖИМ И ЧАСТОТА",
"# W Q — режим прямоугольника (аппаратный ШИМ)",
"# W S — режим синуса (программный DDS -> ШИМ -> ФНЧ)",
"# F <Гц> — частота прямоугольника, 1..200000",
"# пример: F 1000",
"# SF <Гц> — частота СИНУСА, 1..f_s/2 (защита от алиасинга)",
"# пример: SF 25",
"#",
"# ФОРМА СИГНАЛА",
"# D <0..255> — скважность прямоугольника (128 = 50 %)",
"# пример: D 64 (25 % включено)",
"# M <0..127> — амплитуда синуса (127 = максимум)",
"# пример: M 32 (четверть шкалы)",
"#",
"# ИЗМЕРЕНИЕ И СВИП",
"# A — размах на ADC0 (GP26), мВ -> ответ 'A <мВ>'",
"# SWEEP <f0> <f1> <n> <dwell_ms>",
"# логарифмический свип f0..f1 за n точек,",
"# пауза dwell_ms на точку; печатает 'P <Гц> <мВ>',",
"# в конце 'DONE'",
"# пример: SWEEP 10 100000 25 150",
"# STOP — прервать свип",
"#",
"# СПРАВКА",
"# HELP | ? — этот текст",
"#",
"# ─── СХЕМА (синус: ШИМ даёт меандр, нужен ФНЧ) ───",
"# GP15 --[R1]--+--[R2]--+--> во вход схемы",
"# | |",
"# [C1] [C2] R1=R2=1к, C1=C2=47н",
"# | | (f_c подобрать под вашу f_s)",
"# GND GND",
"# Постоянная составляющая при 50% = Uпит/2. ADC0 — до 3.3 В (делитель!).",
"# ─────────────────────────────────────────────",
]
for ln in lines:
print(ln)
def handle(line, phase):
"""Выполнить команду. Возвращает (ok, phase). Любые ошибки — внутрь."""
line = line.strip()
@@ -229,7 +278,9 @@ def handle(line, phase):
parts = line.split(None, 1) # позиционно: sep=None, maxsplit=1 (в CP нет kwargs!)
cmd = parts[0].upper()
a = parts[1] if len(parts) > 1 else ""
if cmd == "F":
if cmd in ("HELP", "?"):
print_help()
elif cmd == "F":
cmd_f(a)
elif cmd == "SF":
cmd_sf(a)
@@ -266,7 +317,8 @@ def calibrate_fs(phase):
# ─────────────────────────── main ─────────────────────────────
def main():
global fs_eff
print("# DDS generator ready (CircuitPython). help: F/W/D/A/SWEEP/STOP")
print("# DDS generator ready (CircuitPython). Подробный хелп: HELP или ?")
print_help()
phase = 0
try:
fs_eff, phase = calibrate_fs(phase)