Karat3.ru

Клуб каратистов
Текущее время: 14 май 2026, 01:25

Часовой пояс: UTC




Начать новую тему  Ответить на тему  [ 44 сообщения ]  На страницу Пред. 1 2 3 4 5 След.
Автор Сообщение
 Заголовок сообщения: Re: RP2040
СообщениеДобавлено: 02 апр 2026, 04:05 
Не в сети

Зарегистрирован: 25 ноя 2024, 13:52
Сообщения: 97
Запрограммируем какую-нибудь стейт-машину :)
Пусть это будет генератор меандра.

Программируется стейт-машина в ассемблере.
Пишем:
Код:
pio_code = """	- начало объявления многострочной строки (triple-quoted string), в которой записывается исходный код на языке ассемблера PIO
.program square_wave - директива компилятора. Присваивает имя этому блоку кода. Не является инструкцией PIO и памяти PIO не занимает.
.wrap_target 	-  Метка. Помечает адрес в памяти, с которого стейт-машина должна начинать новый цикл после завершения программы.
    set pins, 1 	- Исполняемая инструкция (16 бит) - 1 ячейка памяти PIO.
    			Стейт-машина подает сигнал логической единицы (3.3В) на те GPIO, которые в конфигурации были назначены как set_pins.
			Эта операция выполняется мгновенно в начале такта. Инструкция удерживает это состояние ровно 1 такт частоты PIO.
    set pins, 0	- то же самое, подаёт сигнал логического нуля.
.wrap		- Метка. Указывает на конец зацикленного участка. 
		Как только стейт-машина выполнит предыдущую команду (set pins, 0), она мгновенно (за 0 тактов) перейдет 
		обратно к адресу, помеченному как .wrap_target.
"""		- закрывающий маркер многострочной строки.
Ассемблируем:
Код:
assembled = adafruit_pioasm.assemble(pio_code)
Чтобы библиотека adafruit_pioasm превратила этот текст в массив 16-битных чисел (машинный код PIO), надо вначале прописать импорт библиотеки
Код:
import adafruit_pioasm
инициализируем стейт-машину
Код:
sm = rp2pio.StateMachine(	#
    assembled,			#
    frequency=125_000_000,	# тактовая частота стейт-машины (не выше системной шины)
    first_set_pin=board.GP15,	# настройка коммутатора I/O Mapping - подключаем пин GP15
    set_pin_count=1		# команда set должна управлять только одним пином, начиная с выбранного (GP15)
)
Общий код
Код:
# код CircuitPython
# генератор меандра 62,5 MГц на пине 15
# с использованием PIO

import board
import rp2pio
import adafruit_pioasm

# ассемблерный код
pio_code = """
.program square_wave
.wrap_target
    set pins, 1
    set pins, 0
.wrap
"""

# ассемблирование
assembled = adafruit_pioasm.assemble(pio_code)

# Настройка стейт-машины: 62 500 000 Гц * 2 такта = 125 000 000 Гц
sm = rp2pio.StateMachine(
    assembled,
    frequency=125_000_000,
    first_set_pin=board.GP15,
    set_pin_count=1
)

print("Генератор 62,5 МГц запущен на GP15")

while True:
    pass
.
Вложение:
code09.rar [520 байт]
2 скачивания
.
Теперь пин GP15 генерирует частоту 62,5 МГц автономно, т.е. независимо от работы основных ядер.
Даже при зависании основного процесса генерация сохраняется.
.
Вложение:
04 частота.png
04 частота.png [ 1.77 МБ | 176 просмотров ]
.
щуп и осцилл не позволяют корректно отобразить форму сигнала, так что вот
Вложение:
05 форма.png
05 форма.png [ 326.72 КБ | 176 просмотров ]


Вернуться к началу
 Заголовок сообщения: Re: RP2040
СообщениеДобавлено: 02 апр 2026, 04:39 
Не в сети

Зарегистрирован: 25 ноя 2024, 13:52
Сообщения: 97
А если мы хотим сгенерировать частоту 1 МГц?
Нужно вводить большие задержки или указывать другую тактовую частоту.

