Top.Mail.Ru

Манчестерский код. Часть 2. Декодирование данных.

Закодировав данные манчестерским кодом следуем по наиболее логичному пути, который ведет нас к процессу декодирования. Поставим задачу взять непосредственно те самые данные, которые были сгенерированы в предыдущей статье, подать их на декодер и сверить полученный результат с исходной последовательностью.

За основу возьмем проект из уже упомянутой статьи и добавим в него функции для декодирования манчестерского кода. Сигнал генерируется на PA3, возьмем другой пин, и на него подадим этот сигнал, физически замкнув ножки. Пусть будет PA4, почему бы нет:

STM32CubeMx pinout

Выбранный вывод настраиваем на генерацию прерываний при изменении уровня сигнала, по обоим фронтам сигнала, потому что нам нужны будут и передний и задний фронты для работы:

Помимо этого в CubeMx ничего добавлять или менять не потребуется, таймер будем использовать тот же, насколько я помню - TIM2.

Декодирование манчестерского кода.

Для начала пройдемся по физической сути процесса декодирования. Я его разбил на несколько этапов, что нам добавит наглядности и прозрачности в рассмотрении протекающих явлений. Итак, список такой:

  • синхронизация по фронтам
  • синхронизация по данным
  • декодирование данных

Синхронизация по фронтам.

Берем рассмотренный нами манчестерский код:

Манчестерский код, пример

Нижний сигнал мы будем принимать на входе контроллера. И, в целом, все просто - если передний фронт (переход от низкого уровня к высокому, 0 => 1), то это должно декодироваться в бит "1". Если задний фронт (переход от высокого уровня к низкому, 1 => 0), то это закодированный бит "0".

Но из графика очевидно, что нам нужно брать не все фронты, а вполне определенные, они помечены зеленой меткой. Напротив, изменения сигнала с красными метками мы должны пропускать.

Не проблема - зная период кодирования можно отфильтровать "ненужные" перепады, поскольку время между значимыми пепепадами гарантированно соответствует этому периоду. Поскольку в реальном мире все неидеально, длительности могут плавать, поэтому зададим величину в 75% от периода кодирования. Если время между фронтами больше, то работаем, если время меньше, пропускаем фронт.

Осталось определить отправную точку. То есть для того, чтобы использовать эту логику с длительностями и периодами, необходимо знать хотя бы один значимый фронт (с зеленой меткой), чтобы относительно него уже вести отсчет. Для этой цели послужит следующий механизм.

Опять же из графика можно заметить, что два перепада разного(!) направления, разделенные периодом кодирования, гарантированно являются значимыми. И не важно, передний ли это фронт после заднего или задний после переднего. В этих случаях получаем:

  • передний и задний фронт, время между которыми соответствует периоду - это закодированные биты "1" и "0"
  • задний и передний фронт с аналогичным временным интервалом - это биты "0" и "1" исходной последовательности.

В итоге процесс, названный мной синхронизацией по фронтам, заключается в комбинации этих двух механизмов. Сначала ищем соседние фронты, разделенные периодом, и с разным направлением перепада. Затем относительно этих "верных" фронтов берем следующие, также разделенные времен