ai: репозиторий переименован в eumirts5-dds; задание разделено на часть A (сборка DDS-стенда) и B (исследование интегратора, дифференциатора, RC-фильтра); stub синхронизирован с РПД (добавлен PIO-генератор); README с расшифровкой названия и картой пинов
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -80,7 +80,10 @@
|
||||
|
||||
// ─────────────────────────── пины ───────────────────────────
|
||||
#define PIN_OUT 15 // выход сигнала (прямоугольник — прямо; синус — через RC)
|
||||
#define PIN_TRIG 14 // синхроимпульс (для осциллографа)
|
||||
#define PIN_TRIG 16 // синхроимпульс (для осциллографа)
|
||||
// ВАЖНО: не GP14 — он попадает в диапазон PIO в
|
||||
// варианте 04-dds-pio-rp2040.py; для единой разводки
|
||||
// стенда синхро держим на GP16 во всех вариантах
|
||||
#define PIN_ADC 26 // ADC0 = A0 — вход измерения (выход DUT через делитель!)
|
||||
|
||||
// ─────────────────────── параметры DDS ──────────────────────
|
||||
@@ -269,12 +272,60 @@ static void runSweep(float f0, float f1, int n, uint32_t dwell_ms) {
|
||||
setFrequency((uint32_t)f0); // вернуться к началу
|
||||
}
|
||||
|
||||
// ─────────────────────── подробный хелп ──────────────────────
|
||||
static void printHelp() {
|
||||
Serial.println(F("# ─────────── DDS-генератор: команды ───────────"));
|
||||
Serial.println(F("# Обозначения: <..> — обязательный аргумент."));
|
||||
Serial.println(F("# Все команды вводятся строкой, Enter — конец строки."));
|
||||
Serial.println(F("#"));
|
||||
Serial.println(F("# РЕЖИМ И ЧАСТОТА"));
|
||||
Serial.println(F("# W Q — режим прямоугольника (аппаратный ШИМ)"));
|
||||
Serial.println(F("# W S — режим синуса (DDS -> ШИМ -> внешний ФНЧ)"));
|
||||
Serial.println(F("# F <Гц> — частота выхода, 1..500000"));
|
||||
Serial.println(F("# в режиме Q — частота прямоугольника;"));
|
||||
Serial.println(F("# в режиме S — то же (для совместимости)"));
|
||||
Serial.println(F("# пример: F 1000"));
|
||||
Serial.println(F("# SF <Гц> — частота синуса с защитой от алиасинга"));
|
||||
Serial.println(F("# ограничена SAMPLE_HZ/2 (см. шапку файла)"));
|
||||
Serial.println(F("# пример: SF 25"));
|
||||
Serial.println(F("#"));
|
||||
Serial.println(F("# ФОРМА СИГНАЛА"));
|
||||
Serial.println(F("# D <0..255> — скважность прямоугольника (128 = 50 %)"));
|
||||
Serial.println(F("# пример: D 64 (25 % включено)"));
|
||||
Serial.println(F("# M <0..127> — амплитуда синуса (127 = максимум)"));
|
||||
Serial.println(F("# пример: M 32 (четверть шкалы)"));
|
||||
Serial.println(F("#"));
|
||||
Serial.println(F("# ИЗМЕРЕНИЕ И СВИП"));
|
||||
Serial.println(F("# A — размах на ADC0 (GP26), мВ -> ответ 'A <мВ>'"));
|
||||
Serial.println(F("# SWEEP <f0> <f1> <n> <dwell_ms>"));
|
||||
Serial.println(F("# логарифмический свип от f0 до f1 за n точек,"));
|
||||
Serial.println(F("# пауза dwell_ms на точку; на точку печатает"));
|
||||
Serial.println(F("# 'P <Гц> <мВ>', в конце 'DONE'"));
|
||||
Serial.println(F("# пример: SWEEP 10 100000 25 150"));
|
||||
Serial.println(F("# STOP — прервать свип"));
|
||||
Serial.println(F("#"));
|
||||
Serial.println(F("# СПРАВКА"));
|
||||
Serial.println(F("# HELP | ? — этот текст"));
|
||||
Serial.println(F("#"));
|
||||
Serial.println(F("# ─── СХЕМА (синус: ШИМ даёт меандр, нужен ФНЧ) ───"));
|
||||
Serial.println(F("# GP15 --[R1]--+--[R2]--+--> во вход схемы"));
|
||||
Serial.println(F("# | |"));
|
||||
Serial.println(F("# [C1] [C2] R1=R2=1к, C1=C2=47н"));
|
||||
Serial.println(F("# | | (f_c ~ 3.4 кГц)"));
|
||||
Serial.println(F("# GND GND"));
|
||||
Serial.println(F("# Постоянная составляющая при 50% = Uпит/2: нужен разделительный"));
|
||||
Serial.println(F("# конденсатор, если смещение мешает. ADC0 — до 3.3 В (делитель!)."));
|
||||
Serial.println(F("# ─────────────────────────────────────────────"));
|
||||
}
|
||||
|
||||
// ─────────────────────── разбор команд ──────────────────────
|
||||
static void handleLine(char *line) {
|
||||
char *cmd = strtok(line, " \t");
|
||||
if (!cmd) return;
|
||||
|
||||
if (!strcasecmp(cmd, "F")) {
|
||||
if (!strcasecmp(cmd, "HELP") || !strcmp(cmd, "?")) {
|
||||
printHelp();
|
||||
} else if (!strcasecmp(cmd, "F")) {
|
||||
char *a = strtok(nullptr, " \t");
|
||||
if (a) setFrequency((uint32_t)strtoul(a, nullptr, 10));
|
||||
Serial.print("OK F "); Serial.println(g_freq);
|
||||
@@ -323,7 +374,8 @@ void setup() {
|
||||
startSampleClock();
|
||||
setMode(MODE_SQUARE);
|
||||
setFrequency(1000);
|
||||
Serial.println("# DDS generator ready (RP2040). help: F/W/D/A/SWEEP/STOP");
|
||||
Serial.println("# DDS generator ready (RP2040). Подробный хелп: HELP или ?");
|
||||
printHelp();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user