В каких пределах можно задать тактовую частоту?
Внутри каждой стейт-машины стоит 24-битный делитель, который разделён на две части:
16 бит — целая часть (от 1 до 65535).
8 бит — дробная часть (шагами по 1/256).
На самом деле физически невозможно разделить один такт системной шины на «четвертинки». Делитель хитрит: он использует джиттер (дрожание фазы).
Если вы задали делитель 1.5, PIO будет чередовать такты: один такт он «спит» 1 системный цикл, а следующий — 2 системных цикла. В среднем за большой промежуток времени получится ровно 1.5, и частота будет соответствовать заданной.

Например, для качественного звука нужна частота дискретизации 44100 Гц.
С учетом всех тактов PIO, вам может понадобиться частота шины PIO, например, 11.2896 МГц.
125 МГц / 11,2896 МГц = 11,0721372
Благодаря 8-битной дробной части, можно установить ближайшее значение (например, 11 + 18/256 = 11,0703125)
125 МГц / 11,0703125 = 11,2915 МГц
и ошибка в частоте звука будет ничтожной (11,2915*100/11,2896 = 100,017%).

Поскольку дробный делитель работает через чередование длительности тактов, на высоких частотах это может создать «некрасивый» сигнал - импульсы меандра будут иметь разную длину (один чуть короче, другой чуть длиннее).

Максимальный коэффициент деления 16-битного делителя - 65536.
При системной частоте 125 МГц минимальная частота PIO составит: 125000000 / 65536 = 1907,35 Гц.

Задавая тактовую частоту PIO, число должно быть целым: В Python пишите 125_000_000 или 125000000.

Вернёмся к генерации частоты в 1 МГц.
Код:
# код CircuitPython
# генератор меандра 1 MГц на пине 15
# с использованием PIO

import board
import rp2pio
import adafruit_pioasm

# 1 такт на включение + 31 такт задержки
# 1 такт на выключение + 31 такт задержки
# Итого 64 такта на полный цикл
pio_code = """
.program square_wave
.wrap_target
    set pins, 1 [31]
    set pins, 0 [31]
.wrap
"""

assembled = adafruit_pioasm.assemble(pio_code)

# Настройка: 1000000 Гц * 64 такта = 64 000 000 Гц
sm = rp2pio.StateMachine(
    assembled,
    frequency=64_000_000,
    first_set_pin=board.GP15,
    set_pin_count=1
)

print("Генератор 1 МГц запущен на GP15")

while True:
    pass
.
Вложение:
code08.rar [545 байт]
4 скачивания
.
Разберём особенности кода.
У нас одна команда стейт-машины занимает 16 бит, хотя ассемблерных команд для неё всего девять: JMP, WAIT, IN, OUT, PUSH, PULL, MOV, IRQ и SET.
Остальные биты тоже значащие:
3 бита: Код самой операции,
5 бит: Поле Delay/Side-set,
8 бит: Специфические данные операции (куда записать, что сравнить).

Мы можем использовать поле Delay/Side-set для задержки или для управления дополнительными пинами.
Всего 5 бит позволяют задать число от 0 до 31.
Существует три основных сценария настройки:
- Только Delay (5:0): Все 5 бит используются для задержки. Вы можете ждать от 0 до 31 такта после выполнения команды.
- Только Side-set (0:5): Все 5 бит управляют дополнительными пинами (до 5 штук). Задержки нет (0 тактов).
- Смешанный режим (например, 3:2): 3 бита под задержку (0–7 тактов) и 2 бита под управление двумя Side-set пинами.

У нас используется только задержка - к каждому такту установки/сброса добавляем задержки на 31 такт.
Выбираем тактовую частоту PIO 64 МГц и задержку в 64 такта (1+31+1+31)
64 МГц / 64 = 1 МГц.
Вложение:
06 частота.png
06 частота.png [ 1.75 МБ | 172 просмотра ]
.
Вложение:
07 форма.png
07 форма.png [ 338.8 КБ | 172 просмотра ]


Вернуться к началу
 Заголовок сообщения: Re: RP2040
