Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA w 2025? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 9 maja 2025, o 20:08


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Ten wątek jest zablokowany. Nie możesz w nim pisać ani edytować postów.  [ Posty: 3 ] 
    Autor Wiadomość
     Tytuł: V-USB na Atmega
    PostNapisane: 25 lut 2014, o 01:11 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 22 cze 2013
    Posty: 988
    Lokalizacja: Byram, MS 39272
    Pomógł: 55

    Czym jest V-USB?

    V-USB jest to biblioteka napisana z myślą o procesorach ATMEL umożliwiająca oprogramowanie komunikacji poprzez interfejs USB. Wprawny programista może spróbować przerobić bibliotekę pod inne procesory. Bibliotekę można ściągnąć ze strony projektu http://www.obdev.at/products/vusb/index.html. W tym miejscu dowiesz się jak obsługiwać USB od strony projektu opartego na procesorze ATMEL oraz od strony środowiska systemu operacyjnego Twojego PC.
    Schematy podłączeń

    Zgodnie z zaleceniami końcówki D+ i D- powinny być podłączone do nóżek odpowiedzialnych za przerwania procesora (INT0, INT1) aczkolwiek łącze D+ interfejsu podłączone być powinno zawsze do nóżki INT0 natomiast D- może być podłączone gdzie chcemy. Dodatkowo ważnym jest aby napięcie wychodzące z łączy D+ i D- było na poziomie 3.6V co można uzyskać na kilka sposobów (patrz schematy poniżej). Zaleca się też podłączenie rezystora pull-up 1.5k do D- oraz pull-up lub pull-down 1M do D+ żeby uniknąć interferencji kiedy USB nie jest podłączone.
    Jako, że USB zasilane jest napięciem 5V do jego obniżenia można użyć diody Zenera

    Obrazek
    Podłączenie 1

    Obrazek
    Podłączenie 2

    Obrazek
    Podłączenie 3

    Rys 1. Sposoby obniżenia napięcia na wyjściu USB


    Obrazek
    Rys 2. Schemat wtyczki


    Przygotowanie do pracy

    Zanim zaczniemy należy przygotować stanowisko pracy. Nie piszę już o samym układzie ale bardziej mam na myśli przygotowanie środowiska programistycznego tj. ściągnięcie biblioteki i przygotowanie jej do pracy z naszym programem.

    Po ściągnięciu biblioteki rozpakowujemy ją do wybranego katalogu. Należy też ściągnąć sterowniki USB dla ©MS WINDOWS, dzięki którym będziemy mogli "rozmawiać" z naszym układem. Można to zrobić ze strony projektu libusb-win32. Moduł ten umożliwi nam skompilowanie sterowników dedykowanych dla naszego układu. Ale o tym później.

    Kopiujemy folder usbdrv do naszego katalogu projektu. Wchodzimy do katalogu i tworzymy kopię pliku usbconfig_prototype.h jako usbconfig.h. Lokalizujemy linie definiującą porty IO oraz taktowanie zegara i jeśli to potrzebne uaktualniamy je do odpowiednich danych. W tym miejscu chciałbym zaznaczyć, że nasz procesor MUSI byś taktowany jedną z wartości: 12 MHz, 15 MHz, 16 MHz oraz 20 MHz lub 12.8 MHz w ostateczności 16.5 MHz +/- 1%. Inne wartości taktowania spowodują, że nie będzie możliwości używania naszego urządzenia.
    Dlatego należy używać zewnętrznych kwarców i oczywiście odpowiednio obliczyć i ustawić FUSE BITy. (ja ustawiam low = AF high = DF ext. = 01)


    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Wstawiamy:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Powinniśmy też skonfigurować nazwę naszego urządzenia oraz numer, przez który będzie nas rozpoznawać nasz sterownik WINDOWS.
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Przydaje się także informacja o tym czy nasze urządzenie korzysta z zasilania USB czy nie

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Tak naprawdę plik usbconfig.h jest na tyle dobrze opisany, że można samemu zaglądnąć do środka i zorientować się co jeszcze można ustawić. Zapraszam do lektury.

    Czas na main.c


    Poniżej mamy podstawowy szkielet programu dla μprocesora obsługującego protokół i łącze USB

    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Co tu mamy? Jak to działa? Małe wytłumaczenie

    Zaimplementujmy funkcję usbFunctionSetup() obsługującą wywołania USB (co i jak opiszę później)
    W częsci głównej programu ustawiamy watchdog na 1 s, która zresetuje procesor jeśli coś pójdzie nie tak i nie zostanie wywołana funkcja wdt_reset() w czasie 1000 ms. To zabezpiecza program przed jakimiś nietypowymi zachowaniami i pozwala uniknąć użytkownikowi odłączania i ponownego przyłączania urządzenia jeśli stanie się coś dziwnego.
    Wywołajmy usbInit() - funkcję inicjującą działąnie biblioteki V-USB.
    Wymuśmy przenumerowanie USB poprzez użycie usbDeviceDisconnect(), a następnie po 500ms usbDeviceConnect(). Na wypadek resetu Watchdog.
    Włączamy przerwania
    Na sam koniec nieskończona pętla resetująca watchdog i wywołująca funkcję obsługi USB usbPool().

    Jak dotąd wszystko wygląda chyba prosto. Zatem wypadałoby napisać jak urządzenie ma odpowiadać na zewnętrzne wywołanie.
    Aby lepiej zrozumieć w jaki sposób procesor odpowiada na zewnętrzne wywołania USB należy przybliżyć działanie trzech podstawowych funkcji. Ale to w następnej części

    ------------------------ [ Dodano po: 16 minutach ]

    Dwie funkcje

    Jak wspominałem w części poprzedniej aby zacząć pisanie programów do komunikacji USB należy poznać dwie, no może trzy podstawowe funkcje służące do komunikacji URZĄDZENIE-KOMPUTER.

    Pierwszą funkcją, która musi być zawsze zdefiniowana jest usbFunctionSetup(uchar dane[8]). Wywołując wezwanie USB z poziomu komputera uruchamiana jest zawsze ta funkcja. Jej wywołanie z poziomu procesora jest następujące:



    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    usbRequest jest zdefiniowany następująco

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.




    Wszystkie dane są przekazywane od strony komputera poprzez funkcje wywołującą działanie programu poprzez USB ale co i jak napiszę w kolejnej części. W tej chwili zajmiemy się tylko funkcjami usbFunctionSetup, usbFunctionRead oraz usbFunctionWrite.

    bmRequestType - informuje sterownik o tym czy chcemy dane przesyłać z czy do urządzenia

    bRequest - rodzaj wywołania (zazwyczaj ustalane przez programiste)

    twValue - wartość przesyłana do urządzenia

    twIndex - index (w rzeczywistości kolejna wartość wysyłana przez programistę)

    twLength - ilość danych


    Funckie usbFunctionSetup możemy wykorzystać do wysyłania danych statycznych. Jeśli chcemy przesyłać dane odczytywane "w locie" winnismy użyć funkcji usbFunctionRead.

    Przyszedł zatem czas na napisanie przykładowego programu służącego do zapalenia i gaszenia diody i przy okazji przesłania jakiegoś krótkiego tekstu np nazwy urządzenia. Ponieważ już wiadomo jak skonfigurować sterownik (patrz USB - AVR - biblioteka VUSB - część I) więc ten etap pominę.
    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Mam nadzieję, że choć trochę rozjaśniłem sposoby komunikacji URZĄDZENIE<-->KOMPUTER poprzez USB. W następnej części wytłumaczę jak można przekazywać większą ilość danych niż 8 znaków (w dwie strony) oraz jak porozumiewać się z naszym procesorem z poziomu komputera (WIN/LINUX). Napiszę też trochę informacji na temat numerowania VENDOR/DEVICE aby pozostać legalnym.

    _________________
    Pomysły na podpis - wyślij SMSa +1 769 243 0011



    Góra
     Zobacz profil  
     
    PostNapisane: 27 lut 2014, o 20:31 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 22 cze 2013
    Posty: 988
    Lokalizacja: Byram, MS 39272
    Pomógł: 55

    usbFunctionRead();

    Przyszedł czas na wytłumaczenie w jaki sposób przesyłać większe ilości danych odczytywanych w locie. Do tego celu służy procedura usbFunctionRead(). Jednakże żeby jej użyć należy najpierw w pliku usbconfig.h zmienić

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.




    na
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    To umożliwi wykorzystanie tej funkcji w naszym programie. Dobrze, zatem czas napisać do czego właściwie służy ta funkcja. Otóż jest ona wywoływana w chwili gdy sterownik żąda wysłania jakichś danych z naszego urządzenia. Na początku wywoływana jest zawsze funkcja usbFunctionConfig(), a następnie wywoływana jest jedna z funkcji usbFunctionRead() lub usbFunctionWrite(). W rzeczywistości jest tak, że funkcja Read służy do wysyłania danych z urządzenia, a funkcja Write do odczytywania danych przychodzących. Żeby jednak nastąpiło wywołanie jednej z tych funkcji to funkcja Setup musi zwrócić wartość USB_NO_MSG tak jak w przykładzie poniżej.
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Funkcję usbFunctionRead() można wykorzystać np do odczytu większej ilości danych z pamięci EEPROM. Mozliwości jest wiele to tylko jeden z przykładów ale warto pamiętać jedną aczkolwiek bardzo ważną rzecz. Mianowicie to, że funkcja ta zwraca max 254 bajtów. Jakby jednak ktoś chciał to da się zwiększyć ilość danych przesyłanych przez nasz program do komputera. Aby to zrobić należy:

    ustawić zmienną USB_CFG_LONG_TRANSFERS na 1 w pliku usbconfig.h.
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    to pozwoli nam na przesyłanie danych powyżej 254 bajtów. Oczywiście powoduje to także zwiększenie ilości zajętej pamięci naszego procesora przez sterownik.

    Teraz możemy wysyłać do hosta więcej niż 254 bajty.

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Jak widać w powyższym przykładzie funkcja usbFunctionRead() wysyła dane poprzez wskaźnik uchar *data. Dane trafiaja wprost do naszego hosta. Pamiętać należy, że funkcja MUSI zwrócić dokładną liczbę wysłanych danych. Jeżeli funkcja zwróci mniejszą liczbę program na komputerze nie będzie w stanie odczytać wszystkich bajtów wysłanych przez urządzenie, jeżeli zwróci większą liczbę niż liczba wysłanych danych to program się wysypie próbując odczytać nieistniejące dane.

    Jeśli z jakichś powodów wewnątrz funkcji wystąpi błąd (np odczytując dane z EEPROM okaże się, że jest błąd odczytu) można poinformować sterownik o błędzie wysyłając jako wynik działania funkcji wartość (-1) 0xff.

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    To poinformuje sterownik i nasz program o tym, że wystąpił błąd.

    Bardziej wnikliwi użytkownicy mogą spróbować przeanalizować działanie funkcji usbReadWrite() czytając źródła USBasp dostępne pod adresem https://github.com/whitequark/usbasp/blob/master/main.c

    Dyskusja na temat http://forum.atnel.pl/post71949.html#p71949
    Różowo-zielony (czyli s...[śliczny] - cenzura mirekk36 ;) ) J.

    _________________
    Pomysły na podpis - wyślij SMSa +1 769 243 0011



    Góra
     Zobacz profil  
     
    PostNapisane: 20 sie 2014, o 09:17 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 22 cze 2013
    Posty: 988
    Lokalizacja: Byram, MS 39272
    Pomógł: 55

    usbFunctionWrite()

    Tak jak pisałem wyżej funkcja ta służy do odbierania danych wysyłanych do urządzenia. Np. w programatorze USBasp wysyłamy ciąg danych z PC do programatora, które mają zostać zapisane w programowanym procesorze. Odbiór danych z PC odbywa się właśnie poprzez funkcję usbFunctionWrite()
    Składnia funkcji jest następująca (odrazu z małym przykładem wykorzystania)
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Jak widać składnia i działanie jest bardzo podobne do usbFunctionRead(). Powyższy przykład pokazuje jak zapisać dane do bufora w pamięci RAM.

    To przyszedł czas na

    USB <--> PC

    W tej części kursu postaram się pokazać na prostym przykładzie jak przy pomocy programu napisanego w C (np. VISUAL C++) pod Windows porozumiewać się z naszym urządzeniem. Takie hello world przy pomocy V-USB. Na początek program zapalający i gaszący diodę po naciśnięciu przycisku zapal/zgaś na ekranie naszego komputera. Ale zanim to nastąpi omówię w jaki sposób podłączać i wyszukiwać nasze urządzenie z poziomu programu PC.



    Po pierwsze trzeba dołączyć plik nagłówkowy pozwalający na komunikacje z USB. Plik ten uzyskamy zmieniając nazwę lusb0_usb.h na usb.h z katalogu sterowników libusb, które musimy zainstaloać (te same, które instaluje się żeby móc korzystać z USBasp)

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Od tej chwili możemy korzystać z połączenia AVR<->PC poprzez USB. Oczywiście wcześniej należy użyć odpowiednich funkcji.

    Na początek stwórzmy przycisk, którym będziemy sprawdzać czy nasze urządzenie jest włożone do gniazda i jeśli jest to połączymy je z programem.

    Do tego celu służą instrukcje

    usb_find_busses(); //************************** szukamy portów USB
    usb_find_devices(); //************************** szukamy urządzeń

    Nastepnie musimy przeszukać uzyskaną w ten sposób bazę podłączonych rządzeń w celu znalezienia naszego. Nasze urządzenie rozpoznajemy poprzez VendorID oraz ProductID, które ustaliliśmy wcześniej w naszym programie


    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    W ten sposób podłączamy nasze urządzenie pod nasz program. Flaga is_connected jest ustawiana w chwili gdy w zmiennej usb_handle znajdzie się hak do naszego urządzenia.

    OK, mamy podłączone urządzenie do programu. Można wysłać pierwszą wiadomość. Informacje wysyła się przy użyciu funkcji usb_control_msg(), która ma następującą składnie

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    A w wyniku zwraca liczbę otrzymanych bajtów lub (-1) w przypadku błędu. (http://libusb.sourceforge.net/doc/function.usbcontrolmsg.html)



    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Zapewne wielu z was zastanawia się czym jest ten zestaw komend/poleceń USB_TYPE_VENDOR | USB_RECIP_DEVICE |USB_ENDPOINT_IN

    Otóż jeżeli wykorzystujemy metodę usbFunctionWrite(), która służy do odczytywania danych wysyłanych z PC (lub innego urządzenia) powinniśmy użyć tej składni

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Jeżeli natomiast dane odczytujemy z naszego urządzenia to korzystamy z takiego zestawu

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Więcej informacji na http://vusb.wikidot.com/host-software, a ja za chwilę wytłumaczę znaczenie poszczególnych poleceń

    _________________
    Pomysły na podpis - wyślij SMSa +1 769 243 0011



    Góra
     Zobacz profil  
     
    Wyświetl posty nie starsze niż:  Sortuj wg  
    Utwórz nowy wątek Ten wątek jest zablokowany. Nie możesz w nim pisać ani edytować postów.  [ Posty: 3 ] 

    Strefa czasowa: UTC + 1


    Kto przegląda forum

    Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 gości


    Nie możesz rozpoczynać nowych wątków
    Nie możesz odpowiadać w wątkach
    Nie możesz edytować swoich postów
    Nie możesz usuwać swoich postów
    Nie możesz dodawać załączników

    Szukaj:
    Skocz do:  
    Sitemap
    Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
    phpBB SEO