CAT протоколы Kenwood и Icom. Примеры использования

Тема cat протокола и вообще сопряжения трансивера с компьютером для многих радиолюбителей остается «темным лесом». Постараюсь пролить немного света на данную проблему с точки зрения построения дешифратора диапазонов практически для любого трансивера.

Общие понятия

CAT (computer aided transceiver, «трансивер с компьютерной поддержкой») — это общее понятие для интерфейса между компьютером и трансивером. Это может быть USB, RS232 (com-порт), UART (Universal Asynchronous Receiver-Transmitter), ethernet и т.д. По такому интерфейсу происходит управление радиостанцией — переключение и считывание частот, видов модуляции и всех остальных параметров. Производители трансиверов обычно стараются придерживаться определенного протокола обмена. Это упрощает интеграцию новых трансиверов в радиолюбительские программы и упрощает работу с ними.

На данный момент существует два самых популярных CAT-протокола, который используют большинство производителей. Это стандарт Icom, который используется во всех трансиверах Icom, и Kenwood, который помимо самой компании Kenwood, использует так же Elecraft и современные модели трансиверов компании Yaesu.

Протокол Kenwood

Чаще всего трансиверы Kenwood уже имеют полноценный RS232 порт, с помощью которого происходит обмен данными с компьютером. Для наших целей нужны всего три линии — RXD, TXD и GND. При этом надо не забыть замкнуть между собой RTS и CTS в этом разъеме.

Описание CAT протокола Kenwood можно скачать здесь. Описание довольно подробное, а для целей дешифрации частоты трансивера нам нужна по сути только команда IF;
При отправке этой команды трансиверу он возвращает в ответ полную информацию о своем состоянии, в том числе о частоте.

Современные микроконтроллеры (к примеру STM32) имеют на своем борту несколько модулей UART. Для наших целей подойдет микроконтроллер с двумя UART. Таки образом можно организовать трансляцию данных «сквозь» микроконтроллер — один UART модуль подключен к трансиверу, другой — к USB-UART преобразователю, который подключается к компьютеру. Таким образом происходит трансляция данных от ПК к трансиверу и в обратную сторону. А микроконтроллер при этом получает всю нужную информацию из этого обмена.

Алгоритм следующий:

  • на обоих UART модулях включаются прерывания (в RX буфер что-то пришло)
  • в обработчиках прерываний первым делом перенаправляем данные, пришедшие в UART, в другой UART
  • далее обрабатываем пришедшие символы от модуля UART, подключенного к трансиверу
  • если посылка начинается с IF, значит это сообщение нам нужно будет «распарсить» (получить из него необходимые данные)
  • если посылка начинается не с IF, ничего не делаем
  • в любом случае ожидаем в конце символа ;
  • после этого запускаем функцию-парсер текущей частоты трансивера
  • модуль UART, подключенный к ПК, делает только ретрансляцию символов на другой UART

Весь алгоритм должен занимать как можно меньше процессорного времени. Как в общем-то и любой обработчик прерываний. Если дешифратор подключен только к трансиверу без ПК, или на компьютере не запущена никакая программа, требующая CAT-обмена, можно организовать самостоятельный опрос трансивера. Для этого необходимо засечь время, в течение которого не происходило обмена данными по UART, подключенному к ПК. Например, если обмена нет в течение 2 секунд — дешифратор может самостоятельно отправить трансиверу запрос формата IF;. При этом после запуска, например, аппаратного журнала на компьютере, обмен данными по CAT будет происходить без коллизий — дешифратор перестанет самостоятельно отправлять запросы к трансиверу.

Пример исходного кода такого обработчика прерываний:

/*
TRXData[37] - массив данных от трансивера
DecodeData() - функция-парсер частоты трансивера
*/
void LPUART1_IRQHandler(void)
{
  char letter2;
  static uint8_t i = 0;
  if (LL_LPUART_IsActiveFlag_RXNE(LPUART1)) 
  {
    USART1->TDR = LPUART1->RDR;
    letter2 = LPUART1->RDR;
    if (letter2 != ';') 
    {
      TRXData[i] = letter2;
      i++;
      if (i == 36) i = 0;
    } else 
    {
      TRXData[i] = ';';
      i = 0;
      if ((TRXData[0] == 'I') && (TRXData[1] == 'F')) DecodeData();
    }
  }
}