СообщениеДобавлено: 02 апр 2026, 05:07 
Не в сети

Зарегистрирован: 25 ноя 2024, 13:52
Сообщения: 97
Это было несложно :)

А теперь кое-что посложнее - создадим на стейт-машинах два квадратурных сигнала (т.е. сдвинутых относительно друг друга на 90 градусов по фазе).
Решение этой задачи позволит напрямую управлять коммутатором детектора Тейло и получать I-Q сигналы.
Код:
# квадратурный генератор менадра
# на PIO
# частота 3650 кГц

import board
import rp2pio
import adafruit_pioasm

# Программа: сдвиг 90 градусов (8 тактов на каждое состояние)
# Состояния (GP15, GP14):
# 1. 01 (1) -> 2. 11 (3) -> 3. 10 (2) -> 4. 00 (0)
pio_code = """
.program quadrature
.wrap_target
    set pins, 1 [7] ; GP14=1, GP15=0 (1 такт + 7 задержка = 8)
    set pins, 3 [7] ; GP14=1, GP15=1 (1 такт + 7 задержка = 8)
    set pins, 2 [7] ; GP14=0, GP15=1 (1 такт + 7 задержка = 8)
    set pins, 0 [7] ; GP14=0, GP15=0 (1 такт + 7 задержка = 8)
.wrap
"""

assembled = adafruit_pioasm.assemble(pio_code)

# Расчет: 3 650 000 Гц * 32 такта = 116 800 000 Гц
sm = rp2pio.StateMachine(
    assembled,
    frequency=116_800_000,
    first_set_pin=board.GP14,
    set_pin_count=2           # Управляем GP14 и GP15 одновременно
)

print("Сигнал 3.65 МГц: GP14 (0°) и GP15 (90°) запущен")

while True:
    pass
.
Вложение:
code10.rar [667 байт]
3 скачивания
.
Разбираем код.
Так как у нас квадратурный сдвиг фаз, то расписываем период с разделением на квадранты (на 4 части):
01
11
10
00

set pins, 1 [7] - первым тактом устанавливаем сразу оба пина в число 1, т.е. 01 -> GP14,GP15 (GP15=0, GP14=1), плюс задержка на 7 тактов
set pins, 3 [7] - устанавливаем пины в число 3, т.е. 11 -> GP14,GP15 (GP15=1, GP14=1), плюс задержка на 7 тактов
set pins, 2 [7] - устанавливаем пины в число 2, т.е. 10 -> GP14,GP15 (GP15=1, GP14=0), плюс задержка на 7 тактов
set pins, 0 [7] - устанавливаем пины в число 0, т.е. 00 -> GP14,GP15 (GP15=0, GP14=0), плюс задержка на 7 тактов

итого 1+7+1+7+1+7+1+7 = 32 такта на период.
нам нужна тактовая частота: 3 650 000 Гц * 32 такта = 116 800 000 Гц.

в set_pin_count=2 не забываем указать, что управляются два пина (начиная с GP14)
.
Получаем квадратурный сигнал на 3650 кГц:
Вложение:
08 квадратура 3,65М.png
08 квадратура 3,65М.png [ 371.34 КБ | 164 просмотра ]


Вернуться к началу
 Заголовок сообщения: Re: RP2040
СообщениеДобавлено: 02 апр 2026, 07:55 
Не в сети

Зарегистрирован: 25 ноя 2024, 13:52
Сообщения: 97
Теперь про АЦП.
Как мы уже знаем, АЦП подключен как устройство через более низкий уровень - APB Splitter - разделитель шины APB (Advanced Peripheral Bus).
АЦП классический 12-битный преобразователь последовательного приближения (SAR) имеет разрешение 12 бит (значения от 0 до 4095), но в среде CircuitPython значения масштабируются до 16 бит (0–65535) для единообразия.
Максимальная частота дискретизации составляет 500 kS/s (500 тысяч замеров в секунду). Один замер занимает ровно 2 мкс (96 циклов тактовой частоты АЦП 48 МГц).
5 входных каналов, переключаемых мультиплексором:
- 4 внешних: GPIO 26, 27, 28 и 29.
- 1 внутренний: встроенный датчик температуры чипа.
.
Вложение:
09 АЦП_01.png
09 АЦП_01.png [ 53.32 КБ | 158 просмотров ]
Режимы работы
Блок АЦП может работать в двух режимах управления:
Single-shot (Одиночный): Процессор говорит: «Измерь сейчас», АЦП делает замер и ждет.
Free-running (Непрерывный): АЦП сам запускает новое измерение сразу после предыдущего или по сигналу таймера (Pacer). Именно в этом режиме он выдает паспортные 500 kSPS (500 тысяч замеров в секунду).

Внутри АЦП есть «почтовый ящик» — FIFO (очередь) на 4 результата.
Когда АЦП заканчивает замер, он кладет 12-битное число в FIFO.
Если вы используете DMA, специальный контроллер видит, что в FIFO что-то появилось, и мгновенно забирает данные в оперативную память (SRAM) через Bus Fabric.
Это происходит без участия ядер процессора, что позволяет собирать данные на частоте 500 кГц «в фоне».

Особенности АЦП RP2040:
- Эффективное число бит (ENOB): Из-за внутренних шумов и нелинейности реальная точность АЦП ниже теоретических 12 бит. Измеренное значение ENOB составляет около 8.7...9 бит (в зависимости от шумов питания).
- Ошибка DNL (дифференциальная нелинейность): Это аппаратный изъян (Errata RP2040-E11), проявляющийся в виде резких скачков погрешности при определенных значениях (512, 1536, 2560, 3584). Это вызвано дефектом в емкостной матрице внутри чипа.
- Эффект «Kickback»: В момент начала замера АЦП подключает внутренний конденсатор (~1 пФ) к входному пину, что может вызвать кратковременный скачок напряжения (помеху) в измеряемой цепи.

Рекомендации по использованию:
- Внешний ИОН: Для профессиональных задач рекомендуется подавать на ADC_VREF напряжение от отдельного стабильного источника опорного напряжения, а не использовать общую шину 3.3В.
- Оверсемплинг: Аппаратное или программное усреднение нескольких замеров помогает частично нивелировать шум и ошибки DNL, увеличивая реальное разрешение.
- Чтобы внутренний конденсатор АЦП успевал заряжаться за 2 мкс, источник сигнала должен иметь низкое выходное сопротивление. Если импеданс выше 100 кОм, точность замеров падает.


Вернуться к началу
 Заголовок сообщения: Re: RP2040
СообщениеДобавлено: 03 апр 2026, 05:44 
Не в сети

Зарегистрирован: 25 ноя 2024, 13:52
Сообщения: 97
Ну вот, так всё хорошо начиналось, и на тебе!
Спалил я эту плату...
Ночью уже сидел, правил код. Подпаялся коротенькими проводками, повесил на них звуковуху, записываю, анализирую, правлю. И тут земляной проводок звуковухи отрыватся и чиркает по питательным контактам...
То ли +3,3 на +5,0 коротнуло, то ли +5,0 на землю - в общем, сдох флэш-диск: после бут-ресета RPI-RP2 виден, но при попытке записать на него любой UF2-файл плата или перегружается и теряет диск, или просто ничего не происходит.
Пробовал на другом компе - та же фигня.
МикроПитон на Thonny также качает свою среду в uf2, но не может вписать на флэш.
Вложение:
02.jpg
02.jpg [ 170.96 КБ | 147 просмотров ]
.
Пытался чистить флэш - flash_nuke.uf2
Скачал для проверки прошивку мигания светодиодом blink.uf2 - она тоже не вписывается во флэш.
Короче, надо менять плату :(
256 рублей коту под хвост )))
.
Вложение:
flash_nuke.rar [8.38 КБ]
3 скачивания
Вложение:
blink.rar [281 байт]
2 скачивания
.
PS
Закажу парочку плат с флэшем на 4 Мб
должно хватить, а они дешевле :)

https://aliexpress.ru/item/1005004266011707.html


Вернуться к началу
 Заголовок сообщения: Re: RP2040
