M2D/M2D2. Как получить кодированный сигнал

Применение декодеров M2D и M2D2 уже хорошо само по себе: не надо напрягаться — что-то изобретать, потеть над программным обеспечением для микроконтроллера по расшифровке манчестеровского кода — установил микросхему и легко получил результат! Простота применения и эффективность получения результатов на лицо. Да и цена ненапряжная.

Но есть одна заморочка. Разработчики, использующие M2D/M2D2 уже не однажды задают мне один и тот же вопрос — а как, собственно. получить Манчестерский сигнал?

Не-е, вообще получить сигнал, закодированный Манчестеровским кодом, проблемы нет! Вопрос в том, как это сделать эффективно?

Ведь люди что делают — они программно формируют этот код с помощью ногодрыжества. Само по себе это не есть нечто криминальное. Можно итак делать. Другое дело, что это не есть хорошо. Особенно в случае, если в передающем микроконтроллере используются прерывания, которые вносят сдвиги при формировании фронтов сигнала. Отсюда и проблемы с его приёмом и декодированием.

Что ж! Значит, пришло время поделиться секретами.

Позвольте, я начну с издалека, что бы было понято, что и для чего мы делаем.

Итак, у нас имеется некоторое оборудование, назовём его условно — зонд, — которое получает какие-то данные из физической среды. Например, измеряет температуру или измеряет магнитную проницаемость среды. Не важно ЧТО измеряет это оборудование, важно, что измеряемые величины оцифрованы и находятся в памяти микроконтроллера.

Кроме того, и это следует особо отметить, у зонда нет своего источника питания. И в самом деле, если этот зонд предназначен для погружения в глубокую скважину, то есть два способа запитать его.

Первый способ — снабдить зонд достаточно энергоёмкими источниками питания, и каждый раз перед погружением разбирать-собирать зонд. С одной стороны, это не совсем удобно делать в «поле». А с другой — частые разборки-сборки зонда не очень продлевают срок его эксплуатации. Ведь зонд, погруженный в скважину на глубину 1 км, подвергается ахрененно высокому давлению в 100 кг на квадратный сантиметр.

А ведь бывают исследования и более глубоких скважин. На пяти километрах глубины давление уже 500 очков. Вы можете себе представить такое адское давление. Я — с трудом. Поэтому каждая сборка-разборка зонда (для замены источника питания) чревата тем, что при очередном погружении зонд протечёт. Последствия прикидывайте сами.

Поэтому, зонды со сменяемыми источниками питания применяются не очень часто.

Второй способ — подавать питание по кабелю, с помощью которого зонд опускается в скважину. Этот способ используется значительно чаще.

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

Другой вариант — использовать недорогой одножильный кабель. Но в этом случае придётся изобретать систему передачи данных и питания по одной жиле. Собственно, это не космические технологии, но определённые трудности имеются.

Как можно видеть от наземного оборудования (точнее — от блока питания) к зонду по жиле кабеля поступает питающее напряжение. По той же жиле в обратном направлении — от зонда к наземному оборудованию — данные.

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

На стороне зонда нужно как-то суметь из кабеля получить питание и «засунуть» в кабель сигнал. На стороне наземного оборудования, нужно в кабель подать питающее напряжение, а из кабеля извлечь данные.

Задача безусловно решаемая. Секретов никаких нет. Всё давно уже известно.

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

или RC-разделитель

После того, как сигнал данных будет отфильтрован от постоянного напряжения, питающего зонд, он подаётся на декодер M2D/M2D2. С выхода декодера сигнал можно предать сразу в компьютер или же подать в микроконтроллер.

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

А вообще, зачем нужно использовать стабилизаторы? Почему нельзя обойтись без них? Застабилизировали напряжение на входе в кабель и всё!

Нет, не всё! К сожалению, жила кабеля и оплётка кабеля обладают сопротивлением. И это сопротивление достаточно большое. Порой оно может достигать десятков-сотен ом. Поэтому на кабеле вполне может падать даже несколько десятков вольт.

Мало того — оплётка кабеля не имеет изоляции. Поэтому когда кабель смотан на бобину, то начальные витки контачат с последними витками и сопротивление по обмотке незначительное. По мере опускания зонда в скважину кабель разматывается и сопротивление по его оплётке увеличивается. А это значит, падение напряжения на кабеле будет возрастать. Ну и не надо забывать, что у лебёдки имеются токосъёмники, у которых контакты находятся далеко не в идеальном состоянии. В общем, стабилизатор напряжения на стороне зонда, как ни крути, — нужен.

Если бы нам не нужно было передавать сигнал по кабелю, то мы могли бы установить какой-нибудь традиционный стабилизатор типа 7805 и успокоиться. К сожалению, такой способ в нашем случае не работает. Входное сопротивление такого стабилизатора крайне мало и полезный сигнал, который мы хотим «загнать» в кабель, будет легко зашунтирован.

И что же нам делать?

Поэтому мы с вами вместо обычных стабилизаторов в схеме зонда должны использовать параллельные стабилизаторы.

Да, они не отличаются высоким к.п.д. Да, они рассеивают много тепла. Но зато они имеют очень высокое входное (подчёркиваю — не выходное!) сопротивление, и поэтому практически не ослабляют передаваемый сигнал.

Ну и нам остаётся рассмотреть последний вопрос — как не напрягаясь закодировать сигнал кодом Manchester-II.

В своей практике я обычно использую UART-ы (USART). По сравнению с другими интерфейсами, такими как SPI и I2C (TWI), — использование UART-а довольно-таки удобно. Сигналы с UART можно сразу «загонять» в комп используя простецкие USB-конвертеры типа CH340G или FT232R. Ну а если у вас на компе имеется последовательный порт RS232, то использовать микросхему MAX232 или её аналог. В общем, передавать сигналы с UART в комп крайне просто.

Вопрос в том, что нужно сделать, чтобы UART-овский сигнал закодировать кодом Манчестера?

Эта задача решается чрезвычайно просто, если вы используете микроконтроллер AVR. Для получения результата нужно смешать на элементе ИСКЛЮЧАЮЩЕЕ-ИЛИ сигнал TX с выхода UART-а с синхросигналом XCK.

На выходе элемента ИСКЛЮЧАЮЩЕЕ-ИЛИ будет идеальный сигнал в манчестеровской кодировке. Нам остается только усилить его и подать в кабель.

На схеме центральная жила кабеля обозначена как LINE, а оплётка кабеля — SHIELD.

В левой части схемы для примера приведены два параллельных стабилизатора на 15 В и на 5 В. Стабилизаторы рассчитаны на максимальные токи 250 мА и 100 мА соответственно. Если вы предполагаете, что ваши схемы будут потреблять меньшие токи, то смело увеличивайте значения резисторов R5R6 и R10R11. Микросхемы LM317 Работают в режиме генераторов стабильного тока. Весь ток, который не будет «скушан» вашей схемой пойдёт на разогрев транзистора Q2 или Q3. Поэтому тут нужно чётко себе представлять на какой ток должен быть рассчитан стабилизатор.

Всё! Задача передачи данных и подачи питания по одному проводу решена.

Ниже приведен пример программы (для зонда), которая занимается передачей в комп строки символов «1234567890».

#include <stdint.h>
#include <avr/interrupt.h>
#include <util/delay.h>


// Определения битов порта PD
#define TXD         (1)    // Данные
#define XCK         (4)    // Синхросигнал

// Скорость работы последовательного порта
#define BAUD            (9600)


// Настраивает ноги микроконтроллера
void initPins(void)
{
  // Порт D
  DDRD  = (_BV(XCK) | _BV(TXD));  // XCK и TXD -- это выходы
  PORTD = (_BV(XCK) | _BV(TXD));  // XCK и TXD в неактивном состоянии должны быть = 1  
}


const uint8_t *pPack;  // Указатель на пакет
uint8_t txOut;         // Индекс байта для копирования в передатчик
static uint8_t txLen;  // Длина пакета


