Устройства TOSUN серий CAN/CAN FD и LIN можно использовать из проектов на VB6.0 через библиотеку libTSCAN: сканирование и подключение аппаратуры, одиночная и циклическая отправка CAN-сообщений, приём и фильтрация сообщений. Разбираем демо-проект приёма и передачи CAN-сигналов.
Ключевые слова: CAN-сообщения, VB6.0, libTSCAN, TLIBCAN, tsfifo.
1. О демо-проекте
Краткое описание: язык VB6.0 вызывает интерфейсы libTSCAN и реализует сканирование аппаратуры, подключение, одиночную и циклическую отправку CAN-сообщений, приём и фильтрацию сообщений.
Типовая потребность: действующие VB-проекты, которые ещё поддерживаются и развиваются, и в которых требуется приём/передача сообщений через аппаратуру TSCAN.
2. Техническая основа
В VB6.0 функции из libTSCAN.dll объявляются оператором Declare — эти объявления позволяют VB6.0 взаимодействовать с низкоуровневым API. Например:
Private Declare Function tscan_connect Lib "libTSCAN.dll" (ByVal ADeviceSerial As String, ByRef AHandle As Long) As Long
3. Реализация демо-проекта
3.1. Добавление файлов библиотек
Для работы с устройствами TOSUN CAN/CAN FD и LIN нужны динамические библиотеки libTSCAN.dll, libTSH.dll, binlog.dll и liblog.dll; их зависимости показаны на рис. 3-1.
Файлы библиотек находятся в установочном каталоге TSMaster: C:\Program Files (x86)\TOSUN\TSMaster\Data\SDK\examples\Python\Linux\lib\libTOSUN\windows\x86.

Создайте VB-проект и скопируйте перечисленные зависимости в его каталог — содержимое папки проекта показано на рис. 3-2.

3.2. Объявление функций libTSCAN.dll
Функции libTSCAN.dll объявляются оператором Declare. Синтаксис:
Private Declare [Function|Sub] имя_внешней_функции Lib "имя_библиотеки" [Alias "псевдоним"] ([список_параметров])
- Private — необязательно: объявление видно в текущем модуле. Для использования в нескольких модулях применяйте Public.
- Declare — ключевое слово объявления внешней функции.
- Function или Sub — выбирается по тому, возвращает ли внешняя функция значение.
- имя_внешней_функции — имя, под которым функция используется в коде VB6.0.
- Lib — задаёт имя DLL-библиотеки с определением функции (без расширения .lib или .dll).
- Alias — необязательно: псевдоним, если имя функции в DLL конфликтует с правилами именования VB6.0.
- список_параметров — параметры функции: имена, типы и способ передачи (ByVal или ByRef).
' загрузка библиотеки libTSCAN; обязательно вызывается перед остальными API Private Declare Sub initialize_lib_tscan_verbose Lib "libTSCAN.dll" (ByVal AEnableFIFO As Boolean, ByVal AEnableErrorFrame As Boolean, ByVal AUseHWTime As Boolean, ByVal ATSType As Long) ' освобождение библиотеки libTSCAN; обязательно вызывается перед выходом из программы Private Declare Sub finalize_lib_tscan Lib "libTSCAN.dll" () ' запрос производителя, названия продукта, серийного номера, числа CAN-каналов, ' поддержки CAN FD, числа каналов LIN, FlexRay и Ethernet Private Declare Function tscan_get_device_info_detail Lib "libTSCAN.dll" (ByVal ADeviceIndex As Long, ByRef AManufacturer As Long, ByRef AProduct As Long, ByRef ASerial As Long, ByRef ADeviceType As Long, ByRef ADeviceName As Long, ByRef ACANChannelCount As Long, ByRef AIsCANFD As Boolean, ByRef ALINChannelCount As Long, ByRef AFRChannelCount As Long, ByRef AEthernetChannelCount As Long) As Long ' подключение устройства Private Declare Function tscan_connect Lib "libTSCAN.dll" (ByVal ADeviceSerial As String, ByRef AHandle As Long) As Long ' отключение устройства Private Declare Function tscan_disconnect_by_handle Lib "libTSCAN.dll" (ByVal AHandle As Long) As Long ' запрос числа TSCAN-устройств в сети Private Declare Function tscan_scan_devices Lib "libTSCAN.dll" (ByRef ADeviceCount As Long) As Long ' настройка канала классического CAN Private Declare Function tscan_config_can_by_baudrate Lib "libTSCAN.dll" (ByVal AHandle As Long, ByVal AChnIdx As Long, ByVal ARateKbps As Double, ByVal A120OhmConnected As Long) As Long ' настройка канала CAN FD; AControllerType [0: классический CAN, 1: ISO-FD, 2: NonISO-FD] ' AControllerMode [0: Normal, 1: ACKOff, 2: Restricted, 3: Internal Loop, 4: External Loop] Private Declare Function tscan_config_canfd_by_baudrate Lib "libTSCAN.dll" (ByVal AHandle As Long, ByVal AChnIdx As Long, ByVal AArbRateKbps As Double, ByVal ADataRateKbps As Double, ByVal AControllerType As Long, ByVal AControllerMode As Long, ByVal A120OhmConnected As Long) As Long ' отправка сообщений CAN/CAN FD Private Declare Function tscan_transmit_can_sync Lib "libTSCAN.dll" (ByVal ADeviceHandle As Long, ByRef ACAN As TLIBCAN, ByVal ATimeoutMS As Long) As Long Private Declare Function tscan_transmit_can_async Lib "libTSCAN.dll" (ByVal ADeviceHandle As Long, ByRef ACAN As TLIBCAN) As Long ' циклическая отправка сообщений CAN/CAN FD ' добавление циклически отправляемого CAN-сообщения Private Declare Function tscan_add_cyclic_msg_can Lib "libTSCAN.dll" (ByVal ADeviceHandle As Long, ByRef ACAN As TLIBCAN, ByVal APeriodMS As Single) As Long ' удаление циклически отправляемого CAN-сообщения Private Declare Function tscan_delete_cyclic_msg_can Lib "libTSCAN.dll" (ByVal ADeviceHandle As Long, ByRef ACAN As TLIBCAN) As Long
3.3. Структуры данных CAN / CAN FD
Структуры данных CAN и CAN FD показаны на рис. 3-3.

3.4. Описание используемых интерфейсов
initialize_lib_tscan_verbose — инициализация модуля библиотеки tscan. Другие API-функции можно вызывать только после инициализации CAN-модуля этой функцией. Используется в паре с finalize_lib_tscan.
AEnableFIFO[IN] — включить ли механизм FIFO; рекомендуется True, иначе чтение сообщений функциями tsfifo_receive_xx будет невозможно;AEnableErrorFrame[IN] — принимать ли кадры ошибок; при False драйвер отбрасывает кадры ошибок;AUseHWTime[IN] — использовать ли аппаратное время устройства;ATSType[IN] — установите False.
Возвращаемого значения нет.
finalize_lib_tscan — освобождение CAN-модуля перед выходом из программы; парная к initialize_lib_tscan. Параметров и возвращаемого значения нет.
tscan_get_device_info_detail — получение информации об устройстве. Параметры: ADeviceIndex [IN] — индекс устройства; AManufacturer [OUT] — производитель; AProduct [OUT] — название продукта; ASerial [OUT] — серийный номер; ADeviceType [OUT] — тип устройства; ADeviceName [OUT] — имя устройства; ACANChannelCount [OUT] — число CAN-каналов; AIsCANFD [OUT] — поддержка CAN FD; ALINChannelCount [OUT] — число LIN-каналов; AFRChannelCount [OUT] — число FlexRay-каналов; AEthernetChannelCount [OUT] — число Ethernet-каналов.
tscan_connect — подключение устройства и получение его уникального дескриптора. Параметры: ADeviceSerial — серийный номер нужного устройства; пустая строка означает подключение любого доступного устройства; AHandle — дескриптор устройства, по которому выполняются все последующие операции с аппаратурой.
tscan_scan_devices — сканирование числа устройств в сети. Параметр: ADeviceCount [OUT] — число устройств в сети.
tscan_config_can_by_baudrate — настройка скорости CAN-шины. Параметры: AHandle — дескриптор устройства; AChnIdx — номер канала приложения; ARateKbps — скорость; A120OhmConnected — включение внутреннего терминального резистора.
tscan_transmit_can_sync — отправка CAN-сообщения: функция завершается только после подтверждения отправки. Успешный возврат гарантирует, что сообщение действительно передано в CAN-шину. Параметры: ADeviceHandle — дескриптор устройства; ACAN — данные сообщения; ATimeoutMS — таймаут синхронного ожидания.
tscan_transmit_can_async — асинхронная отправка CAN-сообщения. Параметр: ACAN — пакет данных CAN; состав TLIBCAN см. в разделе о структурах данных CAN/CAN FD.
tscan_add_cyclic_msg_can — добавление циклически отправляемого сообщения. Параметры: ADeviceHandle — дескриптор устройства; ACAN — пакет данных CAN; APeriodMS — период.
tscan_delete_cyclic_msg_can — удаление циклически отправляемого CAN-сообщения. Параметр: ACAN — удаляемое циклическое сообщение.
tsfifo_receive_can_msgs — чтение пакетов сообщений из аппаратного буфера. Параметры: ADeviceHandle — дескриптор устройства; ACANBuffers — буфер для прочитанных сообщений (создаётся вызывающей стороной); ACANBufferSize — размер буфера; AChn — целевой канал: для многоканальных устройств выбирает читаемый канал, по умолчанию канал 1; ARxTx: ==0 — принимать только Rx-сообщения, >0 — читать и Tx, и Rx; по умолчанию только Rx.
tsfifo_add_can_canfd_pass_filter — вызывается, если нужно принимать только сообщения с определёнными ID. Параметры: ADeviceHandle — дескриптор устройства; AChnIdx — индекс канала; AIdentifier — идентификатор сообщения; AIsStd — стандартный ли кадр.
tsfifo_delete_can_canfd_pass_filter — отмена фильтрации сообщений. Параметры: ADeviceHandle — дескриптор устройства; AChnIdx — индекс канала; AIdentifier — идентификатор сообщения; AIsStd — стандартный ли кадр.
3.5. Результат работы демо на VB6.0
- Кнопка «Сканировать устройства» — число устройств в сети выводится в элементе справа.
- Кнопка «Запросить информацию об устройстве» — подробная информация об устройстве выводится справа.
- Кнопка «Подключить» — подключение аппаратуры; справа выводятся журнал успешного подключения и дескриптор устройства.
- Кнопка «Настроить аппаратный канал» — настройка канала и скорости.
- Кнопка «Канал 1: отправить обычное сообщение» — одиночная отправка 0x7B.
- Кнопка «Принимать CAN-сообщения на канале 2» — чтение сообщений из FIFO с выводом в ListBox ниже.
- Кнопка «Отправить циклическое сообщение» — сообщение 0x29A отправляется с периодом 50 мс.
- Кнопка «Остановить циклическую отправку» — циклическая отправка 0x29A прекращается.
- Кнопка «Принимать CAN-сообщения на канале 2» — чтение сообщений из FIFO с выводом в ListBox (рис. 3-4).

4. Вопросы и ответы
В: После подключения устройство непрерывно принимает сообщения. Если затем включить фильтрацию и отправить сообщения, нужно ли при приёме сначала вычитать накопленные старые данные, пока не дойдут отфильтрованные ID?
О: Да. После добавления фильтра самостоятельно очистите старый буфер функцией tsfifo_clear_can_receive_buffers.
В: Что означает возвращаемое значение функций?
О: Возвращаемое значение 0 — успешное выполнение, остальные значения — ошибка. Конкретную причину смотрите по таблице встроенных констант TSMaster: например, значение 3 означает «устройство не найдено» — проверьте, нормально ли подключено устройство TSCAN (рис. 4-1).