СообщениеДобавлено: 03 апр 2026, 06:14 
Не в сети

Зарегистрирован: 25 ноя 2024, 13:52
Сообщения: 97
Перед тем как сжечь плату, удалось добиться кое-каких результатов при работе со стейт-машинами.

Стояла задача получить генератор RTTY сигнала.
Я задействовал две стейт-машины: МОДЕМ и МОДУЛЯТОР.

Код модема:
Код:
rtty_modem_pio = """
.program rtty_modem
    pull block          ; Ждем байт один раз
    mov osr, osr        ; Зацикливаем его
loop_forever:
    mov x, osr          ; Копируем в рабочий регистр
    set y, 7            ; Счетчик на 8 бит
bit_loop:
    out pins, 1 [20]    ; Выводим бит и ждем ~22мс (при 2000Гц)
    nop [21]
    jmp y-- bit_loop
    mov osr, x          ; Восстанавливаем данные
    jmp loop_forever
"""
.program rtty_modem - название программы. Мы потом будет использовать его для обращения к этому блоку кода.

Получаем код Бодо символа + старт и стоп биты
pull block - ждём, пока основное ядро пришлет данные в FIFO-буфер.
Как только данные приходят, они перемещаются в OSR (Output Shift Register — выходной регистр сдвига).
mov osr, osr - сбрасываем счётчики положения сдвига и направления сдвига регистра OSR
Также отключается автоподгрузка данных из FIFO-буфера.

loop_forever: - метка цикла передачи (главного цикла модема)
mov x, osr - сохраняем символ OSR в X
set y, 7 - устанавливаем счётчик (регистр Y) = 7

bit_loop: - метка сдвигового цикла
out pins, 1 [20] - извлекаем один бит из регистра OSR на пин платы, оставшиеся биты сдвигаются, потом ждём 20 тактов
направление сдвига зададим при инициализации машины
nop [21] - ждём 21 такт
jmp y-- bit_loop - если Y<>0, то Y=Y-1 и перейти к bit_loop.

mov osr, x - восстанавливаем символ OSR из X
jmp loop_forever - возвращаемся к передаче

Таким образом, в этой программе поступивший один раз символ раскладывается на биты, выводится на пин и бесконечно крутится в цикле.
Например, чтобы передать символ А нам нужно отправить в буфер 0xC6 = 11000110.
Передаём мы начиная с младшего бита: 0 - 1 - 1 - 0 - 0 - 0 - 1 - 1
Получился первый бит - стартовый = 0,
потом код Бодо для символа А = 11000,
и два стоп-бита = 11.

Посчитаем задержки передачи одного бита:
1+20+1+21+1 = 44 такта.
Базовая частота 2000 Гц = 1/2000 = 0,0005 = 0,5 мс/такт.
Длительность передачи одного бита 44*0,5 = 22 мс.
Попали в стандартные 22 мс.


Вернуться к началу
 Заголовок сообщения: Re: RP2040
СообщениеДобавлено: 03 апр 2026, 06:51 
Не в сети

Зарегистрирован: 25 ноя 2024, 13:52
Сообщения: 97
Теперь программа модулятора
Код:
fsk_modulator_pio = """
.program fsk_modulator
.wrap_target
    jmp pin mark_tone    ; Если на GP14 единица, идем на Mark

space_tone:              ; 1000 Гц (Space)
    set pins, 1 [28]
    nop         [28]
    set pins, 0 [28]
    nop         [27]
    jmp pin mark_tone
    jmp space_tone

mark_tone:               ; 1170 Гц (Mark)
    set pins, 1 [23]
    nop         [24]
    set pins, 0 [24]
    nop         [24]
.wrap
"""
Программа постоянно проверяет проверяет состояние одного входного пина:
- Если на входе 0, она генерирует «низкий» тон (Space).
- Если на входе 1, она генерирует «высокий» тон (Mark).

.program fsk_modulator - название программы.

.wrap_target - метка начала автоматического цикла
jmp pin mark_tone - проверка входного пина:
Если на пине «1», программа прыгает в секцию mark_tone.
Если на пине «0», выполнение продолжается строкой ниже (в space_tone).