// Обработчик прерывания от передатчика UART
ISR(USART_TX_vect)
{
  UCSR0B &= ~(_BV(TXCIE0) | _BV(TXEN0));  // Останавливаем передатчик
  UCSR0C &= ~_BV(UMSEL00);                // Останавливаем XCK
}


ISR(USART_UDRE_vect)
{
  UDR0 = pPack[txOut];  // Загружаем очередной байт пакета в регистр передатчика

  txOut++;  // Переходим к следующему байту пакета

  if (txOut == txLen)  // Это конец?
  { // Это был последний байт пакета. Меняем тип прерываний от передатчика
    UCSR0B &= ~_BV(UDRIE0);  // Запрещаем передачу от опустошения входного буферного регистра
    UCSR0B |=  _BV(TXCIE0);  // Разрешаем прерывание по окончанию передачи
  }
}


// Инициализация UART
void initUart(void)
{
  UBRR0 = F_CPU / (2 * BAUD) - 1;
  UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);  // Синхронный режим
}


// Посылает пакет данных
// p - указатель на пакет данных
// len - длина пакета
void sendPack(const uint8_t *p, uint8_t len)
{
  pPack = p;
  txLen = len;

  txOut = 0;    // Индекс текущего байта для передачи

  UCSR0C |= _BV(UMSEL00); // Запускаем XCK   
  UCSR0B |= _BV(UDRIE0) | _BV(TXEN0);  // Разрешаем передачу
}


char buf[] = "1234567890\n";


int main(void)
{
  uint8_t len = sizeof buf;
  
  initPorts();
  initUart();

  sei();
  while (1) 
  {
    sendPack((uint8_t *) buf, len);
    _delay_ms(1000);
  }
}

Немного поясню, что в программе происходит. Программа один раз в секунду вызывает функцию передачи пакета символов sendPack().

Эта функция инициализирует глобальные переменные и запускает передатчик. Сама передача данных происходит по-байтно в обработчике прерывания.

Код программы написан для компиляции в avr-gcc (который под Линуксом).

К сожалению, такой способ получения манчестеровского кода работает только в микроконтроллерах AVR. У микроконтроллеров STM32 тоже есть возможность получения тактового синхросигнала для создания Манчестера, но есть одна неприятная засада. В паузах между байтами, когда нет передачи по TX, синхросигнал тоже пропадает. Но что ещё хуже — я не смог получить синхроимпульсы при передаче стартового и стопового бита. Ну это вообще ни в какие ворота! Таким образом, один из лучших микроконтроллеров вообще выбывает из соревнований по глупой причине его инвалидности. А жаль! Очень жаль!

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

Что же касаемо AVR, то микроконтроллеры «молотят» синхросигнал XCK не взирая на то, что передаются ли информационные биты или стартовые/стоповые, или вообще образовалась пауза в передаче между байтами. Производство сигнала XCK происходит постоянно не взирая на состояние TX, и выключается только программно.

Ещё раз — принцип непрерывности передачи синхросигнала вне зависимости от передачи данных избавляет от многих проблем. В частности, нет необходимости каждый раз восстанавливать синхронизацию.

Что же делать, если очень хочется работать с STM32?

Единственное, что можно попробовать — это попробовать передавать информацию через UASRT, а через SPI. Для этого нужно вместо сигналов TX и XCK смешивать на ИСКЛЮЧАЮЩЕМ-ИЛИ сигналы MOSI и SCK. Остальное всё остается без изменений. На приёмном конце — M2D и M2D2 имеют соответствующие выводы и для данных, и для синхросигнала. К этим выводам нужно подключить входы микроконтроллера MOSI и SCK. На забудьте, что на приёмной стороне модуль SPI микроконтроллера должен работать в режиме slave. Остаётся только сожалеть, что в случае передачи по SPI, не получиться легко (то есть — непосредственно) передать сигнал с M2D/M2D2 сразу в комп. Хочешь-не хочешь, а дополнительный микроконтроллер ставить придётся.

Ну и в заключение хочу поблагодарить тех, кто использует мои M2D/M2D2. Спасибо!

Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

w

Connecting to %s