Skocz do zawartości

Kurs STM32 F4 - #4 - Pierwszy projekt, GPIO, przerwania


Komentator

Pomocna odpowiedź

Witam serdecznie, to mój pierwszy post i pytanie na które nie znalazłem konkretnej odpowiedzi ( przynajmniej nie w moim przypadku)

Mam nucleo z stm32f091rc wiec nie jest to w 100% kompatybilne, ale internet pomaga 🙂 Z mikrokontrolerami miałem tylko do czynienia kilka lat temu i to z mcs-51 i troche z arduino.

W System Workbench for stm 32 wyświetla mi się taki komunikat:

Info : auto-selecting first available session transport "hla_swd". To override use 'transport select '.

Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD

adapter speed: 1000 kHz

adapter_nsrst_delay: 100

srst_only separate srst_nogate srst_open_drain connect_assert_srst

srst_only separate srst_nogate srst_open_drain connect_assert_srst

Info : Unable to match requested speed 1000 kHz, using 950 kHz

Info : Unable to match requested speed 1000 kHz, using 950 kHz

Info : clock speed 950 kHz

Error: libusb_open() failed with LIBUSB_ERROR_NOT_SUPPORTED

Info : STLINK v2 JTAG v27 API v2 M v15 VID 0x0483 PID 0x374B

Info : using stlink api v2

Info : Target voltage: 72.811768

Info : stm32f0x.cpu: hardware has 4 breakpoints, 2 watchpoints

Info : Unable to match requested speed 1000 kHz, using 950 kHz

Info : Unable to match requested speed 1000 kHz, using 950 kHz

adapter speed: 950 kHz

stm32f0x.cpu: target state: halted

target halted due to debug-request, current mode: Thread

xPSR: 0xc1000000 pc: 0x08000564 msp: 0x20008000

Info : Unable to match requested speed 8000 kHz, using 4000 kHz

Info : Unable to match requested speed 8000 kHz, using 4000 kHz

adapter speed: 4000 kHz

** Programming Started **

auto erase enabled

Info : device id = 0x10006442

Info : flash size = 256kbytes

stm32f0x.cpu: target state: halted

target halted due to breakpoint, current mode: Thread

xPSR: 0x61000000 pc: 0x2000003a msp: 0x20008000

wrote 4096 bytes from file Debug/first.elf in 0.194521s (20.563 KiB/s)

** Programming Finished **

** Verify Started **

stm32f0x.cpu: target state: halted

target halted due to breakpoint, current mode: Thread

xPSR: 0x61000000 pc: 0x2000002e msp: 0x20008000

stm32f0x.cpu: target state: halted

target halted due to breakpoint, current mode: Thread

xPSR: 0x61000000 pc: 0x2000002e msp: 0x20008000

verified 2976 bytes in 0.030080s (96.617 KiB/s)

** Verified OK **

** Resetting Target **

Info : Unable to match requested speed 1000 kHz, using 950 kHz

Info : Unable to match requested speed 1000 kHz, using 950 kHz

adapter speed: 950 kHz

shutdown command invoked

Ale przez st-link utlinty wszystko jest ok, (czasami gubi połaczenie) da się normalnie zaprogramować i wyczyścić. Przez SW for stm32 chyba też działa, ale czasami przy debuggowaniu coś nie wygląda to jak trzeba. Zastanawia mnie o co chodzi z tymi komunikatami "Unable to match requested speed" i czy jest się czym martwić ? 🙂

Z góry dzięki i pozdrawiam.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

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

Witam kolegów

Mam pytanie dotyczące zadania do samodzielnej realizacji. Wykonałem własne rozwiązanie oraz sprawdziłem rozwiązanie dołączone do artykułu i oba nie działają w pełni poprawnie.

W obu przypadkach zmieniono typ przerwania na reakcję na jedno ze zboczy (co widzę w kodzie z rozwiązaniem).

Ja wykorzystuję funkcję switch, analogiczne rozwiązanie jest do pobrania z funkcją if. Cała reszta jest identyczna.

Chodzi o drganie styków, którego nie eliminuje wbudowany układ tłumienia (sprzętowy). Czy możemy to ograniczyć programowo? Przyszło mi do głowy wykorzystanie opóźnienia zadziałania ewaluacji przypadku wciśnięcia, ale nie wydaje mi się, żeby dało się korzystać z timera wewnątrz przerwania wywołanego zboczem. Prosiłbym o pomoc.

Link do komentarza
Share on other sites

raFFcio, witam na forum 🙂 Jeśli program działa poprawnie reagując tylko na jedno ze zboczy, to nie dorabiałbym problemów zmieniając sposób wyzwalania przerwania - chyba, że gdzieś jeszcze z tego korzystasz(?).

Najprościej zastosować filtr RC (ostatecznie doszliśmy do wniosku, że chyba na płytkach jednak go nie ma... można go dolutować). Metod ograniczania programowego drgania styków jest wiele. Można np. w momencie wykrycia przerwania ustawiać sobie zmienną pomocniczą na 1, która jest regularnie zerowana przez timer co kilka milisekund. Wtedy przy wywołaniu przerwania sprawdzamy, czy zmienna ma wartość 1, czy 0. Jeśli jej wartość to 1, tzn., że przerwanie wystąpiło bardzo szybko jedno, po drugim (więc to drgania styków), jak mamy 0, tzn., że jest to pierwsze przerwanie od wciśnięcia.

Link do komentarza
Share on other sites

Witaj

Niestety wyraźnie w przypadku wgrania obu plików binarnych przerwanie jest wykonywane wielokrotnie.

Wobec tego dwa pytania:

1. Czy możemy używać timera wewnątrz przerwania od przycisku?

2. Sposób ze zmienną, o którym mówisz - czy mógłbyś zaprezentować fragment kodu? Bo nie do końca rozumiem kiedy i jak miałoby następować przypisanie i sprawdzanie warunku.

Link do komentarza
Share on other sites

Czy możemy używać timera wewnątrz przerwania od przycisku?

A dlaczego chcesz go używać wewnątrz przerwania? Spróbuj zrobić tak, że przerwanie od przycisku jedynie ustawia jakąś zmienną (flagę) i od razu wychodzimy wtedy z przerwania. Inne operacje powinny dziać się już poza przerwaniem. Oczywiście wewnątrz przerwania można też dodać warunek sprawdzający, czy zmienna pomocnicza ma wartość 0, czy 1. Głównie chodzi o to, aby wewnątrz przerwania na nic nie czekać. Dawno nie pisałem już nic na STMy, więc nie chcę teraz wprowadzać Cie w błąd programami pisanymi "z głowy" 🙂

Niezależnie od tego polecam jednak iść dalej z kursem - w kolejnych częściach jest więcej informacji chociażby o timerach, które powinny rozwiać Twoje wątpliwości 🙂

Link do komentarza
Share on other sites

Witam, własnie przerabiam ten poradnik na płytce STM32F4 Nucleo F446ZE. Próbowałem zrobic zadanie domowe postępując według poradnika, sugerowałem się także już zzrobioną pracą domową, lecz mam problem.

Nie mam kontroli nad zapalanymi się diodami (posiadam 3: czerwona, niebieska i zielona). Raz zapalają się 2 na raz, raz wszystkie gasną, nie mam takiej sekwencji jak powinna być czyli zapala się jedna, później druga, później trzeba itd. Czy ktoś wie czemu tak może być?

Oto mój kod:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
static uint8_t state = 0;
if (GPIO_Pin == Button_Pin) {
	if (state == 1) {
		HAL_GPIO_TogglePin(Led_Red_GPIO_Port, Led_Red_Pin);
//		HAL_Delay(0);
	} else if (state == 2) {
		HAL_GPIO_TogglePin(Led_Blue_GPIO_Port, Led_Blue_Pin);
//		HAL_Delay(80);
	} else if (state == 3) {
		HAL_GPIO_TogglePin(Led_Green_GPIO_Port, Led_Green_Pin);
	}
	++state;
	if (state == 4) {
		state = 0;
	}

}
}
Link do komentarza
Share on other sites

słyszałem słyszałem, jak widać w programie nawet próbowałem tego użyć, ale po użyciu własnie delay żadna dioda się nie zapalała. Zdziwiło mnie to, bo według kursu funkcja opóźniająca, przyjmująca jako parametr czas opóźnienia w milisekundach to własnie

HAL_Delay(delay_time_in_miliseconds)

Nawet jeśli, to kopiując jużgotowy fragment bez Delay, usuwając 1 diodę (bo u mnie są 3) i zmieniając parametry program powinien działać w taki sam sposób jak na filmie umieszczonym w kursie, a tak nie jest.

Link do komentarza
Share on other sites

Używanie opóźnień w przerwaniach to bardzo zła praktyka. Dodatkowo, w zależności od tego jak taka funkcja delay jest zaimplementowana, delay może nie działać

Link do komentarza
Share on other sites

Ja próbowałem w różny sposób poradzić sobie z drganiem styków w zadaniu domowym, ale jak dotąd bezskutecznie. Jeżeli na płytce faktycznie znajduje się sprzętowy filtr to nie spełnia swojego zadania.

Próbowałem również w przerwaniu ustawiać jedynie flagę, a obsługę zapalania odpowiednich diod LED w programie głównym. Nie przyniosło to rezultatu. Domyślam się, że w trakcie wykonywania polecenia włączenia/wyłączenia diod LED musi występować przerwanie od drgania styku i ponownie załącza flagę. Próbowałem w takim przypadku wyłączyć przerwania na chwilę (co oczywiście wiem, że nie jest zalecane, ale zależało mi żeby to uruchomić poprawnie). Bez rezultatu.

Sprawdzałem też wyjście przycisku względem GND na oscyloskopie i co ciekawe drgania styków występują, ale nie mają amplitudy sięgającej 3V.

Link do komentarza
Share on other sites

Używanie opóźnień w przerwaniach to bardzo zła praktyka. Dodatkowo, w zależności od tego jak taka funkcja delay jest zaimplementowana, delay może nie działać

W takim razie znasz jakiś sposób, żeby to zadziałało tak jak powinno?

Link do komentarza
Share on other sites

W moich układach w takich przypadkach stosuję przerzutnik Schmitta z filtrem RC. Sam filtr RC obecny na płytce jest niewystarczający, bo na zboczu na pinie mikrokonrolera i tak pojawiają się zakłócenia, które skutkują wielokrotnym wyzwalaniem przerwania.

W takim razie znasz jakiś sposób, żeby to zadziałało tak jak powinno?

Tzn. żeby drgania nie powodowały wielu przerwań? Jeden to sprzętowa eliminacja, a drugi to manewry programowe, czyli np. po pojawieniu się przerwania ustawienie flagi mówiącej 'ignoruj przerwania', która po np. 50ms będzie zresetowana w głównej pętli.

  • Lubię! 1
Link do komentarza
Share on other sites

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!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.