Как создать виртуальный com порт для usb windows xp

Из описания на сайте: VSPE призвана помочь инженерам программного обеспечения и разработчикам создавать / производить отладку / тестирование приложений,

Содержание

  • 1 ПРОБЛЕМЫ СО СКАЧИВАНИЕМ ИЛИ ИНСТАЛЛЯЦИЕЙ?
  • 2 Вас могут заинтересовать:
    • 2.1 Advanced Serial Port Monitor
    • 2.2 Advanced Serial Data Logger
    • 2.3 Advanced TCP/IP Data Logger
    • 2.4 Serial Printer Logger
    • 2.5 Advanced NMEA Data Logger

Из описания на сайте:
VSPE призвана помочь инженерам программного обеспечения и разработчикам создавать / производить отладку / тестирование приложений, которые используют последовательные порты. Она может создавать различные виртуальные устройства для приема / передачи данных. В отличие от обычных последовательных портов, виртуальные устройства имеют специальные возможности: например, то же устройство может быть открыто несколько раз по различным приложениям, которые могут быть полезны во многих случаях. Вы можете сделать доступными физические данные СОМ порта для нескольких приложений, расшаривать последовательный порт для локальной сети (по протоколу TCP) итд.

Функции:
* Virtual device: connector
* Virtual device: data splitter
* Virtual device: pair
* Mapper device
* User mode device: TcpServer
* User mode device: TcpClient
* User mode device: Serial Redirector
* User mode device: UDP Manager
* User mode device: Bridge
* Python scripting system
* x86 and x86_64 processor architecture support
* VSPE API (C/C++ header and static library) for native language developers
* VSPE API Python bindings for Python developers
* Embedded HTTP server
* Data monitoring

Эмулировать COM-порт помогают соответствующие драйверы и программы, с помощью которых создаётся виртуальный порт в системе. Для начала надо установить АТОЛ-драйвер, соответствующий типу подключаемого оборудования. Для эмуляции COM-порта предназначена программа «Virtual Null Modem». Чтобы осуществить отправку данных на COM-порт без подключения устройства можно использовать бесплатную программу «COM Port Data Emulator».

Утилиты запускают процесс создания виртуального СОМ-порта путём простого включения режима «Эмуляция» через интерфейс программы. Если же был установлен драйвер для эмуляции, то новый виртуальный COM-порт просто будет отображаться в диспетчере устройств. Таким образом можно осуществить подключение оборудования к ПК посредством эмуляции COM-порта. Подключите устройство и переведите его в режим работы по USB, следуя прилагающийся инструкции.

Чтобы проверить, верно ли подключено оборудование, зайдите в режим тестирования драйвера АТОЛ нужного устройства. В открывшемся окне интерфейса следует выбрать вкладку «Настройка свойств», затем нажать кнопку «Поиск оборудования». В параметрах поиска следует выбрать искомое устройство и подождать, пока оно отобразится в списке. Затем это окно можно закрыть и вернуться к предыдущему. Там следует нажать кнопку «Проверка связи», и если установка завершена правильно, то в строке «Результат» отобразятся параметры подключённого оборудования.

Теперь следует настроить верное отображение устройства в 1С. Для этого заходим в раздел «Подключение и настройка торгового оборудования». Там следует выбрать пункт «АТОЛ», а в пункте «Порт» указать «COM1» (если COM-портов несколько и среди них присутствуют реальные, выбираем необходимый виртуальный, который создавался с помощью эмуляции).

Для Win2000 — Windows 10 (2019) (Server, x86, x64). Последняя версия: 2.7.3 build 1108. 8 ноября 2019.

Бесплатное обновление для COM Port Data Emulator (начиная с версии 2.7.0 до последней версии 2.7.3 build 1108. 8 ноября 2019.)

Скачайте файл и замените файлы в папке с программой новыми файлами из архива.

Замечание! Нет необходимости скачивать это обновление, если вы скачаете полный пакет установки.

ПРОБЛЕМЫ СО СКАЧИВАНИЕМ ИЛИ ИНСТАЛЛЯЦИЕЙ?

Если Вы столкнулись с какими-либо проблемами при скачивании или инсталляции, пожалуйста, свяжитесь со службой технической поддержки AGG Software. Подробнее.

Вас могут заинтересовать:

Advanced Serial Port Monitor

Программа, которая, пригодится Вам как для наблюдения за передачей данных другими приложениями, так и непосредственно, для отправки и приема данных через последовательный порт (RS232) Вашего компьютера. Программа позволяет различными способами сохранять данные в файл и визуализировать данные на экране монитора. Она может пригодиться как начинающим, так и профессионалам. подробнее

Advanced Serial Data Logger

Advanced Serial Data Logger обрабатывает данные, полученные через RS232 порт, COM порт или через RS485 при наличии аппаратного конвертора. Программа записывает данные в файл Excel, Access, базу данных и т.п. подробнее

Advanced TCP/IP Data Logger

Advanced TCP/IP Data Logger позволяет захватывать данные, передаваемые по протоколу TCP/IP или UDP и сохранять их в файл, а также передавать в другие приложения Excel, Access или базы данных. Программа в реальном времени собирает данные от любого устройства или инструмента и может использоваться как при работе в локальной сети, так и при работе в Интернет. подробнее

Serial Printer Logger

Serial Printer Logger может заменить ваш старый матричный принтер и собирать данные в реальном времени в текстовые, двоичные лог-файлы, а также непосредственно создавать файлы документов Adobe PDF или MS Word. Эта замена позволит сэкономить ваши деньги, которые вы бы потратили на бумагу, расходные материалы и техническую поддержку устаревшего устройства. подробнее

Advanced NMEA Data Logger

Advanced NMEA Data Logger захватывает данные с последовательного порта или сетевого интерфейса, обрабатывает их в соответствии с вашими нуждами, затем выделяет пакеты данных и трансформирует их в переменных, которые далее передаются в другие приложения Windows — путем отправки нажатия клавиш, или экспортируются через DDE (Dynamic Data Exchange), ODBC, OLE. подробнее

Виртуальный com-порт может использоваться для того, чтобы подключить несколько приложений к одному и тому же порту. Создаются копии этого порта, и приложения могут работать с виртуальными портами, которые могут посылать данные на реальный порт и присоединенному устройство.

Как создать виртуальный com порт

Вам понадобится

  • — компьютер с выходом в интернет
  • — браузер
  • — навыки системного администрирования
  • — Advanced Virtual COM Port
  • — USB Serial Converter или Virtual Null Mode

Инструкция

Скачайте и установите программу Advanced Virtual COM Port. Для этого откройте браузер и перейдите по ссылке http://www.advancedvirtualcomport.com/files/AdvancedVirtualComPort.zip. Данная программа включает сетевые и локальные функции виртуального порта COM. Она может создать виртуальный порт и присоединиться к нему через виртуальный кабель модема, через сеть или интернет. Эти порты, созданные в программе, выглядят так же, как и реальные. Работают они аналогично. Запустите программу, выполните процедуру создания порта: нажмите кнопку «создать порт», выберите источник создаваемого порта. Следуйте инструкциям программы. Далее зайдите в «Панель управления», выберите «Диспетчер устройств», там проследите появление нового порта в списке портов.

Скачайте драйвер для виртуального порта, чтобы поставить виртуальный com-порт на компьютер, с сайта http://com0com.sourceforge.net/. Распакуйте архив с драйвером в папку, подключите кабель с разъемом USB к компьютеру. Другой конец кабеля, там, где два разъема DB-9, никуда не подключайте. Далее автоматически установится оборудование. Выберите опцию «провести поиск подходящего драйвера для устройства», с указанием места его размещения. Далее нажмите кнопку «Обзор» и выберите скачанный драйвер. В следующем окне нажмите кнопку «Готово». После установки USB Serial Converter будет запущен мастер установки последовательного порта. Повторите процедуру установки оборудования с помощью мастера нового оборудования. Перезагрузите компьютер, чтобы сделать виртуальный com порт. Зайдите в «Панель управления», «Система», нажмите «Диспетчер устройств» и проследите появление нового порта.

Скачайте и установите программу Virtual Null Mode. Создание виртуального порта com с помощью этой программы представляет собой достаточно простую процедуру. После установки программы программа предложит создать новое устройство, выберите «Да», далее выберите номера портов, кликните кнопку «ОК» в окне программы и в диалоговом окне. Далее программа установит виртуальные порты на компьютер. Перезагрузите ПК, зайдите в «Диспетчер устройств» и проверьте появление новых портов.

Источники:

  • виртуальный порт usb
  • Запрет использования виртуальных COM-портов в Windows

Войти на сайт

или

Забыли пароль?
Еще не зарегистрированы?

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Обновлено 12.06.2017

Подключаем com порт usb в Windows

Всех приветствую вновь на страницах своего блога и сегодня хочу рассказать, как подключить com порт usb в Windows . Поговорим, что это такое и для чего используется. Я думаю для начинающих сетевых администраторов, да и просто для продвинутых пользователей это будет интересно, для меня в свое время это было просто какой-то магией, позволяющая настраивать серверное оборудование.

Что подключают через com порт

Через com порт ранее подключали модемы, мышки. Сейчас он используется для соединения с источниками бесперебойного питания, для связи с аппаратными средствами разработки встраиваемых вычислительных систем, спутниковыми ресиверами, кассовыми аппаратами, с приборами систем безопасности объектов, а также с многими прочими устройствами.

С помощью COM-порта можно соединить два компьютера, используя так называемый «нуль-модемный кабель» (см. ниже). Использовался со времен MS-DOS для перекачки файлов с одного компьютера на другой, в UNIX для терминального доступа к другой машине, а в Windows (даже современной) — для отладчика уровня ядра.

Но в сетевом мире через com порт подключаются к консольному порту сетевых устройств (коммутаторов, роутеров, таких брендов как Cisco или Juniper)

Какая схема подключения к коммутаторам через последовательный порт. Есть переходники, например от фирмы st-lab На одном конце USB который вы подключаете к компьютеру, а второй это com порт.

Подключаем com порт usb в Windows-2

Далее к ком порту подсоединяется вот такой шнурок, com порт, а с другой стороны LAN RJ45, и вся схема дает нам один большой шнурок USB to LAN.

