Skocz do zawartości

Kurs STM32 F4 - #11 - Komunikacja przez USB


Pomocna odpowiedź

Napisano
html_mig_img
Standardem komunikacyjnym w świecie PC stał się interfejs USB. Można go znaleźć w ogromnej ilości urządzeń takich jak kamery, myszki, pamięci przenośne, czy klawiatury.Mikrokontrolery nie stanowią tutaj wyjątku i coraz częściej wyposażane są w kontroler USB, którego obsługą zajmiemy się w tym odcinku kursu

UWAGA, to tylko wstęp! Dalsza część artykułu dostępna jest na blogu.

Przeczytaj całość »

Poniżej znajdują się komentarze powiązane z tym wpisem.

Uruchamiałem ostatnio USB na STM32 (Mass Storage) i miałem trochę podobny problem z wykrywaniem urządzenia. Wyglądało to jak jakby przy wstrzymaniu programu albo reflashowaniu procka, kontroler wykrywał timeout i odłączał urządzenie. Zmieniłem więc podłączenie rezystora 1K5, zamiast na stałe do VCC jest teraz podłączony do jednego z GPIO i zaraz po resecie jest ustawiany na 0 i po około sekundzie, po przeprowadzeniu całej inicjalizacji jest ustawiany na 1. Kontroler wykrywa to jak odłączenie i podłączenie.

Powyższy screen pochodzi z STM32F4DISCOVERY z STLink-a, USB z procka nie ma wcale tego rezystora, więc może w tym problem.

W moich projektach używam też takiego rozwiązania ( 1.5k do gpio ) i urządzenie jest wykrywane bez problemu. Jedyny ew. błąd pojawia się jak się próbuje wykorzystać port com w momencie jego inicjalizacji / ładowanie drivera przez windows czy coś takiego. Wystarczy spokojnie poczekać 3 sekundy od wsadzenia urządzenia do podłączenia się aplikacją windowsa do coma i działa w 100%.

  • 2 tygodnie później...

Witam, mam problem ponieważ Windows nie wykrywa w ogóle mojego stm32f429, nie wiem jak to zrobić, próbowałem również z innymi komputerami i to samo, nie wykrywa w ogóle mikrokontrolera jako urządzenia USB, co mam zrobić z tym fantem?

Ja dodam, że jeśli robimy coś z USB na własnych płytkach pcb należy zadbać o długość ścieżek - tzn. najlepiej jak są krótkie, a jeśli musimy je poprowadzić dłuższą drogą niezbędny będzie układ stosowany w zestawach Discovery który podłącza się równolegle do linii USB. Straciłem na tym dużo czasu, a okazało się ze problemem były właśnie niewiele za długie ścieżki.

Aha przejawia się to tym, że komputer wykrywa uszkodzone urządzenie ( unknown device ). A najłatwiej sprawdzić połączenie zwierając BOOT0 do +3,3v przy starcie ( tryb bootloadera).

karo212, w komentarzach do kursu rozmawiamy wyłącznie o platformie sprzętowej opisywanej w artykułach. Jeśli masz problem z inną płytką, to załóż osobny temat w odpowiednim dziale. Unikniemy wtedy nieporozumień i zbędnego zamieszania.

Po pierwsze: dzięki za kurs!

A teraz problem/zagadka: napisałem prosty programik w zasadzie bardzo podobny co przykład z przyciskiem ale z odbieraniem komendy. Główna pętla (wyczyszczona, żeby mniej miejsca zajmowała):

while (1)
 {
  if(ReceivedDataFlag == 1)
  {
	   ReceivedDataFlag = 0;

	   if( strcmp( (char *)ReceivedData, "Red") == 0 )
		   HAL_GPIO_TogglePin(LED_RED_GPIO_Port, LED_RED_Pin);
	   if( strcmp( (char *)ReceivedData, "Green") == 0 )
		   HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);

	   MessageLength = sprintf((char *)DataToSend, "Odebrano: %s\n\r", (char *)ReceivedData);
	   CDC_Transmit_FS(DataToSend, MessageLength);
  }
 }

... nie działa. uC w ogóle nie odpowiada nie reaguje. natomiast po dodaniu jednego nop'a wszystko śmiga aż miło (oczywiście delay robi to samo ale chodzi mi, że jedna instrukcja nop wystarczy):

while (1)
 {
  if(ReceivedDataFlag == 1)
  {
	   ReceivedDataFlag = 0;

	   if( strcmp( (char *)ReceivedData, "Red") == 0 )
		   HAL_GPIO_TogglePin(LED_RED_GPIO_Port, LED_RED_Pin);
	   if( strcmp( (char *)ReceivedData, "Green") == 0 )
		   HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);

	   MessageLength = sprintf((char *)DataToSend, "Odebrano: %s\n\r", (char *)ReceivedData);
	   CDC_Transmit_FS(DataToSend, MessageLength);
  }
  asm("nop");
 }

Moja pierwsza myśl to priorytety przerwania - jakby program nie mógł wyskoczyć z głównej pętli jeżeli ciągle sprawdza warunek?

Programy testuje na STM32F103.

Pozdrawiam

EDIT: wiem, że to inna platforma sprzętowa ale problem dotyczy chyba implementacji biblioteki HAL'a, więc wklepałem to tuaj.