Генерация тона "Space"
space_tone:
set pins, 1 [28] - установить состояние пина = 1. Ждать 28 тактов.
nop [28] - пропустить 1+28 тактов
set pins, 0 [28] - установить состояние пина = 0. Ждать 28 тактов.
nop [27] - пропустить 1+27 тактов

после каждого периода проверяем пин:
jmp pin mark_tone - если pin=1, то перейти к mark_tone.
jmp space_tone - иначе (pin=0), то перейти к space_tone.

Генерация тона "Mark"
mark_tone:
set pins, 1 [23] - установить состояние пина = 1. Ждать 23 такта.
nop [24] - пропустить 1+24 такта
set pins, 0 [24] - установить состояние пина = 0. Ждать 24 такта.
nop [24] - пропустить 1+24 такта

Как только PIO выполняет последнюю инструкцию перед .wrap (в вашем случае это nop [24] в блоке mark_tone), он мгновенно и аппаратно перепрыгивает обратно на .wrap_target.
Команды (и такта) на это не тратится :)

Задержки в скобках для каждой команды не могут превышать 31, поэтому после команды установки пина добавлена команда nop со своей задержкой.
Посчитаем такты.
для марка 1+23+1+24+1+24+1+24+1(переход по условию) = 100,
для спейса 1+28+1+28+1+28+1+27+1(по условию не подошёл)+1(безусловный переход) = 117.

Базовая частота 117000 Гц = 1/117000 = 8,5470085e-6 = 8,547 мкс/такт.
Частота марк 1/(8,5470085e-6*100) = 1170 Гц
Частота спейс 1/(8,5470085e-6*117) = 1000 Гц
Идеально.

Полный текст кода:
Вложение:
code26.rar [1.43 КБ]
5 скачиваний
.
Поскольку машины не имеют между собой программной связи (по крайней мере из CircuitPython), то выход первой машины (модема) соединяю со входом второй (модулятора) при помощи резистора GP13 - 470 Ом - GP14 :)


Вернуться к началу
 Заголовок сообщения: Re: RP2040
СообщениеДобавлено: 03 апр 2026, 16:01 
Не в сети

Зарегистрирован: 25 ноя 2024, 13:52
Сообщения: 97
Выкусил сгоревшую плату и впаял новую через кроватку.
Это полностью решило проблему :)
.
Вложение:
IMG_20260403_1943130.jpg
IMG_20260403_1943130.jpg [ 966.33 КБ | 112 просмотров ]
Добавляю итог сегодняшних бдений.

Костяк кода RTTY маяка.
Передаются длинные фразы, поддержка кириллицы.

Особенностей код не имеет, все ключевые моменты разобраны выше.
Тут только добавлены словари, по которым разбираем фразу.
Полученные коды бодо "оборачиваем" в стартовый и стоповые биты, и при необходимости применяем переключение регистров.
В начале и в конце фразы добавляем тон марк длительностью 0,5 сек - чтобы обозначить начало и конец передачи.
.
Вложение:
code36.rar [2.36 КБ]
3 скачивания
.
Полученный сигнал записал в mp3
Вложение:
SoundRTTY2.mp3 [1.13 МБ]
3 скачивания


Вернуться к началу
 Заголовок сообщения: Re: RP2040
СообщениеДобавлено: 04 апр 2026, 11:09 
Не в сети

Зарегистрирован: 25 ноя 2024, 13:52
Сообщения: 97
Пора переходить к приёму сигналов.
Оцифровывать входящий сигнал будем встроенным АЦП (12-бит, 500 Кс/с)
У нас тоны приняты 1000/1170 Гц, поэтому частота дискретизации - 8 КГц. Подробнее об этом в соседней ветке
На стандартной скорости 45,45 бод, длительность одного бита равна 1/45,45 = 0,022 с = 22 мс.
Для тона 1000 Гц (спейс) период колебаний равен 1/1000 = 1 мс,
Для тона 1170 Гц (марк) период колебаний равен 1/1170 = 0,855 мс.
Значит, в одном бите будет 22/0,855 = 25 полных периодов для марка (или 22 для спейса). Немного.

