№2 / 2015 / статья 5

«Мое первое приложение для беспроводной связи в диапазоне 868 МГц» – пошаговая инструкция. Часть II

Олег Пушкарев (КОМПЭЛ)

Дано: недорогой популярный трансивер CC110L на отладочной плате 430BOOST-CC110L; микроконтроллер MSP430G2553 на отладочной плате MSP-EXP430G2. Все – производства Texas Instruments. Задача – создать простое беспроводное устройство для передачи данных в диапазоне 868 МГц

Перед вами – продолжение статьи, первую ее часть можно найти в 10 номере «Новостей электроники» за 2014 год. Рассматриваемый в данной статье программный код использован в нескольких учебных проектах, выполненных в среде разработки IAR 7.0. Исходные коды и описания лабораторных работ вы сможете скачать с сайта КОМПЭЛ, пройдя по ссылке.

Режим передачи данных

Простейшую программу, которая реализует передачу пакета при нажатии на кнопку можно найти в проекте LAB4_TX.eww (CC110L_TX_Base.c). Для выбора рабочей частоты, скорости передачи данных, вида модуляции и других параметров необходимо настроить CC110L путем записи определенных значений в его внутренние регистры. При настройке CC110L мы использовали значения, экспортированные из программы SmartRF Studio 7. Эта программа может генерировать текстовый файл с именами и значениями для тех регистров, которые имеют величины, отличные от установленных по умолчанию. При работе в SmartRF Studio нужно обязательно установить правильное значение частоты кварца. По умолчанию в SmartRF Studio стоит частота кварца 26 МГц, так как на всех отладочных платах производства Texas Instruments (СС11xxxEMK) стоит кварц 26 МГц. На используемых нами платах 430BOOST-CC110L в модулях A110LR09A распаян кварц 27 МГц, поэтому необходимо изменить значение в окне Xtal frequency на значение 27.000000. Файл, экспортированный из SmartRF Studio, нужно сохранить в папке проекта и включить в исходный код программы как обычный заголовочный файл (строка #include «CC110L_xx_config.h»).

После первоначальной настройки регистров CC110L находится в режиме IDLE, то есть не осуществляется ни прием, ни передача данных. Потребление CC110L в этом режиме меньше, чем при включенных режимах TX или RX, но не минимально возможное. В данном примере мы не экономим на потреблении и не принимаем мер по достижению минимального энергопотребления нашей схемы. В конце статьи приведен пример использования режимов сна CC110L для максимального снижения потребляемого схемой тока.

Мы выбрали режим работы CC110L с автоматической калибровкой синтезатора частоты (PLL) при каждой передаче, поэтому калибровка автоматически выполняется при переходе из IDLE в режим передачи или приема. Отдельно подавать команду на калибровку PLL нет необходимости.

Параметры передатчика, такие как рабочая частота, вид модуляции, скорость, выходная мощность, девиация, были установлены с помощью функции registerConfig(). Эта функция записывает значения из файла CC110L_TX_config.h. Используется индивидуальная запись по адресу каждого регистра. Запись ведем только в те регистры, значения которых должны отличаться от значений при сбросе (по умолчанию). Требуемые значения регистров нам помогла сформировать программа SmartRF Studio 7, которая фактически и сформировала текстовый файл, включенный в наш проект под именем CC110L_TX_config.h.

Для отправки данные нужно занести в TX FIFO (буфер передатчика внутри CC110L), а затем дать команду-строб STX, после чего они уйдут из FIFO в эфир. CC110L самостоятельно добавит перед отправляемыми данными преамбулу и четыре байта синхрослова, а после них – контрольную сумму.

Строб – это специальный регистр CC110L, куда не надо передавать какие-либо данные, достаточно к нему обратиться по SPI (по его адресу). Информацию о командах-стробах можно найти в файле cc11xL_spi.h, они также описаны в документации на стр. 63, тable. 26-1.

CC110L у нас настроен на переменную длину пакета, поэтому первый байт в буфере трактуется передатчиком CC110L как длина пакета. Соответственно, далее в буфер TX FIFO нужно отправить определенное количество байт – ни в коем случае не меньшее, чем заданное значением длины.

У нас простая программа отправки пакета, она не анализирует ошибки, которые могут возникнуть в CC110L, например TX Buffer underun. Если программа формирует корректный обмен с CC110L и имеет простой алгоритм, то такие ошибки возникнуть не могут.При каждом нажатии на кнопку передатчик отправляет в эфир пакет данных, который состоит из двухбайтного счетчика и нескольких символов, которые мы вручную записываем с помощью функции createPacket(uint8 txBuffer[]). Эта функция вызывается перед отправкой каждого пакета. Она заполняет txBuffer в памяти MSP430 следующими данными: длиной пакета, двумя байтами счетчика отправленных пакетов и пятью произвольно выбранными символами. Разумеется, в реальном изделии можно наполнить отправляемый пакет какими угодно полезными данными – состоянием кнопок, отсчетами АЦП, значением температуры, уровнем яркости светильника и тому подобным.

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

Режим приема данных

Рис. 1. Отображение принятых данных

Рис. 1. Отображение принятых данных

Простой, но устойчиво работающий код приемника приведен в проекте LAB6_RX_Data.eww (CC110L_RX_Data.c). Реализован прием пакетов переменной длины и отображение принятых данных через аппаратный UART MSP430G2553. На ПК в программу-терминал выводится счетчик принятых пакетов, сила сигнала, счетчик отправленных пакетов, собственно, данные и признак совпадения CRC (рисунок 1). В терминал выводятся даже сбойные пакеты – это помогает в разборе непонятных ситуаций, особенно при работе с предельно слабым сигналом или в условиях помех. В реальном приложении можно просто отбрасывать пакеты с неверной контрольной суммой, хотя можно пытаться работать и с такими данными, так как часть из них может быть целой. В определенных ситуациях это даст большую выгоду, по сравнению с полной потерей отдельного пакета.

Начало программы приемника совпадает с программой передатчика. Сначала производится инициализация периферии микроконтроллера, затем прописываются регистры CC110L значениями из файла «CC110L_RX_config.h». CC110L у нас настроен на переменную длину пакета, поэтому первый байт, принятый в RX FIFO, трактуется как длина пакета. Преамбула и синхрослово из радиопакета в RX FIFO никогда не заносятся! В программе анализируются ошибки, которые могут возникнуть в процессе приема, например, RX Buffer overflow, и реализовано корректное, с учетом Errata, обращение к определенным регистрам.

Для включения режима приема мы посылаем строб-команду CC110L_SRX и переходим в бесконечный цикл, в котором последовательно выполняем описанные ниже действия.

Ждем прерывания, которое формируется CC110L при приеме пакета. После приема преамбулы и синхрослова линия GDO0 устанавливается в «1». Начиная с этого момента, поступающие из эфира данные заносятся в буфер RX FIFO. Затем, после приема данных, линия GDO0 переходит в «0». Этот отрицательный перепад «1 → 0» является источником прерывания для MSP430G2553 (по линии P2.6). В подпрограмме отработки прерывания переменная packetSemaphore устанавливается в «1». Программа постоянно проверяет значение переменной packetSemaphore, и находится в этом месте до тех пор, пока в буфере не появятся какие-либо данные, то есть, пока не будет принят пакет из эфира.

Когда значение переменной packetSemaphore становится равным «1» (ISR_ACTION_REQUIRED = 1), это означает, что приемник CC110L принял в буфер RX FIFO радиопакет. Это могут быть как ожидаемые полезные данные, так и бессмысленный мусор, если в процессе приема произошли ошибки, например, вследствие помехи, которая возникла в середине принимаемого пакета. Далее программа вычитывает из CC110L значение регистра RXBYTES, где находится длина принятого пакета и признак RXFIFO_OVERFLOW, который сигнализирует о том, что в процессе приема произошло переполнение буфера. При чтении регистров CC110L по SPI могут быть ошибки, если читаемый микроконтроллером регистр одновременно обновляется самим CC110L. Ошибка возникает достаточно редко и только при определенных условиях. Это описано в Errata на CC110L (3. SPI Read Synchronization Issue). При выбранных нами настройках, а именно – при автоматическом переходе CC110L в режим IDLE после приема пакета, этой ошибки не может быть, так как вычитываемый нами регистр не может обновляться (прием окончен). Тем не менее, для универсальности кода мы делаем защиту от ошибки чтения SPI. Применяется следующий, рекомендованный производителем, метод – чтение регистра выполняется до тех пор, пока дважды не будет вычитано одно и то же значение.

Далее проверяем, что у нас в RX FIFO действительно есть какое-то количество байт данных, то есть, проверяем, что rxBytes > 0. Почему rxBytes может оказаться равным нулю? В силу разных причин:

  • произошла очистка буфера по факту несовпадения CRC (если эта опция включена);
  • прием прекратился сразу после приема синхрослова;
  • какие-то иные причины.

Не все из перечисленных выше событий могут возникнуть в конкретном режиме работы CC110L. Например, в используемой конфигурации CC110L (файл CC110L_RX_config.h) мы не включили очистку буфера при несовпадении CRC. Тем не менее, чтобы сделать код максимально надежным, мы производим несколько проверок – на наличие данных и на ошибку RX FIFO error.

Если мы обнаружили ошибку RX FIFO overflow, то это означает, что в буфере лежит мусор, который нужно просто удалить. Для этого есть специальная команда-строб SFRX («очистить приемный буфер»). Строб SFRX можно подавать только в состояниях IDLE или RXFIFO_OVERFLOW.

В случае, когда ошибки переполнения буфера не было, мы вычитываем принятые данные из RX FIFO CC110L. В ОЗУ MSP430G255 у нас подготовлен массив rxBuffer[64] на максимальную длину 64 байта. В нашем примере, пакет не должен содержать более 61 байта полезных данных, так как в буфер RX FIFO будет автоматически добавляться длина пакета (самый первый байт), а также после полезных данных будут добавляться значения RSSI и CRC (2 байта после принятых данных).

Даже если у нас не было ошибки RXFIFO_OVERFLOW и из RX FIFO было прочитано какое-то количество байт, мы должны убедиться, что это корректно принятые данные, то есть, проверить, что флаг совпадения CRC = 1. Сама проверка CRC производится автоматом, встроенным в CC110L. У нас настроен режим PKTCTRL1 APPEND_STATUS = 1, поэтому после полезных данных в FIFO добавляются два байта. Это индикатор силы сигнала RSSI (первый добавленный байт) и флаг CRC OK (второй). Флаг CRC лежит в старшем бите второго добавленного байта.

Итак, если контрольная сумма совпала, то это означает, что мы прошли все проверки и можем утверждать, что пакет принят успешно. Переключаем состояние красного светодиода – это будет индикатор «Принят пакет данных». Теперь мы можем извлечь и использовать для любых целей принятые данные, которые лежат в буфере rxBuffer [64]. Буфер имеет размер 64 байта, но реально принятый пакет может быть любой длины. Актуальное количество данных (длина пакета) находится в переменной rxBytes. С помощью функции View_data_on_uart (rxBuffer, rxBytes) отображаем через UART силу сигнала, длину пакета и принятые символы. Значение RSSI выдается CC110L в дополнительном коде со смещением. Для того, чтобы перевести значение RSSI в привычный вид, например, -79 дБм, необходимо воспользоваться формулой из документации (раздел 16.2, стр. 42).

Для корректного отображения уровня сигнала в дБм необходимо вычитанный байт RSSI преобразовать по следующему правилу:

If RSSI_dec >= 128 then RSSI_dBm = (RSSI_dec – 256)/2 – 74 (RSSI_offset)

Else if RSSI_dec < 128 then RSSI_dBm = (RSSI_dec)/2 – 74 (RSSI_offset)

После приема пакета CC110L находится в режиме IDLE, то есть не осуществляется ни прием, ни передача данных. Мы сами задали в настройках такой вариант работы трансивера, когда после получения пакета CC110L автоматом переходит из режима приема в режим IDLE, поэтому для продолжения приема мы снова включаем режим приемника стробом CC110L_SRX, и тем самым замыкаем наш бесконечный цикл «прием пакета – отображение через UART – прием пакета – и так далее».

Режим сна

Для реализации режима пониженного энергопотребления необходимо перевести MSP430 и CC110L в режим сна. Сделать это очень просто – достаточно вставить в код две строки. В проекте LAB4_TX.eww предусмотрена дополнительная конфигурация LowPower (выбирается в настройках проекта IAR), в которой активируется режим сна при ожидании нажатия на кнопку. При нажатии на кнопку происходит пробуждение микроконтроллера и отправка пакета. До момента нажатия на кнопку обе микросхемы переводятся в режимы пониженного энергопотребления – для этого в цикле вставлена функция use_low_power_modes (), где есть две такие строки:

trxSpiCmdStrobe(CC110L_SPWD); // Переводим радио CC110L в режим сна

__bis_SR_register(LPM3_bits + GIE); // MSP430 в режим LPM3 с ожиданием прерывания

Режимы сна для MSP430 и CC110L позволяют уменьшить ток потребления до значений долей микроампер при ожидании прерывания. Измеренное на практике значение находилось в пределах 100…300 нА (рисунок 2).

Рис. 2. Потребление СС110L в режиме сна

Рис. 2. Потребление СС110L в режиме сна

Фильтрация пакетов при приеме

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

Фильтрация по длине пакета

В регистре PKTLEN (0x06) задается длина пакета, если мы собираемся работать с пакетами фиксированной длины. При работе с пакетами переменной длины программа SmartRF Studio не включает этот регистр в файл настроек. Соответственно в регистре остается значение «по умолчанию», то есть 255. Для режима переменной длины пакета значение в PKTLEN определяет максимальную длину пакета. Если принятый байт длины имеет большее значение, чем число в PKTLEN, то пакет отбрасывается, и происходит возврат в режим приема. Рекомендуется добавить в файл CC110L_RX_config.h строку {CC110L_PKTLEN, 0x3B}, то есть ограничить максимальное количество записываемых в RX FIFO байт.

Фильтрация по адресу

Если принятый адрес совпадает с адресом, заданным в регистре ADDR (0x09), то пакет принимается и записывается в буфер FIFO RX.

Если адрес не совпадает, то возобновляется режим приема. В рассматриваемых здесь проектах режим адресации не используется.

Фильтрация по контрольной сумме

Включается в регистре PKTCTRL1 (0x07). Если CRC в пакете не соответствует принятым данным, то очищается весь буфер RX FIFO. Переход в следующий режим программируется в регистре MCSM1 (0x17). Возможные варианты: IDLE, FSTXON, TX или сохранение режима RX. В наших проектах мы не используем этот фильтр, чтобы иметь возможность наблюдать (выводить через UART) содержимое ошибочно принятых пакетов.

Управление выходной мощностью

Настройка выходной мощности трансивера задается в файле с помощью строки{CC11xL_PA_TABLE0, 0x03}.

В проекте трансивер работает с минимально возможной мощностью -30 дБм, что существенно ограничивает дальность действия – в пределах одной комнаты. Для получения максимальной дальности связи необходимо заменить в файле CC110L_TX_config.h значение 0x03 на 0xC0. Запись в регистр PA_TABLE0 значения 0xC0 соответствует выходной мощности +12 дБм. При такой выходной мощности трансивер CC110L будет работать на дальности в единицы километров при прямой видимости антенн.

Заключение

Приведенный исходный код программ имеет множественные комментарии на русском языке, что должно существенно облегчить работу с трансивером CC110L даже начинающему программисту. Полученные при работе с CC110L навыки в значительной мере пригодятся и при изучении других радиочастотных решений TI, так как идеология трансиверов и методы управления довольна схожи. Все упоминаемые в данной статье программы можно найти в едином архиве лабораторных работ (IAR), которые вы можете загрузить по ссылкам 1 и 2.

Получение технической информации, заказ образцов, заказ и доставка.

Наши информационные каналы

Теги: , ,
Рубрики:

О компании Texas Instruments

В середине 2001 г. компании Texas Instruments и КОМПЭЛ заключили официальное дистрибьюторское соглашение, которое явилось результатом длительной и успешной работы КОМПЭЛ в качестве официального дистрибьютора фирмы Burr-Brown. (Как известно, Burr-Brown вошла в состав TI так же, как и компании Unitrode, Power Trend и Klixon). С этого времени компания КОМПЭЛ получила доступ к поставке всей номенклатуры производимых компанией TI компонентов, технологий и отладочных средств, а также ...читать далее