Spróbuj zadeklarować zmienną ReceivedDataFlag jako volatile, to też powinno pomóc a przy okazji wyjaśnić zagadkę.

W kursie jest błąd - brakuje właśnie volatile w zmiennych modyfikowanych z poziomu przerwania. Poza tym używanie extern wewnątrz funkcji to baaardzo brzydka praktyka.

  • 2 miesiące później...

Też mi często w Realterm wyskakuje ten błąd z parametrem, natomiast gdy włączyłem inny terminal Tera Tera to nie napotkałem wcale na takie problemy, więc coś z konfiguracją terminala chyba musi byc 🙂

  • Lubię! 1
  • 4 tygodnie później...

Witam! To moja pierwsza przygoda z USB. Próbowałem uruchomić zgodnie z kursem to USB. Niestety komputer nawet nie widział urządzenia. Podłączyłem więc 1k5 opornik do portu GPIO i na chwilę wyłączam, a po inicjacji włączam stan wysoki i komputer rozpoznaje podłączenie do komputera ale wyskakuje taki błąd:

A request for the USB device descriptor failed.

Ktoś wie czy to może być spowodowane? Uruchomiłem ten sam kod również na płytce z STM32f103 i również ten sam błąd.

Czy może ten identyfikator należy gdzieś ustawić?

EDIT:

Po wgraniu kodu jeszcze raz i kliknięciu przycisku Reset wykrywa płytkę discovery, ale pojawia się znowu błąd:

Nie można uruchomić tego urządzenia. (Kod 10).

Czy nikt nie zetknął się z takim problemem?

----

ROZWIĄZANIE:

Rozwiązałem problem. Problem tkwił w rozmiarze paczki. Pomógł mi ten link:

forumST

W nowszej wersji kodu w podanych miejscach z tego forum nie ma takich wartość, są podobne. U siebie zmieniłem następujące parametry z wartości 512 każdy na 64:

w pliku usbd_cdc.h

#define CDC_DATA_HS_MAX_PACKET_SIZE                 64  /* Endpoint IN & OUT Packet size */

oraz

w pliku

usbd_def.h

#define USB_HS_MAX_PACKET_SIZE                            64

Pomogło. Teraz system wykrywa poprawnie STM i łączy się bez problemu z RealTerm.

Mam nadzieje, że wątek komuś pomoże. Płytka z STM32F103 też działa na tym kodzie, ustawieniach i z użyciem rezostora 1k5. Serdeczne dzięki dla Autora! ➕

Jeśli chcecie uruchomić USB na STM32f7 disco Board to wstawiłem też instrukcję jak je uruchomić tutaj:

https://community.st.com/thread/14400

🙂

814724010_bladstm32f4discovery.thumb.png.9a1dd07874777b2a2c3345262360f660.png

  • Lubię! 1
  • 4 tygodnie później...

przy debuggowaniu wysypywał sie na static

CDC_Transmit_FS()

na:

USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDevice_0->pClassData;

przed CDC_Transmit() dodałem

CDC_Init()

i gra

(na stm32f746g-discovery)

  • 2 miesiące później...

Cześć, jestem tu nowy i uczę się programowania Discovery razem z tym kursem. Mam pytanie czy istnieje możliwość przesyłania danych i zapisywania ich na pendrive podpięty pod gniazdo micro USB? Czy programem wyjściowym(do takiego zapisu), może być program z tego kursu? Jeśli jest to oczywista sprawa to przepraszam, dopiero się uczę, a wydaje mi się to ciekawym i potrzebnym zagadnieniem.

  • 3 tygodnie później...

Witam.

Odnośnie obsługi USB/CDC mam takie pytanie.

Jeśli wysyłam stringi przy pomocy CDC_Transmit_FS(), np tak:

CDC_Transmit_FS(...);
CDC_Transmit_FS(...);
CDC_Transmit_FS(...);

to wysyła mi się tylko pierwszy na liście. Nie jest to jakiś problem, bo można po każdym dać HAL_Delay() i jest już dobrze, choć pewnie mało elegancko.

Rozwiązaniem niby jest sprawdzanie co funkcja zwraca np:

while (CDC_Transmit_FS(... , ...) != USBD_OK);

i to też działa, ale... dopóki po stronie PC jest otwarty ten port. Jeśli go zamknę to program staje na tej linii programu i czeka.

Jak wobec tego sprawdzić, czy po stronie PC port jest otwarty i czy jest sens wysyłać cokolwiek na USB? Niby można zrobić jakiś timeout i wyjść, ale czy nie ma lepszego rozwiązania?

Co do pytania z tekstu z otwieraniem portu, to nie wiem, czy to ten problem, bo używam Debiana, ale u mnie po każdym resecie lub wgraniu programu zmienia się uchwyt do portu

i na zmianę mam /dev/ttyACM0 i /dev/ttyACM1. Nic nie muszę rozpinać, ani restartować.

  • 1 miesiąc później...

Witam Was, znowu muszę sie poradzić. próbuję nawiązać komunikację przez UART. Postępowałem jak w kursie, dioda miga tak jak powinna, zmieniłem port pod swoje urządzenie i w nic. Na ekranie nadal czarno, jakby połączenie nie zostało nawiązane.

Wiecie możę czym to może być spowodowane?

Posiadam trochę inną płytkę, ale wszystko pod nią zmieniłem.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...