Подключаем com порт usb в Windows-3

Установка драйверов com порт usb в Windows

К сожалению в Windows подключенные устройства, usb to com не всегда автоматически устанавливаются в системе, и приходится искать для них драйвера. Если вы покупали его сами, то в комплекте шел диск с драйверами, и можно воспользоваться им, если его нет, то смотрим как найти драйвера.

Открываем диспетчер устройств в Windows. Если не знаете как, то нажмите CTR+Pause breake, либо нажмите Win+R и в окне выполнить введите devmgmt.msc. Как видите у меня в разделе Порты (COM и LPT) нашелся на третьем COM порту неизвестный провод, и драйверов для него не нашлось у системы, о чем говорит нам желтый значок.

Подключаем com порт usb в Windows-4

Переходим в свойства данного устройства и выбираем ИД оборудования, у вас будет, что то по типу usbVID_067B&PID_2303&REV_0300, вот его вы копируете и ищите в гугле или яндексе.

Подключаем com порт usb в Windows-5

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

Далее вы уже можете использовать возможности com порта, с помощью таких утилит на подобие Putty, где вы выбираете пункт Serial и указываете нужный порт Com порта, посмотреть его можно в том же диспетчере устройств.

Подключаем com порт usb в Windows-6

Надеюсь вы научились и разобрались как подключать com порт usb в Windows.

Написать эту статью меня сподвигли те сложности, которые пришлось пройти в попытке разобраться, как же именно ядро контроллера STM32F103 работает с драйвером USB, который находится на борту. Имеющиеся туториалы (например, вот или вот) по созданию устройств, в том числе и композитных, в основном сфокусированы на особенностях использования библиотек. Я же хочу рассказать, как оно работает на уровне регистров.

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

И вот на этом месте оказалось, что места, как в ПЗУ, так и в ОЗУ для стандартных библиотек уже не остаётся: библиотеки часто пишутся так, чтобы отлавливать ошибки. Поэтому там, где достаточно присвоить пару заранее рассчитанных значений строго определённым регистрам возникают структуры из нескольких переменных и функции со множеством условных переходов. И те и другие пожирают довольно много памяти. Поверх этого библиотеки от STM сами по себе достаточно сложны по своей структуре. Переменные попрятаны в макросы, которые в свою очередь завёрнуты в функции, вызываемые через указатели. Так что пришлось во всё это влезать и разбираться.

Процесс работы с инициализированным USB довольно прост. Но вот процесс инициализации — это головоломка не для слабых умов. Чтобы понять, что там происходит, мне пришлось нарисовать довольно объёмную блок-схему, которая больше похожа на карту подземелья в D&D, чем на алгоритм. И прежде чем спуститься в это подземелье, нам понадобится следующее снаряжение.

Регистры

Итак, что нам понадобится для того, чтобы разобраться. Вообще, полезно иметь под рукой Reference Manual (DOC Id 13902, глава 22, страницы с 580 по 609). В этом документе содержатся адреса нужных для работы регистров и описание битов в этих регистрах. А также режимов работы этих битов (это важно). Для удобства программирования, я вынес эти адреса в макросы:

Макросы

	//макрос адресации
	#define REG(x)  (*((volatile unsigned int )(x)))
	
	//базовый адрес регистров драйвера
	#define USB_BASE_ADDR   0x40005C00
	//адрес начала области памяти драйвера USB          
	#define USB_PMA_ADDR    0x40006000
	
	//регистры состояния конечных точек
	#define EP0R	REG(USB_BASE_ADDR)
	#define EP1R	REG(0x40005C04)
	#define EP2R	REG(0x40005C08)
	#define EP3R	REG(0x40005C0C)
	#define EP4R	REG(0x40005C10)
	#define EP5R	REG(0x40005C14)
	#define EP6R	REG(0x40005C18)
	#define EP7R	REG(0x40005C1C)
	#define ENDPOINT(bEpNum)        REG(USB_BASE_ADDR + (bEpNum)*4)
	#define PMA_BUF(INum)        REG(USB_PMA_ADDR + (INum)4) 
	#define PMA_SBUF(SINum)        (((volatile unsigned short int *)(USB_PMA_ADDR + (SINum)*2)))
	
	//остальные регистры
	#define CNTR	REG(USB_BASE_ADDR + 0x40)   
	#define ISTR	REG(USB_BASE_ADDR + 0x44)   
	#define DADDR	REG(USB_BASE_ADDR + 0x4C) 
	#define BTABLE	REG(USB_BASE_ADDR + 0x50)

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

  • CNTR — контролирует, какие из событий должны вызвать прерывание и обратить на себя внимание контроллера. Нам понадобятся 0x8000 (данные приняты) и 0x0400 (запрос на перезагрузку драйвера). Также есть события по переполнению буфера приёма (0x4000), отправке устройства в спящий режим (0x0800) и выхода из него (0x1000) и т.д.

  • ISTR — собственно, описание прерывания. Старшие биты (с 15 по 8) — соответствуют регистру CNTR. Младшие 4 указывают номер конечной точки, которая требует внимания и бит номер 4 (0x0010) — это направление: 1 означает, что данные принимаются от хоста (обычно компьютера, но сейчас это умеют и смартфоны) в контроллер. 0 — что хост ждёт данных от нас.

  • DADDR — младшие 7 бит хранят номер, который хост присвоил нашему устройству в текущей сессии. Изначально ноль. Старший бит указывает, что драйвер USB принципиально готов к работе.

  • BTABLE — смещение адреса описания конечных точек. Дело в том, что для работы нам нужно куда-то помещать данные — как принятые, так и те, которые мы будем отправлять. Местом для этого служит внутренняя память драйвера, Packet Memory (PMA). И для разметки этой памяти служит таблица, размещаемая в той же самой памяти начиная с позиции BTABLE. Эта таблица состоит из следующих полей: Адрес буфера отправки, количество байт, отправляемых на данном шаге, адрес буфера приёма, размер буфера приёма (и его заполненность).

  • Наконец, PMA_BUF и PMA_SBUF — та самая внутренняя память драйвера, всего 512 байт. PMA_BUF обращается к ней как к массиву DWORD, а PMA_SBUF обращается к ней как к массиву WORD. Адресация в этой области памяти идёт по словам, так что обратиться к отдельному байту всё равно не получится.

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

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

Запуск USB

Прежде чем начать работу, нам необходимо включить драйвер и подключить соответствующие ноги:

SystemInit();

//Это то, что находится в  файле system_stm32f10x.c стандартной библиотеки.

#include "stm32f10x.h"
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */ 
/* Set HSION bit */ 
RCC->CR |= (uint32_t)0x00000001;
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ 
RCC->CFGR &= (uint32_t)0xF8FF0000;
/* Reset HSEON, CSSON and PLLON bits */ 
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset HSEBYP bit */ 
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ 
RCC->CFGR &= (uint32_t)0xFF80FFFF;
/* Disable all interrupts and clear pending bits  */ 
RCC->CIR = 0x009F0000;
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ 
/* Configure the Flash Latency cycles and enable prefetch buffer */

__IO uint32_t StartUpCounter = 0, HSEStatus = 0;

/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 
/* Enable HSE */ 
RCC->CR |= ((uint32_t)RCC_CR_HSEON); 
//  RCC->CR |= ((uint32_t)RCC_CR_HSION);

/* Wait till HSE is ready and if Time out is reached exit */ 
do { 
HSEStatus = RCC->CR & RCC_CR_HSERDY; 
//    HSEStatus = RCC->CR & RCC_CR_HSIRDY; 
StartUpCounter++; 
} while(((RCC->CR & RCC_CR_HSERDY) == 0) && (StartUpCounter < HSE_STARTUP_TIMEOUT));

if ((RCC->CR & RCC_CR_HSERDY) != RESET) //	  if ((RCC->CR & RCC_CR_HSIRDY) != RESET) 
{ 
//HSEStatus = (uint32_t)0x01;    
/* Enable Prefetch Buffer */
     FLASH->ACR |= FLASH_ACR_PRFTBE;      
/* Flash 2 wait state */
     FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
     FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;       
/* HCLK = SYSCLK */     
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;      
/* PCLK2 = HCLK */     
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
      /* PCLK1 = HCLK */     
	  RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 

    /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
	RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |                                         RCC_CFGR_PLLMULL));     
	RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);   
	//PLLMULL9 - for 8MHz 
	//    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLMULL9);   
	//PLLMULL9 - for 8MHz     
	/* Enable PLL */
	RCC->CR |= RCC_CR_PLLON;      
	/* Wait till PLL is ready */     
	while((RCC->CR & RCC_CR_PLLRDY) == 0)     {     }      /* Select PLL as system clock source */     
	RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));     
	RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;      
	/* Wait till PLL is used as system clock source */     
	while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)     {     } 
	}SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; 
	/* Vector Table Relocation in Internal FLASH. */

USB_Init()

SystemInit();

//Содержимое SystemInit описано выше. 
//Сама функция находится в  файле system_stm32f10x.c стандартной библиотеки.

// Enable USB_DISCONNECT GPIO clock 
RCC->APB2ENR |= RCC_APB2Periph_GPIOF;

// Использование 11 пина как USB pull-up pin 
GPIOF->CRH &= 0xFFFF0FFF; 
GPIOF->CRH |= 0x00007000; 

//general output, open drain, 50MHz
//Конфигурация тактирования 
*(__IO uint32_t *) (0x424200D8) = 0;
//включить тактирование шины USB 
RCC->APB1ENR |=RCC_APB1Periph_USB;
//Приоритет прерывания (низший приоритет из возможных 0xf0, высший 0x10)
NVIC->IP[USB_LP_CAN1_RX0_IRQn] = 0xA0; 
//pending - будем проверять в цикле 
NVIC->ISER[(uint32_t)(USB_LP_CAN1_RX0_IRQn) >> 0x05] = (uint32_t)0x01 << (USB_LP_CAN1_RX0_IRQn & (uint8_t)0x1F);

USB_RESET();

После инициализации и включения тактирования остаётся только выполнить разметку PMA и разрешить USB принимать данные. За это отвечает функция USB_RESET():

USB_RESET()

#define EP0RX_OFFSET 	0x80
#define EP0TX_OFFSET 	0x40
#define EP1TX_OFFSET 	0xC0
#define EP2TX_OFFSET 	0x100
#define EP3RX_OFFSET 	0x110

BTABLE = 0;	// Адрес таблицы дискрипторов внутри PMA

//EP 0 - нулевая конечная точка 
	// ADDR_TX 
	PMA_BUF(0) = EP0TX_OFFSET; 
	// COUNT_TX = 0 нужно заполнять перед отправкой данных 
	PMA_BUF(1) = 0; 
	// ADDR_RX 
	PMA_BUF(2) = EP0RX_OFFSET; 
	// Указываем размер буфера приема 64 байта, BL_size = 1 (32 байта на блок), 2 штуки 
	PMA_BUF(3) = 0x8400;
	EP0R = ((EP0R ^ 0x3020) & 0x3030) | 0x0200; 

//EP 1 CDC TX 
	PMA_BUF(4) = EP1TX_OFFSET; 
	PMA_BUF(5) = 0; 
	PMA_BUF(6) = 0; 
	PMA_BUF(7) = 0; 
	ENDPOINT(1) = ((ENDPOINT(1) ^ 0x0020) & 0x3030);

//EP 2 CDC interrupt 
	PMA_BUF(8) = EP2TX_OFFSET; 
	PMA_BUF(9) = 0; 
	PMA_BUF(10) = 0; 
	PMA_BUF(11) = 0; 
	ENDPOINT(2) = ((ENDPOINT(2) ^ 0x0020) & 0x3030)|0x0600;

//EP 3 CDC RX 
	PMA_BUF(12) = 0; 
	PMA_BUF(13) = 0; 
	PMA_BUF(14) = EP3RX_OFFSET; 
	PMA_BUF(15) = 0x8400; 
	ENDPOINT(3) = ((ENDPOINT(3) ^ 0x3000) & 0x3030);

//Данные глобальные переменные нужны для формирования ответов на запросы хоста:
USB_Feature = 0xC0;
USB_Configuration = 0;
USB_Interface = 0;

//Обнуляем прерывание
ISTR = 0;
// Включаем модуль USB, адрес устройства 0
DADDR = 0x80;
// Дополнительно сбрасываем флаги прерываний(событий) USB
ISTR &= ~ISTR_RESET;

Здесь нам потребуются пояснения, связанные с особенностями работы регистров конечных точек. Разные биты в них отвечают не только за разные режимы работы, но и по-разному реагируют на попытки записать в них 0 или 1. Так что присаживайтесь поудобнее.

  • Старший бит, 0x8000, CTR_RX отвечает за приём и поднимается тогда, когда в область PMA для конечной точки пришли данные от хоста. Поднять его со стороны контроллера нельзя, только сбросить в 0.

  • Бит 0x4000, DTOG_RX обозначает чётность принятого пакета данных. При записи в него 1 меняет своё значение. В случае работы с COM-портом он нам не понадобится.

  • Биты 0x2000 и 0x1000 — STAT_RX — состояние приёмника конечной точки. Может принимать значения 0x3000 — готова к приёму, 0x2000 — данные обрабатываются и точка занята, 0x1000 — ошибка и 0x0000 — выключено. Эти биты переключаются так же, как и DTOG_RX. Именно поэтому вместо EP0R = 0x3020 приходится городить EP0R = ((EP0R ^ 0x3020) & 0x3030)

  • Бит 0x0800, SETUP — указывает на тип принятых данных, т.е. являются ли эти данные специфической командой.

  • Бит 0x0400 и 0x0200 — EP_TYPE — тип конечной точки: 0x0000 — данные (BULK), 0x0100 — контрольная (CONTROL), 0x0400 — асинхронная (ISO) и 0x0600 — прерывание для хоста (INTERRUPT).

  • Бит 0x0100, EP_KIND — дополнительный параметр. Для конечных точек типа BULK этот бит включает двойную буферизацию, режим, при котором области PMA для приёма и передачи данных меняются ролями после каждого принятого пакета. Это нужно для ускорения приёма-передачи. Для конечной точки типа CONTROL данный бит включает режим STATUS_OUT. Бывает нужен при завершении ответа, но в нашем случае работает и без него.

  • Биты с 0x0080 по 0x0010 (CTR_TX, DTOG_TX, STAT_TX) работают так же, как и старшие 4, только отвечают не за приём, а за передачу данных хосту

  • младшие 4 бита хранят номер конечной точки. Нам потребуется их заполнить когда устройство получит свой номер от хоста.

Как видно, в проекте у нас 4 конечных точки: контрольная нулевая, одна на передачу (первая), одна для прерываний (вторая) и одна на приём (третья). Таблицу разметки мы расположили в начале PMA. В нулевой ячейке таблицы записываем позицию начальной ячейки отправки для контрольной точки. Затем — сколько байт нужно отправить. Затем — начальная ячейка приёма данных. Последняя ячейка содержит информацию о количестве места и количестве принятых данных: старший бит (0x8000) указывает, что блоки имеют размер 32 байта (если 0 — то 2 байта на блок), затем биты с 0x4000 по 0x0400 — количество этих блоков (минус 1). Максимальный общий размер — 512 байт. Оставшиеся 10 бит будут хранить число принятых конечной точкой байт.

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

Дескрипторы

Следующий важный момент, без которого мы не сможем настроить наше устройство — дескрипторы. Это заранее заготовленные и отформатированные ответы на запросы хоста «что ты такое» и «как ты работаешь».

Дескриптор устройства

const char DeviceDiscriptor[] = { 
0x12,   		// bLength / 
0x01,     		// bDescriptorType / 
0x00, 0x02,		// bcdUSB = 2.00 / 

// класс и протокол перечислены на сайте https://www.usb.org/defined-class-codes
0x02, 	// bDeviceClass: CDC / 
0x00,   // bDeviceSubClass / 
0x00,   // bDeviceProtocol / 
0x40,   // bMaxPacketSize0 / 

//STMicroelectronics  СDC
// данные с сайта https://www.the-sz.com/products/usbid/index.php?v=0x04830x83, 
0x04,   		// idVendor = 0x0483 / 
0x40, 0x57,		// idProduct = 0x7540 / 
0x00, 0x02,		// bcdDevice = 2.00 / 1,              

// Index of string descriptor describing manufacturer / 
2,              // Index of string descriptor describing product / 
3,              // Index of string descriptor describing the device's serial number / 
0x01    		// bNumConfigurations / 
};

Дескриптор конфигурации

 const char ConfigDescriptor[] = { 
//Configuration Descriptor 
0x09,   // bLength: Configuration Descriptor size 
0x02,	// bDescriptorType: Configuration 
67,		// wTotalLength:no of returned bytes 
0x00, 0x02,   // bNumInterfaces: 2 interface 
0x01,   // bConfigurationValue: Configuration value 
0x00,   // iConfiguration: Index of string descriptor describing the configuration 
0xC0,   // bmAttributes: self powered 
0x32,   // MaxPower 0 mA 
//Interface Descriptor 
0x09,   // bLength: Interface Descriptor size 
0x04,	// bDescriptorType: Interface 
// Interface descriptor type 
0x00,   // bInterfaceNumber: Number of Interface 
0x00,   // bAlternateSetting: Alternate setting 
0x01,   // bNumEndpoints: One endpoints used 
0x02,   // bInterfaceClass: Communication Interface Class 
0x02,   // bInterfaceSubClass: Abstract Control Model 
0x01,   // bInterfaceProtocol: Common AT commands 
0x00,   // iInterface: 
//Header Functional Descriptor 
0x05,   // bLength: Endpoint Descriptor size 
0x24,   // bDescriptorType: CS_INTERFACE 
0x00,   // bDescriptorSubtype: Header Func Desc 
0x10,   // bcdCDC: spec release number 
0x01,	//Call Management Functional Descriptor 
0x05,   // bFunctionLength 
0x24,   // bDescriptorType: CS_INTERFACE 
0x01,   // bDescriptorSubtype: Call Management Func Desc 
0x00,   // bmCapabilities: D0+D1 
0x01,   // bDataInterface: 1 
//ACM Functional Descriptor 
0x04,   // bFunctionLength 
0x24,   // bDescriptorType: CS_INTERFACE 
0x02,   // bDescriptorSubtype: Abstract Control Management desc 
0x02,   // bmCapabilities 
//Union Functional Descriptor 
0x05,   // bFunctionLength 
0x24,   // bDescriptorType: CS_INTERFACE 
0x06,   // bDescriptorSubtype: Union func desc 
0x00,   // bMasterInterface: Communication class interface 
0x01,   // bSlaveInterface0: Data Class Interface 
//Endpoint 2 Descriptor 
0x07,   // bLength: Endpoint Descriptor size 
0x05,   // bDescriptorType: Endpoint 
0x82,   // bEndpointAddress: (IN2) 
0x03,   // bmAttributes: Interrupt 
8,   	// wMaxPacketSize: 
0x00, 0xFF,   // bInterval: 
//Data class interface descriptor 
0x09,   // bLength: Endpoint Descriptor size 
0x04,  // bDescriptorType: 
0x01,   // bInterfaceNumber: Number of Interface 
0x00,   // bAlternateSetting: Alternate setting 
0x02,   // bNumEndpoints: Two endpoints used 
0x0A,   // bInterfaceClass: CDC 
0x00,   // bInterfaceSubClass: 
0x00,   // bInterfaceProtocol: 
0x00,   // iInterface: 
//Endpoint 3 Descriptor 
0x07,   // bLength: Endpoint Descriptor size 
0x05,   // bDescriptorType: Endpoint 
0x03,   // bEndpointAddress: (OUT3) 
0x02,   // bmAttributes: Bulk 
64,		// wMaxPacketSize: 0x00, 
0x00,   // bInterval: ignore for Bulk transfer 
//Endpoint 1 Descriptor 
0x07,   // bLength: Endpoint Descriptor size 
0x05,   // bDescriptorType: Endpoint 
0x81,   // bEndpointAddress: (IN1) 
0x02,   // bmAttributes: Bulk 
64,		// wMaxPacketSize: 
0x00, 0x00	// bInterval  
};

Дескрипторы обычно довольно подробно описываются во многих туториалах, да и в библиотеках и примерах их найти несложно. Так что эту часть объяснения оставлю коллегам. В частности, USB in a nutshell или USB made simple. Всё-таки моя статья скорее о том, как это добро правильнее передать чтобы оно было воспринято.

А не как тут

При подключении устройство никак не определялось до конца. Вроде COM, но какой-то скомканный. Оказалось, компилятор не смог один из дескрипторов расположить в памяти единым куском. А читаю то я его «от забора и до обеда»! Так что компьютер, вместо того чтобы получить на свой запрос «как ты работаешь», вместо заранее заготовленного ответа «я делаю вот это и вот это» получал ответ «через Ж…» и прекращал дальнейшее общение с устройством. Пришлось этот дескриптор разбить на несколько частей по 16 байт и слать их одну за другой. Заработало.

Потом оказалось, что этот дескриптор я переобъявлял в другом файле, и от костыля удалось избавиться. Теперь каждый раз перепроверяю свои дефайны.

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

Собственно, переменные

typedef enum _CONTROL_STATE{
	WAIT_SETUP, SETTING_UP, IN_DATA, OUT_DATA, LAST_IN_DATA, LAST_OUT_DATA, WAIT_STATUS_IN, WAIT_STATUS_OUT, STALLED, PAUSE
} CONTROL_STATE; 

//массивы и переменные, через которые мы будем работать 
unsigned char USB_Buff1[64]; 
unsigned char USB_COM_TX_Buff1[64]; 
uint16_t USB_RX_Start_pointer=0; 
uint16_t USB_Recieved_bytes=0; 
uint16_t USB_Bytes_to_send_left = 0;

//Эта переменная нужна нам для общения с внешним миром 
uint8_t USB_Function_flags=0; 
//1 - запрос оправки данных на хост(IN) 
//2 - запрос получения данных от хоста (OUT) 
//4 - есть, что обработать 
//8 - Данные от хоста в EP3 обработаны

//переменные для хранения команд, полученных контрольной точкой  
uint16_t USB_Command; 
uint16_t USB_wValue; 
uint16_t USB_wLength;
//Стадия процесса обработки команды от хоста 
CONTROL_STATE USB_state_flag = WAIT_SETUP;
//параметры контрольной конечной точки и конфигурация устройства 
uint8_t USB_DADDR = 0; 
uint8_t USB_Feature; 
uint8_t USB_Configuration; 
uint8_t USB_Interface; 
uint8_t EPindex; 
uint16_t BKIstr=0;
uint16_t SaveTState;

Чтение и запись массивов данных в PMA

//P1 - указатель на первый элемент массива, откуда читаем
//P2 - позиция в массиве PMA, с которой записываем данные
//N - количество байт
//max - размер области PMA размеченный для данной операции
void TO_WRITE_PMA(uint16_t *P1, uint32_t P2, uint16_t N, uint16_t max){
	uint8_t i;
	N = (N > max)? max : N; 
	for(i=0; i<N; i+=2){ 
		PMA_SBUF(P2+i) = *P1;
		P1++; 
	}
}

void TO_READ_PMA(uint32_t P2, uint16_t *P1, uint16_t N, uint16_t max){
	uint8_t i;
	N = (N > max)? max : N; 
	for(i=0; i<N; i+=2){ 
		*P1 = PMA_SBUF(P2+i); 
		P1++; 
	}
}

//генерация текстовых дескрипторов.
//строка Str[] должна оканчиваться пустым символом
//EP - целевая конечная точка
void USB_Message (char Str[], uint8_t EP){
	uint16_t b1 = PMA_BUF(EP * 4);
	uint8_t i;
	//не более 31 символа, т.к. всего у нас 64 байта,
	//из которых 2 - это заголовок 
	//(младший байт - количество, старший - тип дескриптора),
	//а остальные - текст в юникоде 
	for (i = 0; (Str[i] && i < 31); i++) { 
		b1 += 2; 
		PMA_SBUF(b1) = Str[i]; 
	}
	i =i * 2 + 2 b1 = PMA_BUF(EP * 4); 
	PMA_SBUF(b1) = i | 0x0300; 
	//N bytes, 3 - string descriptor 
	PMA_BUF(EP * 4+1) = i;
}

Наконец, входим в подземелье

Во-первых, прерывание. Тут всё просто: определяем причину и выбираем обработчик. Причин у нас две — данные приняты и перезагрузить драйвер (см регистр CNTR выше)

Прерывание

void USB_LP_CAN1_RX0_IRQHandler(){
	BKIstr = ISTR;
	if(BKIstr & ISTR_CTR){
		CTR_LP_CTRX();
	}  
	if(BKIstr & ISTR_RESET){
		USB_RESET();
	}
}

Мы уже знакомы с USB_RESET(), так что не будем туда заглядывать. Настоящее приключение ждёт нас в CTR_LP_CTRX().

Код CTR_LP_CTRX()

#define ISTR_CTR		0x8000
#define ISTR_EP_ID	0x000F
#define EP_CTR_TX		0x0080
#define EP_CTR_RX		0x8000
#define USB_EP0_MAX_PACKET_SIZE	0x0040

void CTR_LP_CTRX() {
uint16_t TempEP;
uint8_t Related_Endpoint, Reserved;
uint16_t USB_wIndex;

while (((BKIstr = ISTR) & ISTR_CTR)) {
    // extract highest priority endpoint number 
    EPindex = (uint8_t)(BKIstr & ISTR_EP_ID);

  if (EPindex == 1 && (EP1R & EP_CTR_TX)){ //CDC Transmit
      EP1R &= 0x8F0F;
      USB_Function_flags |= 1;
	} else if (EPindex == 3 && (EP3R & EP_CTR_RX)){ //CDC Receive
			USB_Function_flags &= 0xEF;
			USB_RX_Start_pointer = 0;

			//you can save up current time
    	//in case you have a limited timeframe for processing this data
    	EP3R = (EP3R ^ 0x2000) & 0x3F8F;
    	USB_Recieved_bytes = (PMA_BUF(15)&0x3FF);
    	TO_READ_PMA(EP3RX_OFFSET, USB_Buff1, 64,64);
			USB_Function_flags |= 2;

        // Decode and service non control endpoints interrupt 
        // process related endpoint register 

    } else if(EPindex == 0){

        // Decode and service control endpoint interrupt 
        // calling related service routine 
        // (Setup0_Process, In0_Process, Out0_Process) 

        // save RX & TX status 
        // and set both to NAK 

  	    SaveTState = EP0R & 0x3030;

  	    EP0R = (EP0R^0x2020)&0xBFBF;
        // DIR bit = origin of the interrupt 
        if (BKIstr & ISTR_DIR) {
            // DIR = 1 */
            // DIR = 1 & CTR_RX       => SETUP or OUT int 
            // DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending 
            	EP0R &=0x0F8F;// SETUP bit kept frozen while CTR_RX = 1 
            	USB_state_flag = STALLED;
            if (EP0R & EP_SETUP) {

              USB_Command = PMA_SBUF(EP0RX_OFFSET);
              USB_wValue  = PMA_SBUF(EP0RX_OFFSET+2);
              USB_wIndex  = PMA_SBUF(EP0RX_OFFSET+4);
              USB_wLength = PMA_SBUF(EP0RX_OFFSET+6);
              if (USB_wLength == 0)
              {
                // Setup with no data stage 

            	  USB_state_flag = WAIT_STATUS_IN;// After no data stage SETUP
            	  PMA_BUF(1) = 0;
            	  if (USB_Command == 0x0900){    // SET_CONFIGURATION
            			  USB_Configuration = USB_wValue;
            	  } else if (USB_Command == 0x0500){//SET ADDRESS
            		  USB_DADDR = USB_wValue | DADDR_EF;
            	  } else if ((USB_Command &0xFDFF) == 0x0100){//SET FEATURE for Device 0300, CLEAR FEATURE for Device 0100

            	  } else if (USB_Command == 0x0B01 && (USB_Configuration) && ((USB_wIndex & 0xFF) <= 1)){//SET INTERFACE
            			  USB_Interface = USB_wIndex;
            	  } else if (USB_Command == 0x0102){
            		  //EndPoint Clear Feature
            		  Related_Endpoint = USB_wIndex & 0x7F;
            	      if ((USB_wValue == 0)//ENDPOINT_STALL)
            	          && (USB_wIndex > 0x100) && USB_Configuration)
            	      {
            		        //Get Status of endpoint & stall the request if the related_ENdpoint
            		        is Disabled
            	    	  TempEP = ENDPOINT(Related_Endpoint);
            	    	  if (USB_wIndex & 0x80) {
            	    		  // IN endpoint 
            			      if ((TempEP&0x0030)==0x0010)
            			      {
            			          ENDPOINT(Related_Endpoint) = (TempEP ^ 0x0030)&0x8FFF;
            			      }
            		      } else {
            		    	  // OUT endpoint
            		    	  if ((TempEP&0x3000)==0x1000)
            		    	  {
            		    		  if (Related_Endpoint == 0)
            			          {
            			            // After clear the STALL, enable the default endpoint receiver 
            			        	  PMA_BUF(3) = 0x8400;
            			        	  EP0R = (EP0R ^ 0x3000)&0xBF8F;
            			          }
            			          else
            			          {
            			            ENDPOINT(Related_Endpoint) = (TempEP ^ 0x3000)&0xFF8F;
            			          }
            		    	  }
            		      }
            	      }
            	  } else if (USB_Command == 0x0302){
									// get Status of endpoint & stall the request if the related_ENdpoint is Disabled
            	      Related_Endpoint = USB_wIndex & 0x7F;
            	      if ((USB_wValue==0) && USB_Configuration){
            	    	  TempEP = ENDPOINT(Related_Endpoint);
            	    	  if (USB_wIndex & 0x80) {
            				    
            				    if(TempEP&0x0030){
            				    	ENDPOINT(Related_Endpoint) = (TempEP ^ 0x0010)&0x8FBF;
            				    }
            			  } else {
            				    if(TempEP&0x3000){
            				    	ENDPOINT(Related_Endpoint) = (TempEP ^ 0x1000)&0xBF8F;
            				    }
            			  }
            	      }

            	  } else if ((USB_Command & 0xDDFF) == 0x0021){
                  //SET_COMM_FEATURE 0221
                  //SET_CONTROL_LINE_STATE 2221
                  //SET Linecoding 2021
         
                  USB_Message("Device connectedr",1);
            		  USB_main_COM_react();

            	  } else {
            		  USB_state_flag = STALLED;
            	  }

            	  SaveTState |= 0x0030;
              } else {
                // Setup with data stage 
            	  USB_state_flag =  LAST_IN_DATA;
            	  PMA_BUF(1) = USB_wLength;
            		if (USB_Command == 0x0680){//GET DESCRIPTOR
            		      if (USB_wValue == 0x0100){
            		    	  TO_WRITE_PMA(DeviceDiscriptor,EP0TX_OFFSET,0x12,USB_EP0_MAX_PACKET_SIZE);
            		    	  PMA_BUF(1)= 0x12;
            		      } else if (USB_wValue == 0x0200){
            		    	  TO_WRITE_PMA(ConfigDescriptor,EP0TX_OFFSET,64,USB_EP0_MAX_PACKET_SIZE);

            		    	  if (USB_wLength>9){
                          
            		    		  PMA_BUF(1)= USB_EP0_MAX_PACKET_SIZE;
            		    		  USB_state_flag = IN_DATA;
            		    	  }
							  
            		      } else if (USB_wValue == 0x0300){
            		    	  PMA_SBUF(EP0TX_OFFSET) = 0x0304; // 3 - string descriptor, N=4
            		    	  PMA_SBUF(EP0TX_OFFSET + 2) = 0x0409;//Lang ID - US
            		    	  PMA_BUF(1)= 4;
            		      } else if (USB_wValue == 0x0301){
            		    	  USB_Message("VENDOR",0);
            		      } else if (USB_wValue == 0x0302){
            		    	  USB_Message("Device name",0);
            		      } else if (USB_wValue == 0x0303){
            		    	  uint32_t buf1 = *(__IO uint32_t*)(0x1FFFF7F0);//get unique chip ID
            		    	  for (Reserved = 2; Reserved<24; Reserved+=2){
            		    		  PMA_SBUF(EP0TX_OFFSET + Reserved)= (buf1 & 0x7) + '0';
            		    		  buf1 >>= 3;
            		    	  }
            		    	  PMA_SBUF(EP0TX_OFFSET)= 0x0318;
            		    	  PMA_BUF(1)=24;
            		      }// End of GET_DESCRIPTOR
            		} else if ((USB_Command&0xFFFE) == 0x0080){// GET STATUS for Device, GET STATUS for Interface
            			Reserved = 0;
            			if (USB_Command == 0x0080){
            			    if (USB_Feature & 0x20){// is Remote Wakeup enabled?
            			    	Reserved |= 2;
            			    }
            			    if (USB_Feature & 0x40){// is Bus-powered?
            			    	Reserved |= 1;
            			    }
            			}
            			PMA_SBUF(EP0TX_OFFSET) = Reserved; 
            		} else if (USB_Command == 0x0082){// GET STATUS for EndPoint
            			Related_Endpoint = USB_wIndex & 0x7F;
            			PMA_SBUF(EP0TX_OFFSET) =0;
            			TempEP = ENDPOINT(Related_Endpoint);
           				if (USB_wIndex & 0x80) {
            					// get Status of endpoint & stall the request if the related_ENdpoint is Disabled
            					if(TempEP&0x0030 == 0x0010){
            						PMA_SBUF(EP0TX_OFFSET) =1;// IN Endpoint stalled 
            					}
            				} else {
            					if(TempEP&0x3000 == 0x1000){
            						PMA_SBUF(EP0TX_OFFSET) =1;//OUT Endpoint stalled 
            					}
            				}

            		} else if (USB_Command == 0x0880){//GET CONFIGURATION
            			PMA_SBUF(EP0TX_OFFSET) = USB_Configuration;

            		} else if ((USB_Command & 0xFE7F) == 0x2021){
                  //Get (21A1)/set (20A1) Line Coding
            			PMA_BUF(EP0TX_OFFSET) = 9600;//baudrate
            			PMA_SBUF(EP0TX_OFFSET+4) = 0;//parity*256+format
            			PMA_SBUF(EP0TX_OFFSET+6) = 8;//datatype
            		} else {
            			USB_state_flag = STALLED;
            		}
            	    SaveTState = (0x3030);
               }
            }
        } else {
            // DIR = 0 
            // DIR = 0      => IN  int 
            // DIR = 0 implies that (EP_CTR_TX = 1) always  
        	EP0R &=0x8F0F;

        	if (USB_state_flag == IN_DATA){
            //last 3 bytes of Config Descriptor
            //no need to use procedure as there is only 2 assignments
		    		PMA_SBUF(EP0TX_OFFSET) = 0x0040;
		    		PMA_SBUF(EP0TX_OFFSET + 2) = 0;
		    		USB_state_flag =  LAST_IN_DATA;
		    		PMA_BUF(1)= 3;
		    		SaveTState = (0x3030);
        	} else if (USB_state_flag == LAST_IN_DATA){
        		USB_state_flag = WAIT_STATUS_OUT;
      			SaveTState = (0x3010);
        	} else {
        		if (USB_DADDR){//SetDeviceAddress
        			for (Reserved = 0; Reserved < EP_NUM; Reserved++) {
        				ENDPOINT(Reserved) = (ENDPOINT(Reserved) & 0x8F80) | Reserved ;
        			}
        			DADDR = USB_DADDR; // set device address and enable device function
        			USB_DADDR = 0;
        		}
        		USB_state_flag = STALLED;
        	}

        }
        PMA_BUF(3) = 0x8400;
       
        if (USB_state_flag == STALLED) SaveTState = 0x1010;

        EP0R = (EP0R^(SaveTState))&0xBFBF;
        return;
    }

  }
}

А теперь я расскажу, что тут происходит. И это именно то, ради чего вся эта статья писалась и ради чего вы её сейчас читаете.

Вначале мы попадаем в цикл, задача которого — обработать все отдельные элементы прерывания по ISTR_CTR (он же 0x8000 — приём данных).

Первое, что мы тут делаем, это определяем, какую именно конечную точку обрабатываем и обрабатываем приём или передачу. Номер конечной точки узнаём из прерывания. Это младшие 4 бита регистра ISTR. Приём или передача регулируются 5 битом (0x0010).

Если у нас актуальная конечная точка номер 1, и бит EP_CTR_TX (0x0080) поднят, хост хочет что-то от нас получить. Однако нам это не важно, так что мы просто опускаем бит CTR_TX (EP1R &= 0x8F0F), и, возможно, что-то делаем. Тут важно отметить, что если мы действительно хотим сформировать и отправить ответ, то нам нужно сначала перевести конечную точку в режим NAK, то есть осуществить операцию EP1R = (EP1R ^ 0x0020) & 0x8F3F, затем записать данные в PMA по адресу EP1TX_OFFSET (хранится в PMA_BUF(4)), затем записать в PMA_BUF(5) количество этих байт, и, наконец, перевести конечную точку в режим «готово» командой EP1R = (EP1R ^ 0x0030) & 0x8FBF

Однако мы вызываем этот процесс из других частей программы, то есть когда именно у нас есть, что отправить. Для этого служит следующая процедура (данные для отправки записаны ранее в рабочий массив USB_COM_TX_Buff1, а их количество хранится в переменной USB_Bytes_to_send_left)

Чтобы отправить данные хосту

Поместить данные (пакет не больше чем USB_EP1_MAX_PACKET_SIZE_TX) в рабочий буфер USB_COM_TX_Buff1,

записать в переменную USB_Bytes_to_send_left количество отправляемых байт в текущем пакете

Вызвать процедуру

#define USB_EP1_MAX_PACKET_SIZE_TX	0x40

//фактическая отправка данных хосту
//данные и их количество записаны в USB_COM_TX_Buff1
//и в USB_Bytes_to_send_left соответственно.
void USB_main_COM_react(){

	if (USB_Bytes_to_send_left){
		//send pack back to the Host
		USB_Function_flags &= 0xFE;
		TO_WRITE_PMA(USB_COM_TX_Buff1 ,EP1TX_OFFSET, 64, USB_EP1_MAX_PACKET_SIZE_TX);
		PMA_BUF(5) = USB_Bytes_to_send_left;
		EP1R = (EP1R^0x0030)&0x8FBF;
		USB_Bytes_to_send_left = 0;

		uint32_t i = 5000;
		while (((EP1R & 0x80) == 0) && (i)) {i--;}
  }
}

Теперь перейдём к обработчику конечной точки номер 3. Она служит для приёма данных. Итак, актуальная конечная точка номер 3 и её бит EP_CTR_RX (0x8000) поднят. Мы опускаем этот бит и одновременно переводим конечную точку в режим ожидания: EP3R = (EP3R ^ 0x2000) & 0x3F8F. Также можно помахать флагами для внешних частей общей программы, но главное, что нас сейчас интересует — это количество принятых байт. Эта информация находится в младших 10 битах ячейки (PMA_BUF(15)&0x3FF). Далее мы перекладываем данные из PMA в рабочий массив и их как-то обрабатываем.

Но это не всё. Когда мы закончим обработку этих данных, нам необходимо перевести конечную точку в состояние «готова к приёму». Это нужно сделать обязательно, иначе, по прошествии некоторого времени хост решит, что наше устройство зависло. Делается это очень просто: EP3R = (EP3R^0x3000)&0xBF8F. Также можно сбросить количество принятых байт в ноль, как это делалось в процедуре USB_RESET: PMA_BUF(15) = 0x8400.

Обработка полученных данных

Данные лежат в массиве USB_Buff1

их количество записано в переменной USB_Recieved_bytes

после обработки выполнить этот код:

PMA_BUF(15) = 0x8400;
EP3R = (EP3R^0x3000)&0xBF8F;

Наконец, самое сложное

Контрольная конечная точка, номер 0.

Помимо простых запросов IN и OUT (EP_CTR_RX и EP_CTR_TX соответственно), есть ещё запрос SETUP (бит 0x0800 в регистре конечной точки EP0R). Принципиально у нас два возможных сценария развития событий — когда команда предполагает ответ и когда не предполагает. Разберём их на примере команды запроса дескриптора конфигурации (как наиболее сложный случай), и на примере назначения адреса устройства.

Танец с бубном номер 1. Отправка дескриптора.

Шаг 1. Из прерывания мы вошли в процедуру и в цикл внутри этой процедуры. Выяснили, что у нас 0 конечная точка. На всякий случай сохраняем состояние приёма и передачи (SaveTState = EP0R & 0x3030), а затем переводим нулевую конечную точку в состояние NAK (обработка данных) и по каналу приёма, и по каналу передачи. Так у нас будет время сформировать ответ хосту.

На этом этапе направление передачи (ISTR_DIR) должно быть OUT (бит поднят), Бит EP_SETUP поднят. Бит EP_CTR_RX тоже поднят(его опускаем).

Копируем данные из области PMA, размеченной для приёма в рабочие переменные. Это будет команда USB_Command = PMA_SBUF(EP0RX_OFFSET);
параметр USB_wValue = PMA_SBUF(EP0RX_OFFSET+2);
индекс USB_wIndex = PMA_SBUF(EP0RX_OFFSET+4);
и длина требуемого ответа USB_wLength = PMA_SBUF(EP0RX_OFFSET+6);

Структура команды следующая:

  • верхние 8 бит (0x8000 … 0x0100) — собственно требуемая операция,

  • 7 бит (0x0080) — направление, если поднят, то хост ждёт от нас ответа

  • 5 бит (0x0020) — указывает на то, что запрос специфичен для данного класса устройств

  • младшие 4 бита — указывают на то, к какому слою USB запрос относится — к устройству, интерфейсу или конечной точке

Теперь мы определяем, нужно ли отправить ответ. Для этого смотрим на USB_wLength. В нашем примере (отправить дескриптор конфигурации) это не ноль.

Смотрим на команду. Её значение 0x0680 — отправить дескриптор. Смотрим на параметр. Он равен 0x0200 — дескриптор конфигурации.

Записываем начало нашего дескриптора в область PMA, которая размечена для отправки данных хосту от конечной точки 0.

Тут у нас может быть два варианта. Поскольку изначально хост не знает размера этого дескриптора, он запрашивает только первые 9 байт (в которых содержится в том числе и информация об общей длине). Это 6 и 7 байты запроса, мы их храним в переменной USB_wLength. В этом случае мы записываем в ячейку PMA (PMA_BUF(1)), в которой хранится количество байт для отправки, число 9. После чего переходим к шагу 3 (LAST_IN_DATA).

Если же у нас запрос полного дескриптора, то может быть 2 варианта: он меньше чем размер буфера отправки, или больше либо равен ему. Если меньше, то записываем то количество байт, которое есть и также переходим к шагу 3 (LAST_IN_DATA). Если же больше, то записываем в PMA_BUF(1) максимальное количество байт, которые можем отправить одним пакетом, и переходим к шагу 2 (IN_DATA).

Шаг 2. IN_DATA. Открываем нулевую конечную точку для приёма и передачи EP0R = (EP0R^0x3030)&0xBFBF и переходим на следующий виток цикла.

Теперь мы попадаем в цикл со следующими параметрами:
(ISTR_DIR) должно быть IN (бит опущен),
EP_SETUP опущен,
Бит EP_CTR_TX поднят(его опускаем)
Если что-то не так, то переводим нулевую конечную точку в состояние STALL (EP0R = (EP0R^0x1010)&0xBFBF) и выходим из цикла.

Если всё так как надо, переводим нулевую конечную точку в состояние NAK на приём и передачу, доотправляем оставшиеся байты дескриптора. Тут может оказаться, что их ноль, но это нормально. Записываем это число в PMA_BUF(1).

Опять же, в этом шаге мы можем крутиться до тех пор, пока оставшееся количество байт для дескриптора будет строго меньше чем максимальный размер пакета для отправки. Тогда мы можем перейти не снова в начало шага 2(IN_DATA), а к шагу 3 (LAST_IN_DATA).

Шаг 3. LAST_IN_DATA. Открываем нулевую конечную точку для приёма и передачи EP0R = (EP0R^0x3030)&0xBFBF и переходим на следующий виток цикла.

Мы снова попадаем в цикл со следующими параметрами:
ISTR_DIR должно быть IN (бит опущен),
EP_SETUP опущен,
Бит EP_CTR_TX поднят(его опускаем).
Если что-то не так, то переводим нулевую конечную точку в состояние STALL (EP0R = (EP0R^0x1010)&0xBFBF) и выходим из цикла.

Если всё так как надо, переводим нулевую конечную точку в состояние RX_VALID, TX_STALL (EP0R = (EP0R^0x3010)&0xBFBF). И снова попадаем в цикл, но параметры у нас вот такие:
ISTR_DIR должно быть OUT (бит поднят),
EP_SETUP опущен,
Бит EP_CTR_RX тоже поднят(его опускаем).

Переводим нулевую конечную точку в состояние STALL (EP0R = (EP0R^0x1010)&0xBFBF) и выходим из цикла.

Дескриптор отправлен.

Танец с бубном номер 2. Получение адреса устройства.

Шаг 1 начинается так же.

Из прерывания мы вошли в процедуру и в цикл внутри этой процедуры. Выяснили, что у нас 0 конечная точка. На всякий случай сохраняем состояние приёма и передачи (SaveTState = EP0R & 0x3030), а затем переводим нулевую конечную точку в состояние NAK (обработка данных) и по каналу приёма, и по каналу передачи. Так у нас будет время сформировать ответ хосту.

На этом этапе направление передачи (ISTR_DIR) должно быть OUT (бит поднят), Бит EP_SETUP поднят. Бит EP_CTR_RX тоже поднят(его опускаем).

Копируем данные из области PMA, размеченной для приёма в рабочие переменные. Это будет команда USB_Command = PMA_SBUF(EP0RX_OFFSET);
параметр USB_wValue = PMA_SBUF(EP0RX_OFFSET+2);
индекс USB_wIndex = PMA_SBUF(EP0RX_OFFSET+4);
и длина требуемого ответа USB_wLength = PMA_SBUF(EP0RX_OFFSET+6);

Смотрим на USB_wLength. На этот раз она равно нулю. Смотрим на команду. Её значение 0x0500 — назначить адрес. Значение адреса записано в USB_wValue, переписываем её во временную переменную USB_DADDR, заодно поднимая ей старший бит. Можно этого не делать, просто так немного удобнее. Переходим к шагу 2 (WAIT_STATUS_IN).

Шаг 2. WAIT_STATUS_IN. Открываем нулевую конечную точку для приёма и передачи EP0R = (EP0R^0x3030)&0xBFBF и переходим на следующий виток цикла.

Теперь мы попадаем в цикл со следующими параметрами:
(ISTR_DIR) должно быть IN (бит опущен),
EP_SETUP опущен,
Бит EP_CTR_TX поднят(его опускаем)

Тут мы только проверяем, нужно ли нам назначить адрес (для этого мы и записывали в USB_DADDR значение). Если да, то переписываем его в регистр адреса DADDR, и записываем в младшие 4 бита каждой из используемых конечных точек их номер — это будет сигнализировать драйверу, что с ними можно работать.
И наконец переводим нулевую конечную точку в состояние STALL (EP0R = (EP0R^0x1010)&0xBFBF) и выходим из цикла.

Адрес назначен.

И напоследок,

Ещё несколько команд, которые нужно уметь обрабатывать

Таблица

Команда (USB_Command)

Что от нас требуется

0x0900

Выбрать активную конфигурацию устройства (сконфигурировать). Номер конфигурации находится в USB_wValue и не должен превышать максимальное для нашего устройства

0x0500

Назначить адрес для данного устройства в текущей сессии. Адрес может быть от 1 до 127 (0 означает, что устройство пока без адреса). Именно по этому номеру хост будет обращаться к устройству

0x0100

Выключить возможность перевода устройства в спящий режим и обратно через порт (Clear Feature)

0x0300

Включить возможность перевода устройства в спящий режим и обратно (SET Feature)

0x0B01

Включить определённый интерфейс. Номер интерфейса содержится в младшем байте USB_wIndex, не должно быть больше чем количество интерфейсов у устройства и устройство к этому моменту должно быть сконфигурировано.

0x0102

Перевести конечную точку в состояние VALID (0x3000 или 0x0030), при условии, что она находится в состоянии STALL. Номер конечной точки находится в младших 7 битах USB_wIndex, направление — в 8м бите. Устройство должно быть сконфигурировано, конечная точка — активна.

0x0302

Перевести активную конечную точку в состояние STALL

0x0221

Настроить COM порт

В моём коде в этом месте ничего не происходит, но я заметил, что к этому моменту устройство и хост уже достаточно хорошо познакомились, и этот (а так же один из двух следующих) запрос приходит в момент подключения терминала. Таким образом сюда можно поставить, например, приветствие.

0x2021

Настроить бодрейт и прочие параметры передачи

0x2221

Настроить состояние линии управления портом

0x0680

Отправить хосту дескриптор. Какой именно определяется параметром USB_wValue:
0x0100 — дескриптор устройства
0x0200 — дескриптор конфигурации
0x0300 — поддерживаемые кодировки
0x0301 — поставщик, строка в юникоде
0x0302 — имя устройства. строка в юникоде
0x0303 — серийный номер устройства, человекочитаемая строка в юникоде

0x0080

Отправить хосту статус устройства. Если питается от хоста, то поднять бит 0x01, если возможность перевода в спящий режим и обратно включена, поднять бит 0x02. Иначе вернуть 0

0x0081

Статус интерфейса. Возвращаем 0.

0x0082

Статус конечной точки. Номер конечной точки находится в младших 7 битах USB_wIndex, направление — в 8м бите.
Возвращает 1, если состояние — STALL.

0x0880

Вернуть номер конфигурации. Это той, которую мы назначали командой 0x0900

0x2021

Обозначить бодрейт и прочие параметры передачи. И вернуть результат:
PMA_BUF(EP0TX_OFFSET) = 9600;//baudrate bytes
PMA_SBUF(EP0TX_OFFSET+4) = 0;//parity*256+format
PMA_SBUF(EP0TX_OFFSET+6) = 8;//datatype

0x2121

Передать хосту бодрейт и прочие параметры передачи. Ответ формируется так же, как и в предыдущем случае.

Надеюсь, что кому-то эта статья будет полезна. По крайней мере, именно такого разбора мне самому не хватало в процессе изучения библиотек и логики работы USB.

Written by Administrator on 07 апреля 2012.

Проблемы при «прошивке» ресиверов. Отсутствие COM порта. Использование ноутбука

В большинстве «старых» компьютеров и ноутбуков, приобретенных более 5лет назад, всегда было несколько COM портов (RS-232). По крайней мере, всегда был хотя бы один разъем «RS-232».

rs_232
Рис. 1. Разъем на корпусе компьютера

К нему подключали различное внешнее оборудование: мыши, принтеры, модемы, специализированное оборудование. Поэтому проблем с подключением ресивера к компьютеру для «прошивки» не возникало. Достаточно было просто подключить, запустить программу для обновления ПО ресивера и спокойно сделать все необходимое.

В современных компьютерах разъем «RS-232» нередко отсутствует. Тут и возникают проблемы, зачастую весьма неприятные. В большинстве ресиверов нет иных способов «прошивки» кроме использования «RS-232». И «USB» вход для подключения внешнего флешь-накопителя есть не у всех ресиверов.

А иногда имеется и другая проблема: ноутбук имеет «COM» порт, но с ресиверами одной модели он работает, а с другими — нет. Это связано с нарушением производителем ноутбука стандарта передачи данных «RS-232». На это они идут в целях экономии энергии заряда аккумуляторной батареи. Если производитель ресивера был технически щепетилен и точен, то в ресивере будет установлена специальная микросхема для «COM» порта. Благодаря этой микросхеме ресивер будет работать и с ноутбуком, и с компьютером. Но установка микросхемы увеличивает общую стоимость изделия, а в последнее время производители экономят даже на этих мелочах! Поэтому и возникает проблема несовместимости ноутбуков и большинства ресиверов.

При использовании компьютера проблема отсутствия необходимых портов«RS-232» решается просто: необходимо приобрести дополнительный модуль с «COM» портами. Это плата, устанавливаемая в компьютер, называется «PIC—COM» или просто «плата СОМ портов».

rs232_plata

Рис. 2. Плата PCI для компьютера с двумя «COM» портами

Если вы не сильны в компьютерах и ранее никогда не имели дело с установкой дополнительного оборудования в компьютер, то обратитесь к специалисту! Иначе можете «умертвить» дорогостоящее оборудование.

После установки платы в компьютер операционная система «Windows» — «ОС» присваивает новым установленным портам номер, например, «1», «2»…«25».

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

rs232_notebook

Рис. 3. Плата для ноутбука с «COM» портом

И тут есть подвох: в «старых» и «новых» ноутбуках два разных стандарта для дополнительного оборудования! Перед приобретением сверьтесь с инструкцией к вашему ноутбуку!

Если же вы не могли приобрести плату на компьютер или ноутбук, то остается один выход: «USB». Практически во всех современных моделях компьютеров имеется «USB» выход, как минимум два, а то и все восемь! В продаже имеются различные преобразователи «USB — COM».

rs232_usb_kabel

Рис. 4. Преобразователь «USB — COM»

usb_sh

Рис. 5. Схема преобразователя «USB — COM»


Как спаять Переходник USB-COM самостоятельно. Вариант — 1

Ссылки по теме

1.Prolific PL2303 HX  документация и драйвера

2. MAX232 документация

Как сделать  самому  переходник USB-COM , который можно использовать для подключения конвертеров и прочих девайсов к  компьютерам  у которых нет «железного» COM-порта.
Внимание!
Переходник описанный ниже  обеспечивает согласование только сигналов RX и  TX.
Все прочие модемные сигналы не задействованы.
Большинству устройств, работающих без  аппаратного управления потоком,  этого более чем достаточно.
С конвертерами Pilot  VAF/MAF  переходник работает 100%

Поехали!

Для сборки вам потребуются следующие детали:

1. PL2303HX  (USB-USART мост  от  Prolific)-1шт.
2. MAX232CSE  (UART-RS232)-1шт.
3. Кварц 12.00 МГц-1шт.
4. Конденсаторы 10 нФ ( smd1206)-2шт.
5. Конденсаторы 1 мкФ (smd1206)-6шт.
6. Резисторы 27Ом ( smd1206) -2шт.
7. Резисторы 1.5КОм (smd1206)-1шт.
8. Разъем mini-USB -1шт.
9. Разеъем DB-9 папа – 1шт.
10. Фольгированный текстолит  для платы 48*22мм – 1шт

Схема переходника

usb_com_sch_2

Печатная плата

usb_com_pcb

Файлы схемы и печатки  в формате Eagle PCB Editor  можно скачать по этой ссылке

Сборка и настройка
Здесь собственно все элементарно  —  делаем плату , сверлим 4-ре отверстия и напаиваем все  детальки.
В итоге у вас должен получиться вот такой вот переходничок:

filtered1

Плату, чтобы не окислялась, можно задуть полиуретановым лаком или   любым быстросохнущим автомобильным лаком, какой есть под рукой.
Далее  этот девайс подключаем  к порту USB  компьютера.
Windows  обнаружит новое устройство и попросит  драйвера 

Идем на сайт пролифика и выкачиваем самую последнюю версию дров

http://www.prolific.com.tw/eng/downloads.asp?ID=31

На момент написания статьи , самый последний драйвер был вот этот.

После скармливания винде драйвера ,  в системе должен появиться новый COM порт Prolific:
device

Теперь необходимо проверить работоспособность переходника

Для этого на переходнике  в разъеме COM-порта , отверткой или  проволочкой замыкаем между собой контакты 2 и 3 ( на самом разъеме обычно выбиты цифры с номерами контактов – приглядитесь повнимательнее ) Как вариант, можно напаять временную перемычку:

peremichka Далее запускаем программу «Гипертерминал»  (Пуск->Программы->Стандартные->Связь->Гипертерминал)
На висте и семерке  гипертерминала нет! Поэтому придется сходить в гугл/яндекс выкачать гипертерминал или  любой его аналог.

Выбираем   в настройках соединения наш новый сом-порт:

hyperterminal

Далее гипертерминал предложит  настроить параметры порта.
Выставляем :
-115200
-8
-N(нет)
-1
-управление потоком отсутствует

hyperterminal1

Теперь запускам соединение,   выбираем английскую раскладку и пробуем  чего-нибудь печатать.

На экране должны появиться символы нажимаемых клавиш:

hello

Если буквы не появляются,  то проверяйте монтаж

Вот собственно и все!
Теперь остается убрать перемычку с контактов 2-3  и можно пользоваться переходником по прямому назначению.

Т.е. в свободный разъем «USB» ноутбука подключается вход такого «преобразователя», с диска из комплекта устанавливается драйвер (программа управления) и в системных настройках появляется виртуальный COM порт с присвоенным порядковым номером.


Как спаять Переходник USB-COM самостоятельно. Вариант — 2

Рисунок 1. Общий вид
rd_6_9_1k

Предлагаемый блок в собранном виде позволяет реализовать принцип: купил – подключил. Устройство позволит пользователям персональных компьютеров подключить к USB-порту устройства, работающие от COM-порта (RS232C).

 Ориентировочная розничная цена: 540 руб

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

Технические характеристики

Напряжение питания от USB порта: 5 В.

Ток потребления: 20 мА.

Скорость соединения RS232C: 110-230000 бит/с

Интерфейс: USB1.1, USB2.0.

Поддерживаемые операционные системы: Win98, Win2000, WinXP, Vista, Linux и др.

Габаритные размеры устройства: 60×30 мм.

Комплект поставки

Блок переходника в сборе: 1.

Инструкция: 1.


Конструкция

Конструктивно переходник выполнен на двусторонней печатной плате из фольгированного стеклотекстолита, защищенной прозрачной термоусадочной трубкой.

Переходник обеспечивает все модемные сигналы: DSR, DTR, RTS, CTS, RI, DCD, а также основные сигналы RXD и TXD.

rd_6_9_2k

Рисунок 2. Схема электрическая принципиальная

rd_6_9_3k (1)

Рисунок 3. Вид печатной платы со стороны деталей

Описание работы блока

Принципиальная электрическая схема приведена на рис 2.

Центральная часть устройства – микроконтроллер CP2102 производства SILICON LABORATORIES. В качестве микросхемы драйвера уровней применен преобразователь MAX3243 производства фирмы Texas Instruments. Переходник обеспечивает все модемные сигналы: DSR, DTR, RTS, CTS, RI, DCD, а также основные сигналы RXD и TXD.


Установка устройства в ОС

Для установки драйверов для компьютера следует сначала скачать соответствующий вашей операционной системе драйвер.

Далее инсталлируйте драйвер на свой персональный компьютер. Подключите переходник. Операционная система обнаружит его и «попросит» драйвер, следует указать ей месторасположение этого драйвера (то место, куда он был распакован).

После успешной установки на переходнике должен засветиться светодиод, сигнализирующий готовность устройства к работе!

NEW Обновлённый драйвер от 25.01.2011 г. качать здесь.

1. Драйвер для Win Vista Вы можете скачать здесь.

2. Драйвер для Windows 2000/XP/Server 2003/Vista (v5.0) Вы можете скачать здесь.

3. Драйвер для Linux Вы можете скачать здесь.

4. Драйвер для Win98SE Вы можете скачать здесь.

5. Драйвер для OC Mac Вы можете скачать здесь.

6. an144sw.zip — c помощью данной программы можно изменить ID коды USB-COM переходника. Это нужно для того, чтобы получить возможность использовать несколько 8050 на одном ПК. Использовать только опытным пользователям! Вы можете скачать здесь.

7. AN205SW.zip — программа, позволяющая изменять стандартный ряд скоростей последовательного порта. Вы можете скачать

здесь.


ПРОВЕРКА РАБОТОСПОСОБНОСТИ BM8050 БЕЗ ВНЕШНЕГО ОБОРУДОВАНИЯ

Для проверки передачи и приема всех необходимых модемных сигналов согласно подключения СОМ-устройства.

1_bm8050

Установите перемычки на контакты 2-3, 4-6, 7-8 СОМ-разъема ВМ8050.

— Соедините устройство c USB-портом ПК.

— Посмотрите, какой порт ОС выделила для устройства, для чего войдите в Пуск — Настройка — Панель Управления — Система — Оборудование — Диспетчер Устройств — Порты (СОМ и LPT) — Silicon Labs CP210x USB to UART Bridge (COM1).

— Запустите стандартное приложение HiperTerminal для Windows из Пуск — Программы — Стандартные — Связь — HiperTerminal.

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

— Посмотрите, какой порт используется программой для связи с устройством, для чего войдите слева вверху Файл — Свойства и напротив «Подключаться через» выберите такой же порт, как и в Диспетчере Устройств (в нашем случае COM1).

— В этом же окне убедитесь, что выбрано управление потоком «Аппаратное» в программе, для чего нажмите кнопку в центре «Настроить» и в нижнем окне «Управление потоком» выберите «Аппаратное».

— Выйдите из настройки программы, для чего нажмите ОК, еще раз ОК.

— Напечатайте текст «Текст» в программе HiperTerminal, при этом на экране печатается текст «Текст», что подтверждает исправность устройства.

— Снимите перемычки с контактов 2-3, 4-6, 7-8 СОМ-разъема ВМ8050.

2_bm8050

— Напечатайте текст «Текст» в программе HiperTerminal, при этом на экране печать отсутствует, что подтверждает исправность устройства.


Настройка драйвера и выбор порта для переходника USB-COM

Тут нас поджидают первые проблемы: во-первых, ОС могла присвоить виртуальному порту слишком большой номер, например,«25». А программа для «прошивки» ресивера позволяет работать с номерами портов от одного до четырех. Во-вторых, не все преобразователи «USB -COM» могут работать с программой для «прошивки» и самим ресивером. Причина в том, что производители оборудования по-разному изготовили свои изделия и программы к ним. Проверять все преобразователи необходимо индивидуально под вашу программу и ваш ресивер. Часто бывает, что с одним оборудованием преобразователь работает, а с другим— нет.

Если первая проблема устраняется изменением номера порта в настройках ОС, то проблему совместимости оборудования, программы и преобразователя устранить нельзя.

Для изменения присвоенного ОС номера необходимо изменить его вручную. Для этого необходимо войти в «Диспетчер устройств»: «Пуск» — «Настройка» —«Панель управления» — «Система».

drv

Рис. 15.6. «Панель управления»

В появившемся окне выбрать вкладку «Оборудование» и щелкнуть по кнопке «Диспетчер устройств». Откроется окно «Диспетчер устройств». В появившемся окне в древовидном списке выбрать строчку «Порты (COM и LPT). В раскрывшемся списке вы увидите все порты, имеющиеся в вашем компьютере. Выберите ваш виртуальный порт: «преобразователь «USB — COM». У меня преобразователь модели «Prolific».

drv2
Рис. 15.7. Список имеющихся портов

Щелкните по этой строчке ПРАВОЙ кнопкой мыши, в открывшемся окне выберите стройку «Свойства».

drv3

Рис. 15.8. Настройка выбранного порта

В появившемся окне выберите вкладку «Параметры порта». В строчке «Скорость» выберите «115200», затем щелкните по кнопке «Дополнительно».

drv4

Рис. 15.9. Настройка параметров порта

В нижней части открывшегося окна найдите вкладку «Номер COM порта».

drv5

Рис. 16. Изменение номера COM порта

Щелкните по вкладке и выберите необходимый номер COM порта.

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

После завершения настройки нажмите «ОК» для сохранения внесенных изменений и полностью выйдите из режима настроек, закрыв все ранее открытые окна. После этого перезагрузите компьютер для внесения необходимых изменений. Если же вы изменяли номер «COM» порта «USB — COM» преобразователя, то достаточно просто вынуть его из разъема компьютера и заново подключить.


Готовые решения USB-COM адаптеров от производителей.

Кабель-адаптер COM 9/25M -> USB AM 1м
shnur_usb_com

Цена — 300 руб.
Описание   Кабель для подключения устройств с последовательным интерфейсом (RS-232) к USB порту.
Тип оборудования   Кабель-переходник
Разъемы кабеля или переходника   COM25M, COM9M, USB A
Совместимость
Совместимость   USB 1.1/2.0
Поддержка ОС   Windows 2000, Windows XP
Прочее
Длина кабеля   1 метр
Логистика
Размеры упаковки (измерено в НИКСе)   21.5 х 14.5 х 4.1 см
Вес брутто (измерено в НИКСе)   0.136 кг

Кабель-адаптер TRENDnet <TU-S9> COM9M—>USB AM 0.6м
trendnet_usb_com

Цена — 500 руб.
Основные
Производитель   TRENDnet
Модель   TU-S9
Описание   Переходник позволяет подключить устройство с интерфейсом RS-232 (например, модем) к порту USB компьютера.
Тип оборудования   Кабель-переходник
Разъемы кабеля или переходника   COM9M, USB A
Диаметр   28/24 AWG
Параметры производительности
Скорость передачи данных   500 Кбит/сек
Питание   От USB порта
Потребление энергии   500 мА — максимальное
Совместимость
Требования к системе   RAM 64 Мб
Поддержка ОС   Windows ME, Windows 2000, Windows XP
Прочее
Соответствие стандартам   RoHS
Длина кабеля   0.6 метра
Вес   75 грамм
Рабочая температура   0 ~ 40°C

Размеры упаковки (измерено в НИКСе)   23 x 16.8 x 4.6 см
Вес брутто (измерено в НИКСе)   0.135 кг
Внешние источники информации
Ссылка на сайт производителя   

www.trendnet.com

Адаптер — переходник  USB-COM (RS-232)
shnur_usb_com2
Цена — 1500 руб.
Адаптер предназначен для использования приборов и адаптеров расчитанных для включения через Com (RS232) порт, например это очень актуально при использовании современных компьютеров, которые имеют только USB, в этом случае, с помощью этого переходника вы можете использовать современные компьютеры и ноутбуки совместно с нашими приборами и адаптерами, такими как Сканер BMW, Сканер Mercedes, Scanmatik и др.

Оборудование для автосервисов, автодиагностика, диагностическое оборудование, диагностика авто, автомобильный сканер, автосканер, диагностический пост, чип тюнинг, оборудование для автодиагностики Carbrain, UNISCAN, ADP-504, KKL-USB, KKL-COM, сканер BMW, сканер Opel, BMW 1.3.6, Automan, Opel scanner, BMW scanner, мотор тестер, газоанализатор, диагностика двигателя, диагностика панели приборов Программатор транспондеров, OBD-2, OBD2, корректировка одометра, U-581, запуск двигателя, crash data, креш дата, крэш дата, спидометр, тахометр.

Хотя может нужно воспользоваться нуль модемным кабелем (2-3, 3-2, 5-5)  и переходником типа —

usb_com_papa

К переходнику добавляете USB удлинитель вот вам и прямой нуль-модемный кабель.

usb_a_b

  • Розничная стоимость 100р. 
  • Тип A-A
  • Длина: 1.5 м

Но для остальных ресов нужен «перевёрнутый» нуль-модемный кабель.

rs232_kabel

  • Розничная цена   155.00 руб.
  • Тип разъема: DB9 F — DB9 F
  • Длина: 1.8 м

или такой переходник:

STLab U-350 (RTL) Адаптер COM 9M -> USB AM
stlab_u-350_usb_com

Цена — 350 руб.
Основные
Производитель   St-Lab
Модель   USB DONGLE SERIAL 1 PORT
Описание   Переходник позволяет подключить устройство с интерфейсом RS-232 (например, модем) к порту USB компьютера.
Тип оборудования   Кабель-переходник
Разъемы кабеля или переходника   COM9M, USB A
Встроенный USB-коннектор    Да
Параметры производительности
Скорость передачи данных   115200 бит/сек
Интерфейс   USB 1.1
Питание   От USB порта
Поддержка ОС   Windows 2000, Windows ME, Windows XP, Windows Vista, Windows 2003 Server
Размеры упаковки (измерено в НИКСе)   17 x 13 x 3.2 см
Вес брутто (измерено в НИКСе)   0.077 кг
Внешние источники информации Ссылка на сайт производителя   www.st-lab.com

How to choose the best solution for your needs?

Choosing the handiest and suitable software solution depends on areas and conditions of usage. Here are a few situations where virtual serial ports can be useful.

1. The absence of a serial port.

Many of the computers that manufactured today are not equipped with any serial ports at all. Some machines take it a step further and do not have ports of any type, relying on wireless connectivity to peripheral devices.

The reduction in reliance on COM ports in machines and devices used for general purposes has not eliminated the requirement for serial connectivity. Many special-purpose devices still make use of serial interfaces to communicate with computers. Some examples are industrial automation monitoring devices, medical monitoring equipment, and specialized laboratory equipment.

2. Sharing a serial monitoring device.

If you have a serial monitoring device in an industrial production facility, it may be transmitting data used as input for several different applications. Creating virtual serial ports from a single port lets all of your applications receive their data at the same time.

3. Accessing multiple serial devices.

Network-attached serial devices can be assigned virtual RS232 ports that can then be merged into a single virtual port that can be used by your application.

So on these occasions, the best choice is virtual serial port emulator software. A benefit of a paid solution is that you receive regular program updates and customer support for your money. This can be a determining factor if you are doing serious development and want the most up-to-date null-modem emulator application available.

The preceding comparison of virtual null-modem software tools indicates that Electronic Team’s Virtual Serial Port Driver offers more features than the other solutions. Ease of use, quality customer support, and a focus on data protection are some of the advantages of this product. It also features a user-friendly interface that makes it an easy task to create and delete virtual COM ports.

The extended capabilities of the PRO version make this flexible software application an effective and powerful tool for developers or users who need to work with serial devices.

These are just a few ways that virtual ports can be used. If you work with serial devices or applications, a serial port emulator like Virtual Serial Port Driver can be an essential component of your software toolbox.

Like this post? Please share to your friends:
  • Как создать аккаунт steam на компьютер windows
  • Как создать виртуальный cd rom привод диск windows 10
  • Как создать аккаунт microsoft windows 10
  • Как создать администратора в windows через cmd
  • Как создать администратора в windows 10 pro