Skip to content

Приём FM диапазона на Si4735

DushkaF edited this page May 2, 2020 · 6 revisions

Работа с Si4735

Разберёмся с управлением приёмником. Все команды, и их описания приложены в файле AN332 Programming Guide. Там таблица команд разделена на 2 части - для приёмника FM и приёмников на другие поддиапазоны на амплитудной модуляции. Для первого запуска рекомендую поймать FM, так как не нужно знать никакой теории по антеннам - сигнал зачастую ловится на любой кусок провода, прикреплённый к антенному входу (у меня ловит даже без него). Таблица для FM части находится начиная со страницы 55.

Стандартный адрес приёмника на шине I2C будет 0x11. Его можно поменять на другой - на 0x63 при подаче на пин SENB логической единицы (подтянуть к 3.3В)
Хочу заметить, что всегда можно запросить прочитать байт статуса, он будет первым из прочитанных.
Вот таблица, показывающая за что отвечают биты в этом байте:




Нас будут чаще всего интересовать биты 7, 6, 0:

  • Бит 7 (Clear-To-Send) нам даёт понять, можно ли передавать следующую команду или стоит подождать
  • Бит 6 (Error) - если в нём пришла единица, то скорее всего была неправильно отправлена команда или не соблюдены условия её выполнения (например приёмник не был включён с помощью POWER_UP)
  • Бит 0 (Seek/Tune Complete Interrupt) возвращает единицу, если мы удачно настроились на частоту и приёмник готов воспроизводить радиостанцию

Рассмотрим порядок команд, которые нам нужно отправить на приёмник

  1. Перед запуском приёмника необходимо притянуть Reset (RSTB) к земле на 100 µs, что указано на странице 7 основного datasheet`а. Только после этого приёмник будет готов устанавливать соединение по шине I2C.

  2. Прежде всего нужно включить приёмник, а именно FM часть. Это делается отправкой команды POWER_UP (0x01), в первом аргументе которой, в младших 4х (Function) битах установлен 0. Также необходимо подключить тактирование от внешнего кварца, это делается установкой единицы в бит 4 (XOSCEN) того же первого аргумента. В примечании к этому пункту написано, что при активации тактирования от кварца необходимо отправит вторым аргументом (OPMODE) значение 00000101, что переключает вывод звука на аналоговый выход ROUT и LOUT. В ответ на эту команду приёмник пошлёт ответ 0x80 (10000000), что соответствует успешному прохождению команды.

  3. Дальше можно попробовать считать версию и другую информацию с приёмника. Для этого есть команда GET_REV (0x10). Она не принимает аргументов, поэтому можно сразу прочитать с неё 15 байт, включая первый статусный. Возвращаемые значения можно посмотреть в таблице на страницах 66-67. Если у Вас это получилось получить это, то мои поздравления!

  4. Теперь уже придём к приёму радиосигнала. Это можно сделать несколькими способами: с помощью установки конкретной частоты (FM_TUNE_FREQ) и с помощью автоматического поиска (FM_SEEK_START). Попробуем второй вариант, так как я почти уверен, что вы не помните конкретных частот радиостанций :). Приступим. Для проверки по событию (например нажатие кнопки) будем вызывать команду FM_SEEK_START (0x21) с аргументом, в котором установим параметр WRAP (2й бит) на 1, что нам даёт просматривать диапазон циклически вниз (тк бит SEEKUP в 0, если 1, то вверх). При вызове этой функции повторно станция переключается на станцию с частотой ниже/выше.
    На этом моменте можно подключить усилитель к аудиовыходу и услышать радиостанцию. Если это так, то поздравляю, можно двигаться дальше.
    По поводу возвращаемого байта STATUS. Он будет постоянно возвращаться 0x80 (10000000) (если, конечно, до этого сделали всё правильно, иначе будет ошибка - 0xC0). Но как же так, я же говорил про 0-й бит статуса, который посылается при успешной настройке на станцию, чего мы и добились? А для этого этого есть отдельная команда FM_TUNE_STATUS (0x22), которую можно вызвать после двух вышеперечисленных функций начала приёма. Она возвращает байт STATUS уже с нужной информацией - 0x80 при отсутствии подключения, 0x81 при его наличии. После статуса приходят ещё 7 байт, подробнее о которых можно узнать на странице 73 AN332 Programming Guide.
    Чуть подробней расскажу как понять, на какой частоте радио мы слушаем. Частоту возвращает вышеописанная функция в 2х байтах 2 и 3 (отсчёт начиная с 0го - статусного!). В байте 2 находится старшая половина, в 3м - младшая. Для этого нужно сложить эти 2 байта и мы получим значение в единицах [10кГц].
    Для примера: мы получили соответственно значения 0x29 и 0xCC. Тогда складывая получаем 29CC что в десятичном виде выглядит как 10 700. Учитывая единицу измерения [10кГц] получаем частоту радиостанции 107.00 МГц

Итоговый код

Я написал программу, которая выполняет вышеуказанный алгоритм: запускает приёмник, передаёт его версию, а после при нажатии на кнопку производит поиск радиостанции. После того, как радиостанция найдена, выводит информацию о подключении, а именно частоту.

В репозитории проекта лежит код.

Думаю, что учитывая вышеописанный алгоритм и описания функций приёма-передачи данных по шине I2C, код не нуждается в излишних комментариях.

Проверка системы автоматического сканирования

Автоматическое сканирование FM_SEEK_START имеет определённый шаг сканирования и другие настройки, которые можно прочитать в таблицах AN332. Давайте проверим как сканирует приёмник без настроек, как много станций он находит и какова повторяемость этого списка.
Для этого я написал вот такой код., в нём при отправке в Serial-порт символа "p" происходит запуск сканирования, который производится 3 раза подряд, при этом выводятся частоты с найденными радиостанциями.

Посмотрим на результат сканирования. К антенному входу был прикреплен 10см провод в качестве антенны:




Видно, что количество и частоты сосканированных радиостанций не одинаково. На RTL-SDR приёмнике я смог начитать 35 радиостанций в указанном диапазоне. Увы, но на данный момент приёмник очень сольно пропускает радиостанции. На это может влиять как и качество настройки, так и качество монтажа аппаратной части - у меня сейчас всё на макетке :) Для лучшего приёма стоит поковыряться в настройках. Надеюсь, что у Вас на это будет больше времени