Тема 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.







Здравствуйте.
В IC-718 крайне неудобно настраивать антенну (длинный луч).
Сначала нужно переключить в меню на RTTY, потом так же в меню убавить мощность до 20 Вт, потом настроить антенну с помощью тюнера, вернуть полную мощность и переключить обратно в SSB.
Нельзя ли сделать настольное устройство, подключаемое к трансиверу, в котором реализовать переключатель рода работ и регулировку мощности?
Можно сделать устройство, которое будет, например, по нажатию кнопки, передавать в трансивер по очереди команды на переключение вида модуляции, изменения уровня мощности и т.д. Но у меня такого готового устройства нет.
Было бы очень замечательно иметь такое устройство в виде небольшой коробочки с единственной фиксированной кнопкой и простейшим световым индикатором (кнопка нажата).
Это бы очень облегчило жизнь пользователям трансиверам ICOM серии 78/718.
Ибо это Единственная операция, которая отнимает кучу времени при работе на трансивере. Пока переключаешься (переключение рода работ происходит перебором по кругу) и настраиваешься, корреспондент пропадает либо в qsb, либо отвечает другому и у них завязывается увлекательнейшая беседа минут на 10-30, либо вообще говорит всем спасибо и уходит, не дождавшись ответа на общий вызов.
А ты сидишь, весь такой настроенный в ксв 1,0 и понимаешь, что жизнь проходит зря)