При желании можно добавить функции-парсеры текущего вида модуляции, активного VFO, активного аттенюатора, уровня мощности и так далее. Всё зависит от ваших потребностей.

Примеры таких дешифраторов я уже публиковал (здесь, здесь и здесь).

Протокол Icom

Алгоритм работы с трансиверами Icom практически такой же. За исключением того, что два модуля UART не нужны. Интерфейс CI-V представляет собой тот же самый UART, только с соединенными между собой линиями RX и TX. Поэтому и дешифратор, и интерфейс для связи с компьютером, могу подключаться к одной линии. Пропускать данные «сквозь» микроконтроллер не требуется. Опрашивать трансивер тоже не надо — в режиме «Transceive» любое изменение частоты формирует посылку в порт CI-V.

Сам протокол обмена не текстовый. Данные посылаются в виде байтов, которые так же можно распарсить в прерывании. Описание протокола.

Пример исходного кода обработчика прерываний:

/*
TRXData[15] - массив данных от трансивера 
DecodeData() - функция-парсер частоты трансивера 
*/
void USART1_IRQHandler(void) 
{
  uint8_t letter;
  static uint8_t i = 0;
  if (LL_USART_IsActiveFlag_RXNE(USART1)) 
  {
    letter = LL_USART_ReceiveData8(USART1);
    if (letter != 0xFD) 
    {
      TRXData[i] = letter;
      i++;
      if (i == 15)
      i = 0;
    } else 
      {
        TRXData[i] = 0xFD;
        i = 0;
        if ((TRXData[0] == 0xFE) && (TRXData[1] == 0xFE)
          && ((TRXData[4] == 0x00)||(TRXData[4] == 0x03))) 
        {
          DecodeData();
        }
      }
    }
}

Частота в протоколе задается в необычном формате:

Для КВ диапазонов в четырех ячейках лежит информация о текущей частоте поразрядно.  Приведу пример функции DecodeData():

void DecodeData()
{
  if ((TRXData[8] == 0x01) || (TRXData[8] == 0x02))
    flag_band = 160; //160m 1000-2999 kHz
  if ((TRXData[8] == 0x03) || (TRXData[8] == 0x04))
    flag_band = 80; //80m 3000-4999 kHz
  if ((TRXData[8] == 0x05))
    flag_band = 60; //60m 5000-5999 kHz
  if ((TRXData[8] == 0x07))
    flag_band = 40; //40m 7000-7999 kHz
  if ((TRXData[8] == 0x10))
    flag_band = 30; //30m 10000-10999 kHz
  if ((TRXData[8] == 0x14))
    flag_band = 20; //20m 14000-14999 kHz
  if ((TRXData[8] == 0x18))
    flag_band = 17; //17m 18000-18999 kHz
  if ((TRXData[8] == 0x21))
    flag_band = 15; //15m 21000-21999 kHz
  if ((TRXData[8] == 0x24))
    flag_band = 12; //12m 24000-24999 kHz
  if ((TRXData[8] == 0x28) || (TRXData[8] == 0x29))
    flag_band = 10; //10m 28000-29999 kHz
  if ((TRXData[8] == 0x050))
    flag_band = 6; //6m 50000-50999 kHz
}

Пример такого дешифратора Icom.

Бонус

Иногда требуется преобразовать один протокол в другой. Единственная сложность в таком случае возникает с формированием данных о частоте. Форматы протоколов разные, поэтому я написал небольшую функцию, которая преобразует данные о частоте из протокола Kenwood в протокол Icom. Вот ее исходный код:

unsigned int hexToDec(char freq[2]) 
{
  unsigned int decValue = 0;
  int nextInt;
  for (int i = 0; i < 2; i++) 
  {
    nextInt = freq[i];
    if (nextInt >= 48 && nextInt <= 57) nextInt = nextInt - 48;
    decValue = (decValue * 16) + nextInt;
  }
  return decValue;
}

Функция принимает на вход две цифры частоты из протокола Kenwood, а возвращает ячейку частоты в формате протокола Icom. Таким образом у меня реализована эмуляция работы интерфейса CI-V для управления различными усилителями мощности (OM Power или Icom) трансиверами с протоколом Kenwood.

Запись опубликована в рубрике STM32, Радио с метками , , . Добавьте в закладки постоянную ссылку.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *