Что такое манчестер в компьютере
Итак, для начала поговорим о том, что представляет собой «манчестерское» кодирование.
В «манчестерском» коде единица кодируется переходом сигнала в середине битового интервала из состояния «OFF» в состояние «ON», а ноль — наоборот, переходом сигнала в середине
битового интервала из состояния «ON» в состояние «OFF».
Что такое состояния «ON» и «OFF»?
Состояния сигнала «ON» и «OFF» — это логические состояния. В общем случае «OFF» — это неактивное состояние, такое же, как при отсутствии какого-либо обмена вообще, а «ON» — это активное состояние, то есть такое, которое как-либо отличается от неактивного. Поэтому, несмотря на то, что на картинке справа состояние сигнала «ON» показано высоким уровнем сигнала, а состояние «OFF» показано низким уровнем, это не нужно понимать буквально (просто с высоким и низким уровнем картинка привычнее и нагляднее). На самом деле состояния «ON» и «OFF» могут быть закодированы совершенно по-разному. Например, ИК-пульты кодируют эти состояния наличием или отсутствием импульсов на определённой частоте, интегральные фотоприёмники (у которых чаще всего неактивным является высокий уровень сигнала на выходе) выдают код, в котором «ON» закодировано низким уровнем, а «OFF» — высоким и т.д.
Ключевым свойством «манчестерского» кодирования является то, что при передаче каждого бита обязательно присутствуют оба состояния сигнала: «ON» и «OFF» (ещё раз смотрим на рисунок вверху). То есть, во время передачи каждого бита сигнал должен хотя бы раз изменить своё состояние. То есть «манчестерский» код может состоять только из интервалов одинарной, если соседние биты одинаковые, и двойной, если соседние биты отличаются, длительности (это продемонстрировано на рисунке слева).
Надеюсь, с тем, что такое «манчестерский» код, всё более или менее понятно, поэтому переходим к следующему вопросу — как этот код принимать и декодировать.
Ну, очевидно, что определить начало передачи данных можно по изменению состояния сигнала, воспринимаемого приёмником, с «OFF» на «ON». Однако тут есть один нюанс. Поскольку передача единицы тоже начинается с состояния «OFF», то при первом изменении сигнала из «OFF» в «ON» мы совершенно никак не сможем диагностировать что это — середина передачи единицы или начало передачи нуля. Единственное, что тут можно сделать — это заранее условиться, какой бит должен передаваться первым (то есть ввести специальный старт-бит, значение которого будет всегда строго определено).
Всё, теперь, если мы знаем с какого бита посылка начинается, знаем длительности интервалов состояний «ON» и «OFF», наш приёмник обладает точным, стабильным генератором и мы
точно знаем сколько хотим принять бит, то можно составить первый простейший алгоритм восстановления исходной, закодированной «манчестерским» кодом посылки:
- — по изменению состояния сигнала с «OFF» на «ON» определяем начало передачи
- — отсчитываем четверть длительности бита (чтобы попасть в середину полубита)
- — начинаем записывать значение сигнала. С этого момента и далее через интервалы, равные длительности бита. И так — до получения необходимого количества бит.
Вариант третий. Мы знаем с какого бита посылка начинается, но не знаем длительности интервалов, в течении которых сигнал находится в состоянии «ON» и «OFF». Что нам делать в
этом случае? Если вы по счастливой случайности знаете значение не только первого бита, но и второго, — значит вам точно известно, через какие интервалы (через целый бит или через половину)
произойдут первые 2 переключения и вы с лёгкостью можете необходимые интервалы засечь или, научно выражаясь, — синхронизировать приёмник с передатчиком.
(Ага, вот мы и раскусили зачем у RC-5 целых 2 стартовых бита. Кстати, в сетях ethernet, где тоже используется «манчестерское» кодирование, для начальной синхронизации используется целая 56-битная преамбула).
Далее можно легко воспользоваться первым или вторым из приведённых выше алгоритмов.
Ну и, предположим, ещё один вариант. Мы знаем первые два бита посылки, но наш генератор — полное говно, хотя и работает (или, говоря научными терминами, мы можем гарантировать, что за время, равное длительности полубита, частота генератора не может измениться в 1,5 раза и более). Тут-то как быть?
Да просто надо по каждому новому фронту заново вычислять значения длительности полубита и целого бита. То есть, другими словами, нужно синхронизировать приёмник с передатчиком не один раз в самом начале, а по каждому новому фронту (под фронтом будем понимать переключения между состояниями «ON»/»OFF»), благо при манчестерском кодировании у нас новый фронт присутствует в каждом передаваемом бите.
Короче говоря, рассматривать разные комбинации можно долго, запомните главное преимущество, за которое «манчестерский» код всем так полюбился: при передаче каждого бита существует изменение состояния «ON»/»OFF», которое даёт возможность синхронизировать передатчик и приёмник.
Кроме описанного выше, существует ещё, так называемое, «разностное» или «дифференциальное» «манчестерское» кодирование. В данном случае при передаче нуля битовый интервал начинается с изменения состояния сигнала на противоположное, а при передаче единицы — состояние сигнала в начале битового интервала не изменяется. В остальном всё так же, как и в обычном «манчестерском» кодировании — в середине битового интервала состояние сигнала обязательно меняется на противоположное (смотрим рисунок слева).
Прародитель "Манчестер Юнайтед" - клуб "Ньютон Хит" был основан рабочими вагоностроительного завода как команда Ланкаширской и Йоркширской железных дорог в 1878 году. Название команды в первые годы звучало как "Ньютон Хит (Ланкашир энд Йоркшир Рейлуэй)".
Первые несколько лет команду спонсировала эта самая железная дорога, но это спонсорство было минимальным. Поле было плохого качества, там даже не было раздевалки. И игрокам приходилось переодеваться в ближайших пабах и отелях.
Первые матчи команда проводила против клубов других железнодорожных сообществ, но постепенно шла вверх по английской футбольной пирамиде. Кстати, тогда цветами команды были желтый и зеленый. В 1890 году железная дорога отказалась от команды, а в 1902 году клуб получил свое нынешнее название.
Решение проблем ограничений
Манчестерское кодирование предлагает средство для устранения этих двух ограничений. Это простая цифровая схема модуляции, которая выполняет две функции:
- гарантирует, что сигнал никогда не будет оставаться на логическом низком или высоком уровне логики в течение длительного периода времени;
- преобразует сигнал данных в сигнал данных плюс синхронизация.
Футбольный клуб при церкви
Прародитель "Манчестер Сити" - клуб "Сент Маркс" находился в историческом районе Манчестера - Вест Гортоне. Изначально клуб состоял при англиканской (протестантской) церкви Святого Марка - отсюда и такое название.
В 1880 году два церковных сторожа решили организовать футбольную команду, чтобы отвлечь прихожан от пьянства и хулиганства, процветающих в Вест Гортоне. При церкви уже действовал крикетный клуб - на его базе был создан и футбольный. Первые матчи футбольный клуб играл с командами других церквей.
Со временем связь с церковью постепенно терялась, команда меняла место расположения, и до того, как стать "Манчестер Сити" клуб поменял еще два названия: АФК "Гортон" и ФК "Ардуик" . "Горожанами" команда стала в 1894 году.
Кстати. Болельщики "Манчестер Юнайтед" до сих пор иногда одевают исторические желто-зеленые цвета, но только в крайних и неординарных случаях. В одной из следующих статей мы обязательно расскажем, что заставляет их это делать.
Вот такой экскурс в английскую футбольную историю. Скоро мы продолжим рассказывать вам о противостоянии этих манчестерских команд. Ставьте палец вверх - подписывайтесь на канал - у нас есть еще очень много интересного!
Ну а первая часть нашей серии тут - в ней мы рассказываем, почему фанаты Сити не считают игру с Юнайтед дерби : Манчестерского дерби не существует
Из названия статьи и обложки вы уже знаете, о чем сегодня пойдет речь, так что начинаем без предисловий сразу с главного. Итак, будем осуществлять генерацию манчестерского кода при помощи контроллера STM32. Разумеется, вначале разберемся, что из себя представляет данный тип кодирования в целом. Сразу могу анонсировать следующую статью, которая будет посвящена уже декодированию того сигнала, который мы сгенерируем сегодня, так что следите за обновлениями, добавляйте в закладки и подписывайтесь на всяческие наши группы )
Избегание постоянного тока
Сложные системы, особенно с высоким напряжением, не всегда способны обеспечить синфазное напряжение передаваемого сигнала совместимо с допустимым диапазоном общего режима приемника. Еще одна проблема - токи повреждения. Постоянное соединение не защищает от опасных долгосрочных токов, возникающих в результате короткого замыкания.
Таким образом, соединение переменного тока является простым способом уменьшить неудобства и риски, связанные с режимами синфазного напряжения и режимами отказа.
Технология линейного кодирования используется в стандартных сетях Ethernet, специфицированная — в стандарте IEEE 802.3. Линейное кодирование — это процесс, посредством которого цифровая информация в двоичном битовом потоке преобразуется в электрические сигналы для передачи.
Манчестерский код: что это такое и зачем его использовать
При передаче данных внедряются различные методы кодирования для обеспечения безопасности данных и быстрой передачи. Манчестерское кодирование является одним из таких цифровых способов кодирования. Оно сильно отличается от других методов, поскольку по умолчанию каждая длина бит данных фиксируется. Состояние бит определяется в соответствии с направлением перехода. Различные системы представляют бит-статус по-разному, но большинство систем представляют 1 бит против перехода от низкого к высокому и 0 бит для перехода с высоким и низким.
Манчестерское кодирование — это метод модуляции данных, который может использоваться во многих ситуациях, но особенно полезен при двоичной передаче информации на основе аналоговых, радиочастотных, оптических, высокоскоростных цифровых или дальних цифровых сигналов.
Синхронизация сигналов является основным преимуществом манчестерского кодирования. Она обеспечивает более высокую надежность с той же скоростью передачи данных по сравнению с другими методами. Но манчестерское кодирование также имеет некоторые недостатки. Например, оно потребляет больше полосы пропускания, чем исходный сигнал.
Все виды кодирования по Манчестеру имеют следующие характеристики:
- Каждый бит передается в фиксированное время.
- "1" отмечается, когда происходит переход от высокого к низкому; "0" выражается, когда выполняется переход от низкого до высокого.
- Переход, который используется для примечания 1 или 0, точно встречается в середине периода.
Кодирование в общем понимании — это процесс преобразования данных в формат, необходимый для удовлетворения потребностей в обработке информации, в том числе:
- Компиляция и исполнение программы.
- Передача данных, хранение и сжатие (декомпрессия).
- Обработка данных приложений, таких как преобразование файлов.
Все виды кодов могут иметь два значения:
- В компьютерной технологии кодирование представляет собой процесс применения определенного кода, такого как буквы, символы и цифры, к данным для преобразования в эквивалентный шифр.
- В электронике кодирование относится к аналого-цифровому преобразованию.
Немного истории
Манчестерский код (впервые опубликован в 1949 году) представляет собой синхронную технологию кодирования часов, используемую физическим уровнем для кодирования тактового сигнала и данных синхронного потока бит. В этом методе фактические двоичные данные, которые должны передаваться по кабелю, не отправляются как последовательность логических единиц и нолей (известные технически как Non Return to Zero или NRZ). Вместо этого биты преобразуются в несколько иной формат, который имеет ряд преимуществ перед использованием прямого двоичного кодирования.
Манчестерский код содержит частые переходы уровня, которые позволяют приемнику извлекать синхронизирующий сигнал с помощью цифровой фазовой блокированной петли (DPLL) и правильно декодировать значение и синхронизацию каждого бита. Чтобы обеспечить надежную работу с использованием DPLL, передаваемый бит-поток должен содержать высокую плотность бит-переходов. Все виды кодов гарантируют это, позволяя принимающему DPLL правильно извлекать тактовый сигнал.
Техническое описание
Двухфазный манчестерский код может потреблять примерно вдвое большую ширину полосы исходного сигнала (20 МГц). Это штраф за введение частых переходов. Для локальной сети 10 Мбит/с спектр сигналов лежит между 5 и 20 МГц. Манчестерское кодирование используется в качестве физического уровня локальной сети Ethernet, где дополнительная пропускная способность не является существенной проблемой для передачи коаксиального кабеля. Ограниченная пропускная способность кабеля CAT5e потребовала более эффективного метода кодирования для передачи 100 Мбит/с с использованием кода MLT 4b/5b. Это использует три уровня сигнала (вместо двух уровней, используемых в манчестерском кодировании), и следовательно, сигнал 100 Мбит/с занимает только полосу пропускания 31 МГц. Gigabit Ethernet использует пять уровней и кодирование 8b/10b, чтобы обеспечить еще более эффективное использование ограниченной пропускной способности кабеля, передавая 1 Гбит/с в полосе пропускания 100 МГц.
Способы кодирования
Во многих случаях вполне приемлемо использовать отдельный тактовый сигнал для достижения синхронизации между передатчиком и приемником. Но иногда такой подход нежелателен, например, когда вам нужно минимизировать количество межсоединений между частями системы или когда миниатюризация требует микроконтроллера с наименьшим количеством контактов, который может каким-то образом обеспечить требуемую функциональность.
В других ситуациях отдельный тактовый сигнал просто не является вариантом. Например, было бы крайне неэффективно включать два отдельных радиочастотных передатчика и приемника (то есть один для данных и один для часов) в сложной беспроводной линии передачи данных.
Как это работает
Двухуровневый код использует переход напряжения в двух состояниях для представления одного бита информации. Бинарный 0 представлен переходом от более высокого к более низкому напряжению в течение времени, установленного для передачи одного бита (то есть одного «битового времени»). Бинарная 1 представлена переходом от низшего к высшему. Для сетей Ethernet высокое напряжение обычно составляет +0,85 вольта, а уровень низкого напряжения обычно составляет -0,85 вольта, что делает каждый переход напряжения равным 1,7 вольта.
Сначала пишем тест
О пользе тестов можно почитать тут. В контексте решения текущей задачи будет использоваться техника Mock-объектов, поэтому для тестирования используется связка gtest (Google Test) + gmock (Google Mocking Framework). Всё это добро поставляются в исходниках, поэтому единственное требование к системе - совместимый C / C++ компилятор, например gcc g++ для Linux или Visual Studio C++ для Windows. Так выглядит простое консольное приложение, которое будет собираться вместе с тестами и запускать их:
Теперь сами тесты. Более простой задачей является преобразование данных в Манчестерский Код (encode), поэтому с неё, пожалуй, и начнём:
Все тесты помещены в макрос TEST_F() . В начале теста с помощью EXPECT_CALL() необходимо установить ожидаемое поведение. В процессе преобразования 0 => 1010101010101010 и при условии, что старший бит идёт первым (MSB), ожидается последовательный вызов методов On_Man_Encode_One() и On_Man_Encode_Zero() и так восемь раз. После того, как ожидаемое поведение описано, необходимо вызвать проверяемый метод Man_Encode() . Если реальное поведение отличается от ожидаемого, в процессе выполнения тестов будет сообщено об ошибке. В конце каждого теста также выполняется проверка условия, что количество нулей равно количеству единиц.
Преобразовать данные в Манчестерский Код очень легко:
Реализация обратной задачи - декодирования данных из Манчестерского Кода в оригинальный несколько сложнее. Перед началом передачи данных необходимо синхронизироваться с приёмником сиигнала. В реализации тестов нас особо не интересует как именно приёмник синхронизируется и в какой последовательности будут вызваны(если вообще будут) On_Man_Decode_Add_1() и On_Man_Decode_Add_0() - для этой цели обозначим предварительные ожидания как testing::AtMost(1) . После синхронизации процесс декодирования можно точно спрогнозировать и описать соответствующие ожидания с помощью EXPECT_CALL() . Также как и в предыдущем случае в конце каждого теста проверяется отсутствие постоянной составляющей (количество нулей и единиц должно совпадать).
Предположительная реализация процесса декодирования Манчестерского кода:
Практика
Тесты это хорошо, но пока что всё это больше похоже на теорию - а теория без практики, как известно, скучна. Поэтому, если Вы дочитали до этого момента, милости прошу посетить следующий пост, в котором в качестве приёмника и передатчика используются два микроконтроллера, а сам процесс эмулируется в виртуальной среде, которая умеет моделировать поведение электрических цепей.
Серийная цифровая связь стала довольно популярной. Существует много разновидностей: среди стандартных интерфейсов на уровне плат у нас есть UART, SPI и I2C. «Цифровая» связь также может быть достигнута с помощью аналоговых сигналов. Одним из примеров является линия радиочастотной передачи данных, которая использует изменения аналоговой амплитуды, частоты или фазы для беспроводной передачи двоичных данных. Также есть высокоскоростные дифференциальные интерфейсы, такие как последовательные линии связи на основе LVDS или USB.
Положительные стороны процесса
Манчестерское кодирование имеет то преимущество, что позволяет передавать данные без необходимости в дополнительном тактирующем сигнале. Это возможно, потому что переходы напряжения происходят в середине каждого интервала передачи бит, который устанавливает шаблон синхронизации. Таким образом, изменение среднего интервала позволяет приемным станциям поддерживать надлежащую синхронизацию друг с другом, чтобы обеспечить целостность передачи. Из-за дополнительного перехода на бит, который используется для целей синхронизации, кодировка Манчестера эффективна только на 50 %. Например, для получения скорости передачи данных 10 Мбит/с требуется полоса пропускания 20 МГц.
Другая версия, называемая дифференциальным манчестерским кодированием, представляет собой двоичный код нуля путем перехода напряжения в начале битового интервала и двоичный код единицы без перехода в начале битового интервала. В обоих случаях переход происходит в середине интервала для целей синхронизации. Дифференциальная манчестерская кодировка используется для сетей Token Ring IEEE 802.5.
Сборка и запуск тестов
Если Вы работаете в связке Windows + Visual Studio, необходимо выполнить следующее:
При использовании Linux + gcc g++:
Тестов много не бывает. Например, было бы неплохо добавить проверку для последовательности из двух байт и более, или проверку условия отсутствия невозможных для Манчестерского Кода комбинаций - например 111 или 000. Чем больше терпения и выдержки на этом этапе разработки - тем крепче будет сон после её сдачи в эксплуатацию.
Определение понятия
При передаче данных манчестерский код представляет собой форму цифрового кодирования, в котором биты данных представлены переходами из одного логического состояния в другое. Это отличается от более распространенного метода, в котором бит представлен либо высоким состоянием, например, +5 вольт, либо низким состоянием, например 0 вольт.
Когда используется код Манчестера II, длина каждого бита данных устанавливается по умолчанию. Это делает сигнал самосинхронизирующимся. Состояние бит определяется в соответствии с направлением перехода. В некоторых системах переход от низкого к высокому представляет логику 1, а переход от высокой к низкой представляет логику 0. В других системах переход от низкого к высокому представляет логику ноля и единицы (как переход от высокой к низкой).
Хорошо, но не идеально. Плюсы и минусы технологии
Главным преимуществом манчестерского кодирования является тот факт, что сигнал синхронизируется. Это минимизирует частоту ошибок и оптимизирует надежность. Основным недостатком является тот факт, что сигнал, закодированный в Манчестере, требует передачи большего количества бит, чем в исходном сигнале.
Несмотря на непреодолимые преимущества стандартной цифровой связи по сравнению с аналоговой сигнализацией, существуют некоторые общие ограничения технологии.
Одно из них — проблема синхронизации: приемник должен знать, когда именно передается информация для отбора входящих данных. Обратите внимание, что эта синхронизация не нужна для аналоговой аудиопередачи. Демодулированный аудиосигнал может быть доставлен в динамик без явной интерпретации данных на стороне приемника.
Другим недостатком является необходимость подключения постоянного тока. Цифровые данные могут включать длинные непрерывные последовательности из них или нули, и, таким образом, стандартный цифровой сигнал, используемый для передачи этих данных, будет оставаться на одном и том же напряжении в течение относительно длительного периода времени.
Манчестерский код.
Манчестерское кодирование (код Манчестер-II) представляет из себя способ кодирования исходного двоичного кода двоичным же цифровым сигналом. Или в переводе - на входе единицы и нули, на выходе - единицы и нули, но порядок их следования, естественно, различается.
Существует два основных типа кодирования:
- кодирование по стандарту IEEE 802.3. В данном случае логический "0" на входе кодируется перепадом напряжения с высокого уровня ни низкий, а логическая "1" - с низкого на высокий. Это мы наглядно рассмотрим чуть ниже, так что все станет окончательно понятно.
- кодирование по Г. Е. Томасу. Здесь все наоборот: бит "0" - перепад с низкого уровня на высокий, бит "1" - с высокого на низкий.
Мы будем использовать первый из этих вариантов, но это не так важно, поскольку переход на другой тип кодирования осуществить очень просто банальным инвертированием.
К особенностям манчестерского кода я бы отнес, в первую очередь:
- какой бы длинной не была исходная последовательность битов, в закодированной последовательности будет одинаковое количество единиц и нулей, что следует из способа кодирования. И это тоже станет более прозрачно при рассмотрении примеров чуть ниже. Из этого факта следует важнейшее свойство, а именно, отсутствие постоянной составляющей сигнала. Что, в свою очередь, делает возможным использование гальванически развязанных элементов для передачи 👍
- вторым важным свойством является возможность самостоятельной синхронизации приемника. То есть приемнику не требуется ни дополнительная линия с тактовым сигналом, ни даже информация о периоде следования битов в исходной последовательности. Это мы как раз подробно рассмотрим в следующей статье, когда реализуем декодирование.
А теперь минутка истории. Код получил свое название в честь университета Манчестера и компьютера Манчестерский Марк I, на котором он был впервые использован. Вот этот красавец:
Наступило время для дважды обещанного наглядного примера. Возьмем два произвольных байта, пусть будут и закодируем их. Напоминаю, используем манчестерский код по IEEE 802.3. И еще один момент - данные в пределах байта будут следовать от младшего бита к старшему. В общем, смотрим:
Каждому "0" на входе соответствует переход от высокого уровня к низкому на выходе (от "1" к "0"), для "1" - аналогично, но наоборот, от низкого к высокому.
На практике создать манчестерский код довольно просто. Для этого используем дополнительный виртуальный тактовый генератор. Виртуальным я его назвал по той причине, что программно этот генератор будет представлять из себя обычную переменную, значение которой будет меняться от "0" к "1" и обратно. При этом период генератора (период изменения значения переменной) должен быть в два раза меньше длительности передачи одного бита в исходной последовательности. Длительность передачи одного бита также называют периодом кодирования. Переходим к наглядности:
Для примера, первый бит: на входе - "1", на тактовом генераторе - "1", код Манчестер-II - "1" ^ "1" = "0".
Аналогично, для второго бита: на входе - "1", на тактовом генераторе - "0", код Манчестер-II - "1" ^ "0" = "1". Именно такой механизм будем использовать в программной реализации, к которой и переходим.
Ограничения интерфейсов
В случае с интерфейсом UART вместо внешних часов, передаваемых передатчиком и приемником, можно использовать внутренние синхронизирующие сигналы. Но эта стратегия приносит существенные ограничения:
- Не устойчива к частотным изменениям, которые становятся более проблематичными, когда передатчик и приемник находятся в разных условиях.
- Не обладает гибкостью, поскольку требует, чтобы устройства Tx и Rx были явно предварительно сконфигурированы для одной и той же скорости передачи данных.
- Обычно приемнику требуется внутренняя тактовая частота, которая значительно выше, чем скорость передачи данных, и это может привести к жестким ограничениям на максимальную скорость передачи данных.
Генератор манчестерского кода на STM32.
По новой традиции в конце статьи я помещу не только ссылку на полный проект, но и полный код файлов под спойлерами. А пока настраиваем в STM32CubeMx все, что понадобится. В данном случае, это один из таймеров, который будет основой для всего, а также порт в режиме выхода, на который будем выводить манчестерский код. У меня выбор пал на TIM2 и PA3, само собой, можно использовать любые другие в точности также:
Не забываем включить интерфейс SWD для отладки и внешнее тактирование. Да, кстати, у меня будет STM32F103C8 с внешним резонатором на 8 МГц. Но, как и всегда, код будет универсальным, чтобы использовать его на любом другом контроллере без малейших проблем. Настройки тактирования традиционные:
То есть тактовая частота таймеров составляет 72 МГц. Настроим TIM2 на переполнение каждые 10 мкс. Для этого берем предделитель 72 (в CubeMx ставим 71), и период, равный 10:
При таком делителе получим частоту таймера равной:
То есть один "тик" таймера - 1 мкс. С периодом 10 получим желаемые 10 мкс. Использование именно такого периода для таймера не критично, эта величина устанавливается в коде и может быть любой другой. Об этом чуть ниже.
Кроме того, включаем прерывание для таймера и генерируем код. Далее CubeMx нам не понадобится. Добавляем в проект файлы для работы с кодом Манчестер-II:
Начнем с определения констант в manchester_code.h - задаем выходной порт и как раз-таки период таймера в мкс:
Также тут присутствует третье значение - MANCH_BIT_TIME_US - это длительность передачи одного бита (период кодирования), также в микросекундах. Прерывание по таймеру будет срабатывать каждые 10 мкс, длительность бита - 100 мкс, поэтому рассчитываем сразу, сколько раз таймер должен переполниться до достижения этого значения:
Далее о формате данных. Как мы уже выяснили, приемник может сам синхронизироваться с принимаемыми битами, с этим все гладко. Но приемник никак не может знать, где именно "начало" данных:
То есть, приемник самостоятельно настроился на анализ нужных фронтов (в следующей статье про декодер это и будет сделано 👍), но в этот момент он может оказаться в произвольном месте байта. А мы хотим принимать данные ровно в том порядке, в котором отправляем. Поэтому к исходным данным мы будет добавлять 16 бит со специальным кодом синхронизации. В качестве этого кода возьмем, например, значение 0xAA55:
На данный момент ограничимся тем фактом, что эти 2 байта нам нужно добавить в начало передаваемых данных, соответственно также закодировав их.
Для структуризации данных добавляем:
Пробегаем по полям:
- data[MANCH_BYTES_NUM] - массив для хранения передаваемых данных. После перечня полей структуры разберемся с размером этого массива
- bitStream - это поле нужно для декодера, пока о нем умалчиваю
- byteIdx - индекс текущего кодируемого байта из массива data[]
- bytesNum - суммарное количество байт, которые нужно закодировать и выдать на выход
- bitIdx - индекс текущего бита в текущем байте data[byteIdx]
- active - флаг активности, "1" - процесс генерации активен, "0" - процесс остановлен.
По поводу размера массива - он задается все здесь же в manchester_code.h, пока мы вообще за пределы этого файла даже не выходили:
- MANCH_BYTES_NUM - максимальное количество передаваемых байт
- MANCH_SYNC_BYTES_NUM - размер синхрополя
- MANCH_DATA_BYTES_NUM - рассчитанное максимальное количество информационных байт, равное 8 в данном случае. 8 я выбрал исключительно для примера и из симпатии к цифре, можно увеличивать до больших значений.
Пойдем поэтапно, manchester_code.c - объявление переменных:
- virtTact - та самая переменная, которая будет играть роль виртуального тактового генератора при генерации манчестерского кода
- encodeData - экземпляр нашей структуры - сердце и центр всего процесса
- encodeTimerCnt - счетчик, его значение будем инкрементировать в прерывании по переполнению таймера
- htim2 - просто перетягиваем из main.c для использования в этом файле
Сейчас пойдет ряд функций для организации кодирования. Для управления выходом добавляем:
Далее по списку и по важности - функция, которая запускает процесс манчестерского кодирования:
В качестве аргументов - указатель на информационные данные и их размер (кол-во байт). Соответственно, передавать в функцию мы будем набор uint8_t значений, которые затем побитно будут кодироваться и выдаваться на PA3. На всякий случай напоминаю, что кодировать данные будем от младшего бита к старшему. То есть если на входе байт 0x22, что в двоичном виде представляет из себя 0b00100010, то на выходе будут последовательно закодированные "0", "1", "0", "0", "0", "1", "0", "0".
Итак, в функции обнуляем счетчики текущего байта и бита, а также проверяем размер данных на превышение максимально возможного количества информационных байт. В случае превышения сохраняем в bytesNum максимально допустимое значение. Далее копируем информационные данные в структуру, но начиная со 2-го байта (индекс = MANCH_SYNC_BYTES_NUM ):
Делаем так по той причине, что первые два передаваемых байта будут синхрополем, которое и помещаем в массив encodeData.data[] .
Следующая функция возвращает текущее значение бита на основе данных структуры MANCH_Data :
В manchData->data[] у нас данные, в manchData->byteIdx - номер байта, в manchData->bitIdx - номер бита. В результате функция возвращает значение этого бита в этом байте в этих данных.
Все, наконец, переходим к прерыванию таймера, в котором соберем воедино все, что было подробно разобрано:
Все действия осуществляем при активном флаге:
Разберемся, что мы имеем в итоге с временными интервалами при текущей конфигурации.
В функцию HAL_TIM_PeriodElapsedCallback() мы попадаем каждые 10 мкс. При этом период кодирования равен 100 мкс. Каждый раз заходя в callback инкрементируем счетчик encodeTimerCnt , что приведет к тому, что через 100 мкс его значение будет равно рассчитанному ранее значению MANCH_ENCODE_TIMER_MAX . Далее отсчитывать не требуется, поэтому обнуляем счетчик в этой части функции:
Кроме того, поскольку прошло 100 мкс, что есть длительность передачи одного бита, то переходим к следующему биту, инкрементируя encodeData.bitIdx . Оставшееся просто - проверяем, не вышел ли индекс бита за пределы байта, и в случае выхода, переходим на следующий байт. А если счетчик байт равен кол-ву передаваемых байт ( encodeData.bytesNum ), то все, финиш, процесс завершается.
Осталась маленькая, но самая важная часть, которая осуществляет генерацию манчестерского кода:
Помните, мы обсуждали, что период виртуального тактового генератора должен быть вдвое меньше длительности бита? Так вот поэтому здесь мы проверяем счетчик на равенство двум значениям, так как этот кусок кода должен выполниться дважды за время, равное длительности передачи бита. И в этом куске получаем значение текущего исходного бита и рассчитываем значение, которое необходимо выдать на выход все по той же формуле:
И в завершение меняем значение virtTact с 0 на 1, либо с 1 на 0.
Дело за малым - запускаем процесс генерации Манчестер-II кода из main() и анализируем результат. Для этого запускаем таймер HAL_TIM_Base_Start_IT(&htim2) и в while(1) будем запускать генерацию каждые 500 мс:
Также здесь фигурирует txData - обычный массив тестовых данных, объявленный здесь же, в main.c:
Последний байт инкрементируем в цикле, чтобы при декодировании убедиться, что не теряем посылки. Компилируем, прошиваем, запускаем, встаем осциллографом на PA3:
Переводим мысленно несколько байт наблюдаемого сигнала из манчестерского кода и получаем полное соответствие исходным данным (плюс синхрополе), что явно сигнализирует об успехе операции кодирования.
Засим откланиваюсь, в следующей статье этот же самый сигнал мы декодируем, причем этим же самым контроллером.
Манчестерский Код - это самосинхронизирующийся двоичный код без постоянной составляющей, в котором значение каждого передаваемого бита определяется направлением смены логического уровня в середине обусловленного заранее временного интервала. Поскольку логических уровней у самой маленькой единицы информации (бит) на данный момент известно всего два (1 и 0), вариантов тут немного: либо смена 1 => 0 либо 0 => 1. Согласно общепринятым стандартам для Манчестерского кода переход от нуля к единице считается 1, а если наоборот, то 0. На самом деле последнее утверждение - это просто формальность - вопрос в том, с какой стороны посмотреть ;-) Главное, чтобы и приёмник и передатчик смотрели на жизнь одинаково.
Введите число и нажмите "Encode Manchester!":
Теперь давайте внимательно посмотрим на картинку и попробуем проанализировать и перечислить основные преимущества и недостатки преобразования данных в Манчестерский Код:
Pазмер данных увеличивается вдвое - это негативно сказывается на скорости передачи
Kоличество логических нулей всегда равно количеству логических единиц, соответственно у такого сигнала не будет постоянной составляющей - это крайне важно для электрических цепей и радиоволн
Комбинация логических уровней 11 однозначно говорит о последнем принятом 0, а комбинация 00, соответственно, говорит о 1. Таким образом после одной из них приёмник синхронизируется
Не может идти последовательно более двух одинаковых логических уровней, т.е. комбинация типа 111 или 000 невозможна
В начале данных и в конце не может быть двух одинаковых логических уровней - только 10 или 01
Читайте также: