Komentator Napisano Wrzesień 24, 2015 Udostępnij Napisano Wrzesień 24, 2015 W poprzedniej części kursu STM32 nauczyliśmy się tworzyć projekt, kompilować oraz uruchamiać prosty program. Niestety był on mało atrakcyjny, bo nie komunikował się ze światem zewnętrznym.Czas więc poznać okno na świat każdego układu, czyli uniwersalne porty wejścia/wyjścia (GPIO). 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. Cytuj Link do komentarza Share on other sites More sharing options...
poczciwy Wrzesień 24, 2015 Udostępnij Wrzesień 24, 2015 A jak z drganiami styków w przycisku ? podobnie jak w AVR czy może są gaszone w jakiś inny sposób. Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Wrzesień 24, 2015 Udostępnij Wrzesień 24, 2015 STM32F103RB nie posiada sprzętowego układu przeciwdziałającemu drganiu styków (debouncer). Na płytce Nucleo znajdziemy filtr RC, który sprzętowo zmniejszy dokuczliwość drgania styków. Natomiast w przypadku podłączania pozostałych mikroswitch-y musimy drganiami zająć się samemu - sprzętowo lub programowo. Cytuj Link do komentarza Share on other sites More sharing options...
Gumili Wrzesień 24, 2015 Udostępnij Wrzesień 24, 2015 Elvis, A jak programowo zrobić takie zabezpieczenie, jeśli chce się również korzystać z przerwań? Czy przerwania się nie kolejkują? Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
Elvis Wrzesień 24, 2015 Udostępnij Wrzesień 24, 2015 Jak zrobić poprawnie obsługę przerwań to właśnie jest praca domowa 🙂 A tak serio, temat jest nieco zbyt obszerny na niniejszy kurs - chociaż liczę, że kilka dobrych przykładów się pojawi. Przerwania w STM32 są dość skomplikowanym tematem. Po pierwsze nie są kolejkowane (tzn. są, ale jest to kolejka 1-elementowa). Jeśli przerwanie nie może być obsłużone natychmiast, bo np. procesor jest w trakcie obsługi innego przerwania, zostanie ono obsłużone w najbliższym możliwym czasie. Jeśli jednak w czasie tego "oczekiwania" przerwanie zostanie wygenerowane ponownie, to zostanie po prostu zgubione. Dlatego wszystkie dobre poradniki mówią, że procedury obsługi przerwań powinny być możliwie krótkie. W przypadku STM32 dochodzą jeszcze priorytety przerwań oraz możliwość wywłaszczenia procedury obsługi przerwania przez przerwanie o wyższym priorytecie. Cytuj Link do komentarza Share on other sites More sharing options...
kost Wrzesień 24, 2015 Udostępnij Wrzesień 24, 2015 Dla osób które posiadają, tak jak ja, Nucleo seria z STM32F3xx, polecam: http://www.st.com/web/en/resource/technical/document/application_note/DM00073522.pdf Dokument opisuje jak przejść z STM32F1xx na STM32F3xx Tak wygląda migająca dioda po przystosowaniu dla STM32F3xx #include "stm32f30x.h" void delay(int time) { int i; for (i = 0; i<time*4000; i++){} } int main(void) { GPIO_InitTypeDef gpio; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); GPIO_StructInit(&gpio); gpio.GPIO_Pin = GPIO_Pin_5; gpio.GPIO_Mode = GPIO_Mode_OUT; gpio.GPIO_OType = GPIO_OType_PP; GPIO_Init(GPIOA, &gpio); while (1) { GPIO_SetBits(GPIOA, GPIO_Pin_5); delay(100); GPIO_ResetBits(GPIOA, GPIO_Pin_5); delay(400); } } Mam pytanie, ustawiłem pin 5 jako wyjście gpio.GPIO_Mode = GPIO_Mode_OUT; i dioda mrugała, jednak w przykładzie dla STM32F1xx wyjście jest typu push-pull, więc dodałem jeszcze: gpio.GPIO_OType = GPIO_OType_PP; słusznie czy nie? bo nie widzę różnicy w działaniu. Cytuj Link do komentarza Share on other sites More sharing options...
mopsiok Wrzesień 25, 2015 Udostępnij Wrzesień 25, 2015 Dzięki za kolejny odcinek, wczoraj przyszedł do mnie zestaw, także miałem już okazję się pobawić 🙂. Niezdecydowanym zdecydowanie polecam 😅 Cytuj Link do komentarza Share on other sites More sharing options...
kulawikm Wrzesień 25, 2015 Udostępnij Wrzesień 25, 2015 poprawione ... 1 Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Wrzesień 25, 2015 Udostępnij Wrzesień 25, 2015 kulawikm, dzięki za czujność 🙂 Napiszę do Treker-a, żeby zmienił, ja już nie mam takich uprawnień. Na usprawiedliwienie mogę tylko napisać, że cały program powinien działać bez problemu. W początkowych wersjach tekstu używałem, podobnie jak przykłady od ST, długich nazw zmiennych - i jak widać tutaj zostało po staremu. Cytuj Link do komentarza Share on other sites More sharing options...
Treker (Damian Szymański) Wrzesień 26, 2015 Udostępnij Wrzesień 26, 2015 kulawikm, dzięki za informacje - poprawione! Cytuj Link do komentarza Share on other sites More sharing options...
Gumili Wrzesień 27, 2015 Udostępnij Wrzesień 27, 2015 No to czas na podsumowanie mojej nauki:) Po pierwsze, wg. mnie jest drobna literówka, mianowicie zmienna SystemCoreClock jest w pliku system_stm32f10x.c, a nie system_stm32f10x.h 🙂 Druga rzecz: Podczas rozwiązywania zadań domowych, zauważyłem że użycie triggera EXTI_Trigger_Rising_Falling "symuluje" zastosowanie filtru (w porównaniu do triggera EXTI_Trigger_Rising) No i na koniec załączam zadania domowe (mam nadzieję, że można) 🙂 zadanie_4.1.c zadanie_4.2.c zadanie_4.3.c zadanie_4.4.c Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Wrzesień 27, 2015 Udostępnij Wrzesień 27, 2015 Gumili, fajnie że chciało Ci się rozwiązać zadania 🙂 Co do zmiennej SystemCoreClock, to nie jest literówka. W języku C rozróżniamy deklarację i definicję, zmiennej, czy też funkcji. Deklaracja informuje kompilator, co nazwa (identyfikator) będzie oznaczała. Przykładowo zmienną o określonym typie. Definicja przydziela pamięć dla zmiennej, albo określa treść funkcji. Przykłady deklaracji: extern int x; void magic_function(void); Przykłady definicji: int x = 5; void magic_function(void) { printf("%d\n", x); } Definicja jest jednocześnie deklaracją. Deklaracji używa się, żeby móc używać danego typu/funkcji jeszcze przed jej zdefiniowaniem. Przykładowo możemy wywołać funkcję, którą zadeklarowaliśmy, ale jej kod jest zdefiniowany później. Co ważne definicja danego obiektu może wystąpić tylko raz w całym programie (inaczej wystąpi błąd podczas linkowania). Natomiast deklaracje mogą pojawiać się wielokrotnie. Najczęściej deklaracje umieszczane są w plikach o rozszerzeniu .h. Dzięki temu pozostałe moduły mogą odwoływać się do tych identyfikatorów, nawet jeśli nie zostały jeszcze zdefinowane. W plikach z kodem .c umieszczane są definicje (oczywiście pasujace do wcześniejszych deklaracji). [ Dodano: 27-09-2015, 11:45 ] Jak chodzi o EXTI_Trigger_Rising_Falling i EXTI_Trigger_Rising to różnica nie polega na filtracji, ale wykrywaniu zbocza sygnału. Jeśli przycisk jest zwolniony, to na wejściu procesora pojawia się sygnał wysoki (logiczne 1, czyli 3.3V). Gdy naciskamy przycisk, zwieramy pin do masy, stan zmienia się na niski (logiczne 0, inaczej 0V). Zmiana ze stanu wysokiego na niski to zbocze opadające. Może być wykryte jeśli reagujemy na zdarzenie EXTI_Trigger_Falling. Jeśli po pewnym czasie zwolnimy przycisk, stan zmieni się z niskiego na wysoki, co odpowiada pojawieniu się zbocza narastającego, czyli EXTI_Trigger_Rising. Ustawienie flagi EXTI_Trigger_Rising_Falling pozwala na wykrywanie obu zboczy, czyli zarówno przyciskania, jak i zwalniania przycisku. Przygotowując ćwiczenia myślałem, że będzie więcej problemów z drgajacymi stykami. Jednak filtr RC skutecznie temu przeciwdziała. Proponuję więc małą zmianę w pracy domowej - podłącz zewnętrzny mikroswitch i porównaj działanie układu 🙂 [ Dodano: 27-09-2015, 11:51 ] A do aktualnej wersji zadań - czy jeśli kilka razy naciskasz przycisk, program zawsze zachowuje się poprawnie? Przykładowo po naciśnięciu 4 razy program 4.1 powinien sterować diodamy w tym samym kierunku co wcześniej, czy zawsze tak jest? Podobnie program 4.2 - czy szybko naciskając 4 razy, zawsze zapalimy odpowiednią diodę? Cytuj Link do komentarza Share on other sites More sharing options...
kost Wrzesień 27, 2015 Udostępnij Wrzesień 27, 2015 Mam problem z obsługą przerwań w moim STM32F303RE, nie mogę zlokalizować problemu, wszystko wykonałem zgodnie z kursem, zmieniając oczywiście pod STM32F3, np.: RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //Aktywacja funkcji alternatywnych SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource13); //wybór linii i portu W pętlę while włożyłem kod z przesuwającą się diodą LED na linijce świetlnej, żeby móc obserwować pracę mikrokontrolera. Po naciśnięciu przycisku główny program się zatrzymuje i na tym koniec. Dioda LED na płytce Nucleo nie zapala się. Wygląda to tak jakby przerwanie zostało wywołane i mikrokontroler w nim pozostał. Gdzie może być błąd? Czy dla STM32F3 obsługa przerwań jest inna? Zastosowałem wszystkie wymagane zmiany według dokumentu: http://www.st.com/web/en/resource/technical/document/application_note/DM00073522.pdf Cytuj Link do komentarza Share on other sites More sharing options...
maciekmiszcz Wrzesień 29, 2015 Udostępnij Wrzesień 29, 2015 Witam! Dziś zacząłem bawić się nową płytką (STM32F0 Discovery) i napotkałem na taki błąd: ../src/main.c: In function 'main': ../src/main.c:14:28: error: 'RCC_APB2Periph_GPIOC' undeclared (first use in this function) RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // uruchomienie zegara modulu GPIO ^ ../src/main.c:14:28: note: each undeclared identifier is reported only once for each function it appears in ../src/main.c:18:22: error: 'GPIO_Mode_Out_PP' undeclared (first use in this function) gpio.GPIO_Mode = GPIO_Mode_Out_PP; // jako wyjscie ^ make: *** [src/main.o] Error 1 Oczywiście zmieniłem port diody na taki jest w mojej płytce. Czy błędy te wynikają z faktu iż mój układ bazuje na M0 a nie na M3? __________ Komentarz dodany przez: Treker Pamiętaj na przyszłość, aby kody i logi umieszczać w tagach , tym razem poprawiłem 🙂 Cytuj Link do komentarza Share on other sites More sharing options...
torcek Wrzesień 29, 2015 Udostępnij Wrzesień 29, 2015 Porty GPIO STM32F0 znajdują się na szynie AHB (dokumentacja). Dodatkowo, biblioteki STM32F3 i STM32F0 różnią się między sobą, nie ma tutaj "GPIO_Mode_Out_PP". Poniżej przykładowa inicjalizacja pinu 8 portu C RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOC, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOC, &GPIO_InitStructure); Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!