HomeMade

Pełna wersja: Programowanie ARM, nauka, środowiska programistyczne IDE
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Stron: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Trochę się pogubiłem w temacie utworzonych MACR dla LEDów. Prosiłbym o przybliżenie tematu, zarówno do Z003, jak i wcześniejszego Z001v3, gdzie macra były zastosowane po raz pierwszy.
Rysio!
Ryszard, makra generalnie mają za zadanie poprawić czytelność kodu i ułatwić jego modyfikację. Przykład: sterujemy diodą LED.

Klasyczne rozkazy na rejestrach do sterowanie diodą LED wyglądają tak:

Kod:
GPIOG->BSRRL = GPIO_Pin_14;  //1->LED, dioda świeci
GPIOG->BSRRH = GPIO_Pin_14;  //0->LED, dioda gaśnie

Jeśli w dużym programie trafisz na taką linię kodu to bez schematu nie wiesz praktycznie nic.

Kod:
GPIOG->BSRRL = GPIO_Pin_14;

Wiadomo, że zmieniasz stan na nodze procesora i tyle, nawet nie wiesz czy taki rozkaz włącza urządzenie czy wyłącza bo dioda może być podwieszona do zasilania lub do masy. Aby kod był bardziej czytelny należy posługiwać się własnymi nazwami opisującymi sterowane elementy systemu, w tym przypadku LED_RED.

Kod:
#define LED_RED_GPIO        GPIOG
#define LED_RED_RCC        RCC_AHB1Periph_GPIOG
#define LED_RED_PIN         GPIO_Pin_14
#define LED_RED_OFF         LED_RED_GPIO->BSRRH = LED_RED_PIN       //niski stan na pinie
#define LED_RED_ON           LED_RED_GPIO->BSRRL = LED_RED_PIN       //wysoki stan na pinie


Dla naszej diody definiujemy port, zegar taktujący dla portu, maskę pinu oraz makra ON/OFF. W definicji makra jest również zawarta informacja o sposobie włączania diody (zerem czy jedynką). Teraz w programie jak chcesz zapalić LED_RED to nie musisz pamiętać na jakim porcie i pinie masz tą diodę ani tego, że włączanie jest jedynką, po prostu piszesz:

Kod:
LED_RED_ON;    // zamiast: GPIOG->BSRRL = GPIO_Pin_14;

Każdy kto widzi taki rozkaz (makro) od razu wie co on robi, kod jest czytelny a program krótszy i łatwiejszy w pisaniu. Dodatkową zaletą stosowania makr jest bardzo łatwa zmiana konfiguracji sterowania. Jeśli musimy zmienić pin diody z pin_14 na pin_12 to poprawiamy tylko definicję jednego makra bez konieczności szukania w całym kodzie programu.

Makra mogą być również bardziej rozbudowane np. z parametrami.

Kod:
#define _gpio_mode_set(gpio,pin_maska)      gpio->MODER   |= pin_maska       //ustawia tryb pracy pinow na porcie

Mamy zdefiniowane makro do konfiguracji pinów portu. nasz pin_14 dla diody LED_RED może pracować w czterech trybach:

Kod:
//domyślny po resecie INPUT oraz
#define GPIO_14_MODE_OUT    ((uint32_t)0x10000000)
#define GPIO_14_MODE_AF     ((uint32_t)0x20000000)
#define GPIO_14_MODE_ANL    ((uint32_t)0x30000000)

Aby skonfigurować nasz pin dla diody jako wyjście wpisujemy:

Kod:
_gpio_mode_set(GPIOG, GPIO_14_MODE_OUT);  //na rejestrach lub
_gpio_mode_set(LED_RED_GPIO, LED_RED_MODE);  //nazwy symboliczne

Ważne jest aby na początku nie mylić numeru pinu, numeru trybu z maską pinu, maską trybu bo to zupełnie co innego.
Dzięki za wyjaśnienia, to rozjaśnia czytanie programu.
Rysio!
Te makra w programie dla procesara nic nie zmieniaja, funkcje zawsze sa takie same. Znienia sie tylko zapis programu. Obsluga enkodera jest niepokojaco krotka w porownaniu do przykadow z internetu. Zastanawia mnie czy bedzie to poprawnie pracowalo z roznymi enkoderami. Chwilowo nie mam jak testowac, urlop poza domem.
Przepraszam za brak polskich liter (telefon).
(26-07-2016 10:48)QRP73 napisał(a): [ -> ]Obsluga enkodera jest niepokojaco krotka w porownaniu do przykadow z internetu.

Długi kod to źle bo trudno go zrozumieć, za krótki też niedobrze bo to niemożliwe żeby te kilka linijek mogły robić to samo co rozbudowane funkcje. Wychowałem się na małych procesorach i generalnie jestem zwolennikiem prostych i szybkich aplikacji, lubię rejestry i przerwania. Obsługę encodera można zrobić na kilka sposobów, ten jest najprostszy i u mnie działa poprawnie. Nic nie stoi na przeszkodzie aby zaprezentować własne rozwiązanie tego zadania.

Po pierwszych postach w tym wątku widziałem duży potencjał grupy i spodziewałem się prezentacji wielu własnych programów oraz ciekawej dyskusji. Niestety na tą chwilę tylko Paweł i ja zamieszczamy działające przykłady. Zachęcam wszystkich, bez tego nie będzie postępów ani w kursie ani nauce.
(26-07-2016 16:20)SP5FCS napisał(a): [ -> ]Długi kod to źle bo trudno go zrozumieć, za krótki też niedobrze bo to niemożliwe żeby te kilka linijek mogły robić to samo co rozbudowane funkcje. Wychowałem się na małych procesorach i generalnie jestem zwolennikiem prostych i szybkich aplikacji, lubię rejestry i przerwania. Obsługę encodera można zrobić na kilka sposobów, ten jest najprostszy i u mnie działa poprawnie.

stawiam piwo ;-) (i chylę czoła)

73
MAciek
(26-07-2016 16:20)SP5FCS napisał(a): [ -> ]Po pierwszych postach w tym wątku widziałem duży potencjał grupy i spodziewałem się prezentacji wielu własnych programów oraz ciekawej dyskusji. Niestety na tą chwilę tylko Paweł i ja zamieszczamy działające przykłady. Zachęcam wszystkich, bez tego nie będzie postępów ani w kursie ani nauce.

Proszę mnie nie martwić, gdzie ja będę szukał wzorów do naśladowania, już się czegoś nauczyłem, mam dalej szperać po internecie? Na chwilę obecną nie czuję się na siłach pisać swoich programików.
Rysio!
Po co chcemy poznać nowy procesor ?

Zapewne po to aby zrobić kiedyś jakiś fajny przyrząd lub sterownik do radia. Procesor ma bardzo rozbudowane układy peryferyjne, do tego dochodzi wyświetlacz TFT, panel dotykowy, CAT, USB, generator Si5351 lub jakiś DDS, jakieś rejestry do sterowania pasmami, przetworniki ADC do S-metra i SWR-a nie wspominając o kodeku i DSP. Jeśli chcemy zbudować jakiś sterownik radia to jest do opanowania ogromny materiał i trzeba napisać setki funkcji. Jeden człowiek sam tego szybko nie zrobi, a nawet gdyby się uparł i zrobił to niekoniecznie podzieli się kodem.

Jakie więc mamy wyjście ? Jeśli chcemy czegoś się nauczyć i zrobić coś praktycznie to większa grupa uczestników kursu powinna się przyłożyć i coś napisać, potestować, poszperać w dokumentacji czy necie za ciekawymi przykładami. Samo się nie zrobi.

Jak pracuje zwykły enkoder mechaniczny możemy sprawdzić na prostym teście wyświetlacza TFT. Enkoder podłączony tak jak w zadaniu nr. 3.
Enkoderem możemy zmieniać nastawę częstotliwości, krok 10Hz.
Zdjęcie i plik HEX w załączniku.
Witajcie.

Co do makr by wniósł dwie rzeczy.
Po pierwsze, i to jest ważne, w "prawej" części czyli zawartości makra, ujmowanie w nawiasy czegokolwiek bardziej złożonego. Można sobie zrobić kuku, jak kiedyś użyje się makra w kontekście złożonym, np wyrażenia. Są różne szkoły, i święte wojny jak te nawiasy zrobić, ale lepsze (prawie) dowolne, niż żadne.
Po drugie, ja jestem z tych, co makra "akcyjne (przeciwieństwo do "wartości" zwykle stałej w wyrażeniu) markuje nawiasem jak funkcja bezargumentowa

Więc
Kod:
#define LED_RED_ON()    { LED_RED_GPIO->BSRRL = LED_RED_PIN;  }

lub żeby nie wywołać polemiki super-hackerów C, jedna z ambitnych notacji

Kod:
#define LED_RED_ON()    do { LED_RED_GPIO->BSRRL = LED_RED_PIN;  } while(0)

W ogóle jestem zwolennikiem odchodzenia od makr najbardziej jak się da, nowoczesne dialekty C (o C++ nie wspominam) mają funkcje inline, które mają wszystkie zalety makr (generowanie kodu maszynowego w miejscu, bez wywołania call, stosu itd) a nie mają wad i ryzyka.


Aha, makro bezargumentowe nie może koło tych nawiasów mieć spacji
W związku z pytaniami o to jak wgrać plik *.hex do naszej płytki Discovery mając wgrane firmware J-Jink do zintegrowanego programatora, lub podpinając zewnętrznego J-Linka odpowiadam w postaci małego tutoriala.

Chyba nie muszę wspominać, że należy mieć zainstalowane sterowniki J-Linka oraz paczkę z softem J-Link Software and Documentation package pobraną ze strony Segger-a.

1. Uruchamiamy z menu program J-Flash Lite.

2. Klikamy na OK w okienku, które wyskoczy....
[attachment=11262]

3. Uruchomi się J-Flash Lite...
[attachment=11263]

W sekcji Interface należy wybrać SWD, w sekcji SPEED ustawiamy prędkość interfejsu - można zostawić wartość domyślną, zaś w sekcji Device wybieramy nasz STM32F429ZI.

4. Klikamy na przycisk z trzema kropkami (obok pola z napisem unspecifed)
Otworzy się takie oto okienko:
[attachment=11264]

Należy wybrać producenta - ST, a następnie z listy nasz stm32F429ZI, który jest na naszej płytce Discovery.
[attachment=11265]

Po wybraniu klikamy na ok.

5. Teraz zobaczymy takie oto okno:
[attachment=11266]

Należy wybrać plik, który chcemy załadować do stm-a. W tym celu klikamy na przycisk z trzema kropkami, który jest w sekcji Data File.
Otworzy się okno do wyboru pliku...
[attachment=11267]

Wybieramy naszego hex-a i klikamy Otwórz

6. Teraz pora na zaprogramowanie naszego stm-a. Robimy to klikając na długi przycisk z nazwą Program Device
[attachment=11268]

Jeżeli nic nie zostało sknocone, to mamy zaprogramowanego stm-a

W razie problemów, można przed programowaniem, wykasować pamięć stm-a naciskając na Erase Chip.

Oczywiście, program przyjmuje również pliki *.bin, ale w tym wypadku w sekcji .bin / Erase Start należy podać adres:
0x08000000 - jeżeli program jest skompilowany dla pamięci Flash
0x20000000 - jeżeli program jest skompilowany dla uruchamiania z pamięci RAM.

Jeżeli jest coś nie zrozumiałe to śmiało piszcie.....
Stron: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Przekierowanie