При частоте тона 1000 Гц на один период колебаний мы получим 8000/1000 = 8 отсчётов. Достаточно.

Один бит содержит 8000*0,022сек = 176 отсчётов.
Чтобы корректно считать сигнал, нужно синхронизироваться с началом передачи бита.
Будем читать сигнал кусками по 64 отсчёта, это кратно степени двойки и примерно равно 1/3 от длительности бита.
Частотное разрешение (расстояние между соседними точками в спектре) при это будет равно 8000/64 = 125 Гц. У нас сигналы имеют разнос 170 Гц. Достаточно.

АЦП у нас достаточно скоростной, и в библиотеке ulab есть скоростные функции обработки, поэтому для снижения шума преобразования применим оверсэмплинг - вместо одного отсчёта будем читать четыре, и осреднять.
8К*4 = 32 КГц - это будет реальная частота работы АЦП.

Энергию сигнала в полосе считаем по алгоритму Гёрцеля. О нём я много писал в соседней ветке.
Ширина полосы алгоритма для каждого сигнала - 100Гц.

Запускаем воспроизведение на компе и снимаем сигнал с аудиокарты.
Оранжевый - работа порогового детектора.
.
Вложение:
01.jpg
01.jpg [ 227.31 КБ | 99 просмотров ]
.
Вложение:
code50.rar [1.89 КБ]
6 скачиваний


Вернуться к началу
 Заголовок сообщения: Re: RP2040
СообщениеДобавлено: 05 апр 2026, 07:42 
Не в сети

Зарегистрирован: 25 ноя 2024, 13:52
Сообщения: 97
Теперь надо знать точно, что за сигнал у нас генерируется.
Для простоты назначим генерацию только латинских букв ABCDEF.
.
Вложение:
code_gen.rar [2.37 КБ]
3 скачивания
.
Захватим сигнал с ноги GP13 - это уровни RTTY
Я пользуюсь устройством, которое можно найти по запросу "logic analyzer 24mhz 8ch"
Например этот:
https://aliexpress.ru/item/1005001621950241.html
ПО: Logic 2 v2.4.14, PulseView v 0.4.2.
У меня стоит ещё старый Logic 1.1.16

Итак, захватываем
.
Вложение:
03.jpg
03.jpg [ 182.62 КБ | 91 просмотр ]
.
первый "ноль" длиной 132,032 мс.
Проверим
3,3 дел х 40мс = 132 мс, совпадает.
.
Вложение:
02.jpg
02.jpg [ 138.3 КБ | 91 просмотр ]
.
Выписал все периоды
Вложение:
03.txt [403 байт]
2 скачивания
.
Теперь смотрим, что у нас на выводе GP15.
Вложение:
05.jpg
05.jpg [ 151.63 КБ | 89 просмотров ]
Тон есть, длительности следующие:
.
Вложение:
04.jpg
04.jpg [ 65.54 КБ | 89 просмотров ]
.
С достаточной точностью совпадают.

Декодируем вручную :)
при помощи таблицы МТК-2

132/22 = 6,0
46,5/22 = 2,1
Значит первый кортеж 0-00000-11 то есть [РУС]

Далее
22/22 = 1
156/22 = 7,1
второй кортеж 0-11111-11 то есть [ЛАТ]

22/22 = 1
44/22 = 2
66/22 = 3
46,5/22 = 2,1
третий кортеж 0-11000-11 то есть - A

22/22 = 1
22/22 = 1
44/22 = 2
90,5/22 = 4,1
четвёртый кортеж 0-10011-11 то есть - B

44/22 = 2
66/22 = 3
22/22 = 1
46,5/22 = 2,1
пятый кортеж 0-01110-11 то есть - C

Далее нет смысла раскодировать. Последовательности понятны.
Записываем в виде mp3-файла
Вложение:
Sound001.mp3 [160.53 КБ]
2 скачивания


Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 44 сообщения ]  На страницу Пред. 1 2 3 4 5 След.

Часовой пояс: UTC


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB