Postanowilem podzielic sie z wami moimi doswiadczeniami wykorzystania interfejsu USB we wlasnych projektach.
Jak wiadomo interfejs USB jest juz powszechnie dolaczanym interfejsem do mikrokontrolerow wiekszosci producentow na rynku.
Sama obsluga USB zarowno po stronie mikrokontrolera jak i pc (a wlasciwie Windows) jest mniej przyjazna niz w wiekszosci uzywane do jej pory polaczenie rs232 (wlaczajac w to przejsciowki rs232<->usb).
Po stronie mikrokontrolera producenci czesto dolaczaja przyklady obslugi USB jednak dotycza one konkretnych klas : HID, MSC, DFU, VPC.
My jednak chcemy prosta komunikacje dwukierunkowa - wyslij, odbierz - tzw komunikacje bulk. Do tego celu pokaze jak przerobic klase VPC gdyz ona posiada to czego potrzebujemy - 2 endpointy (in,out) transmisji bulk. Natomiast wytniemy z deskryptorow endpoint komend i zmienimy klase z VCP na tzw Vendor class.
Po stronie Windows sprawa jest bardziej skomplikowana, gdyz najpierw musimy 'znalezc' nasze urzadzenie w systemie wykorzystujac biblioteke systemowa SetupApi.dll a pozniej sterowac nim za pomoca funkcji biblioteki naszego drivera czyli WinUSB.dll. Zeby ulatwic programowanie dla tych, ktorzy czuja, ze nie dadza rady nawiazac polaczenia ze swoim urzadzeniem, napisalem prosta biblioteke dll, ktora sie podziele i opisze jej funkcje (w sumie cztery), ktore zapewnia komunikacje z naszym urzadzeniem.
I. Mikrokontroler
Jak napisalem wyzej, bede zmienial deskryptory klasy VCP. Platforma testowo-pokazowa bedzie CubeIde i mikrokontroler stm32f042. Jednak zmiana dekryptorow dotyczy kazdego sprzetu i producenta uc. Z powodzeniem testowalem to na mikrokontrolerach ST, NXP i TI.
Zaczynamy:
Tworzymy nowy projekt w CubeIde, konfigurujemy uc wg naszych potrzeb, wlaczamy USB w drzewie Connectivity a w drzewie Middleware USB_DEVICE ustawiamy na Communication Device Class (Virtual Port Com).
Generujemy kod.
Otwieramy plik usbd_cdc.c (Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Src)
W pliku przechodzimy linijki:
Jest to deskryptor dla urzadzen HS. Wszystkie modyfikacje beda pokazane 'od gory' deskryptora.
Zmieniamy ilosc interfejsow w linice:
na 0x01
komentujemy wszystko od linijki:
do:
W pozostalym niezakomentowanym kodzie zmieniamy wartosci:
na 0x00
na 0xFF
Powyzsze powtazamy dla deskryptorow:
USBD_CDC_CfgFSDesc i USBD_CDC_OtherSpeedCfgDesc
Jako ze zmienila nam sie dlugosc deskryptora musimy zmienic wartosc zmiennej:
USB_CDC_CONFIG_DESC_SIZ w pliku usbd_cdc.c (Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Inc) z 67 na 32
Wlasciwie to juz wszystko. Zalecam jednak zmiane VID i PID oraz opisy urzadzenia w pliku usbd_desc.c (USB_DEVICE\App)
Ponizej filmik pokazujacy co do tej pory trzeba zrobic:
Po wgraniu wsadu do uc i podlaczeniu do PC w managerze urzadzen powinnismy zobaczyc nasze urzadzenie.
II. Windows
Do zainstalowania sterownikow proponuje wykorzystac program Zadig. Nie tylko zainstaluje nam sterowniki ale rowniez stworzy pakiet instalacyjny na inne PC.
W tym kroku nie ma zbytnio co opisywac wiec znowu filmik:
Po zainstalowaniu sterownikow w latalogu C:\Users\naszanazwauzytkownika\usb_driver pojawia sie paczka sterownikow dla naszego urzadzenia.
Wlasciwie to juz wszystko - mozna zaczac pisac programy wymieniajace sie danymi z naszym urzadzeniem.
Aby zobaczyc jak napisac przykladowa komunikacje PC<->nasze urzadzenie zapraszam do daleszj czesci artykulu.
III.Komunikacja
Do nawizania komunikacji uzyje napisanej przeze mnie biblioteki i srodowiska Delphi 10.3 (dzialanie biblioteki sprawdzilem rowniez piszac aplikacje na Visual Studio).
Zaczne moze od opisu biblioteki.
Biblioteka exportuje 4 funkcje:
UsbDevInfo jest to rekord/struktura:
Po przypisaniu zmiennej typu UsbDevInfo do funkcji UsbDevOpen wszystkie pola sa automatycznie ustawiane i jedynie najlepiej tylko modyfikowac pole timeout, ktore domyslnie ustawiane jest na 100.
W delphi tworzymy nowy projekt. Na formatke wrzucamy button i memo. Deklarujemy nasz rekord, zmienna (globalna) tego rekordu i GUID naszego urzadzenia, ktore wezmiemy z katalogu sterownika z pliku .inf z linijki DeviceGUID:
Importujemy wszystkie funkcje z biblioteki oloamusb.dll :
W OnCreate formy:
OnClick przycisku:
W OnClose formy:
Program gotowy. Oczywiscie nie ma tu sprawdzenia czy urzadzenie zostalo wykryte (czy uchwyt di.husb > 0)
Zawartosc unitu - caly program:
Po stronie mikrokontrolera (rozpatrujemy kontynuowanie programu z poczatku artykulu) bedziemy potrzebowac zmiennej i funkcji ktora znajduje sie w pliku usbd_cdc_if dlatego inkludujemy:
oraz uzyskujemy dostep do zmiennych:
sa to bufory ,ktore przechowuja man dane odebrane/do wyslania z/do USB
W zmiennych deklarujemy jeszcze licznik, ktory bedziemy przesylac(aby widac bylo ze za kazdym razem dane sa inne):
Na koniec w petli glownej:
Efekt obu programow:
Biblioteka:
Jak wiadomo interfejs USB jest juz powszechnie dolaczanym interfejsem do mikrokontrolerow wiekszosci producentow na rynku.
Sama obsluga USB zarowno po stronie mikrokontrolera jak i pc (a wlasciwie Windows) jest mniej przyjazna niz w wiekszosci uzywane do jej pory polaczenie rs232 (wlaczajac w to przejsciowki rs232<->usb).
Po stronie mikrokontrolera producenci czesto dolaczaja przyklady obslugi USB jednak dotycza one konkretnych klas : HID, MSC, DFU, VPC.
My jednak chcemy prosta komunikacje dwukierunkowa - wyslij, odbierz - tzw komunikacje bulk. Do tego celu pokaze jak przerobic klase VPC gdyz ona posiada to czego potrzebujemy - 2 endpointy (in,out) transmisji bulk. Natomiast wytniemy z deskryptorow endpoint komend i zmienimy klase z VCP na tzw Vendor class.
Po stronie Windows sprawa jest bardziej skomplikowana, gdyz najpierw musimy 'znalezc' nasze urzadzenie w systemie wykorzystujac biblioteke systemowa SetupApi.dll a pozniej sterowac nim za pomoca funkcji biblioteki naszego drivera czyli WinUSB.dll. Zeby ulatwic programowanie dla tych, ktorzy czuja, ze nie dadza rady nawiazac polaczenia ze swoim urzadzeniem, napisalem prosta biblioteke dll, ktora sie podziele i opisze jej funkcje (w sumie cztery), ktore zapewnia komunikacje z naszym urzadzeniem.
I. Mikrokontroler
Jak napisalem wyzej, bede zmienial deskryptory klasy VCP. Platforma testowo-pokazowa bedzie CubeIde i mikrokontroler stm32f042. Jednak zmiana dekryptorow dotyczy kazdego sprzetu i producenta uc. Z powodzeniem testowalem to na mikrokontrolerach ST, NXP i TI.
Zaczynamy:
Tworzymy nowy projekt w CubeIde, konfigurujemy uc wg naszych potrzeb, wlaczamy USB w drzewie Connectivity a w drzewie Middleware USB_DEVICE ustawiamy na Communication Device Class (Virtual Port Com).
Generujemy kod.
Otwieramy plik usbd_cdc.c (Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Src)
W pliku przechodzimy linijki:
Code: c
Jest to deskryptor dla urzadzen HS. Wszystkie modyfikacje beda pokazane 'od gory' deskryptora.
Zmieniamy ilosc interfejsow w linice:
Code: c
komentujemy wszystko od linijki:
Code: c
do:
Code: c
W pozostalym niezakomentowanym kodzie zmieniamy wartosci:
Code: c
Code: c
Powyzsze powtazamy dla deskryptorow:
USBD_CDC_CfgFSDesc i USBD_CDC_OtherSpeedCfgDesc
Jako ze zmienila nam sie dlugosc deskryptora musimy zmienic wartosc zmiennej:
USB_CDC_CONFIG_DESC_SIZ w pliku usbd_cdc.c (Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Inc) z 67 na 32
Wlasciwie to juz wszystko. Zalecam jednak zmiane VID i PID oraz opisy urzadzenia w pliku usbd_desc.c (USB_DEVICE\App)
Ponizej filmik pokazujacy co do tej pory trzeba zrobic:
Po wgraniu wsadu do uc i podlaczeniu do PC w managerze urzadzen powinnismy zobaczyc nasze urzadzenie.

II. Windows
Do zainstalowania sterownikow proponuje wykorzystac program Zadig. Nie tylko zainstaluje nam sterowniki ale rowniez stworzy pakiet instalacyjny na inne PC.
W tym kroku nie ma zbytnio co opisywac wiec znowu filmik:
Po zainstalowaniu sterownikow w latalogu C:\Users\naszanazwauzytkownika\usb_driver pojawia sie paczka sterownikow dla naszego urzadzenia.
Wlasciwie to juz wszystko - mozna zaczac pisac programy wymieniajace sie danymi z naszym urzadzeniem.
Aby zobaczyc jak napisac przykladowa komunikacje PC<->nasze urzadzenie zapraszam do daleszj czesci artykulu.
III.Komunikacja
Do nawizania komunikacji uzyje napisanej przeze mnie biblioteki i srodowiska Delphi 10.3 (dzialanie biblioteki sprawdzilem rowniez piszac aplikacje na Visual Studio).
Zaczne moze od opisu biblioteki.
Biblioteka exportuje 4 funkcje:
Code: delphi
UsbDevInfo jest to rekord/struktura:
Code: delphi
Po przypisaniu zmiennej typu UsbDevInfo do funkcji UsbDevOpen wszystkie pola sa automatycznie ustawiane i jedynie najlepiej tylko modyfikowac pole timeout, ktore domyslnie ustawiane jest na 100.
W delphi tworzymy nowy projekt. Na formatke wrzucamy button i memo. Deklarujemy nasz rekord, zmienna (globalna) tego rekordu i GUID naszego urzadzenia, ktore wezmiemy z katalogu sterownika z pliku .inf z linijki DeviceGUID:
Code: delphi
Importujemy wszystkie funkcje z biblioteki oloamusb.dll :
Code: delphi
W OnCreate formy:
Code: delphi
OnClick przycisku:
Code: delphi
W OnClose formy:
Code: delphi
Program gotowy. Oczywiscie nie ma tu sprawdzenia czy urzadzenie zostalo wykryte (czy uchwyt di.husb > 0)
Zawartosc unitu - caly program:
Code: delphi
Po stronie mikrokontrolera (rozpatrujemy kontynuowanie programu z poczatku artykulu) bedziemy potrzebowac zmiennej i funkcji ktora znajduje sie w pliku usbd_cdc_if dlatego inkludujemy:
Code: c
oraz uzyskujemy dostep do zmiennych:
Code: c
sa to bufory ,ktore przechowuja man dane odebrane/do wyslania z/do USB
W zmiennych deklarujemy jeszcze licznik, ktory bedziemy przesylac(aby widac bylo ze za kazdym razem dane sa inne):
Code: c
Na koniec w petli glownej:
Code: c
Efekt obu programow:
Biblioteka:
Cool? Ranking DIY