Skocz do zawartości

Kurs STM32L4 – #3 – wejścia/wyjścia, czyli GPIO w praktyce


Komentator

Pomocna odpowiedź

@masi23x witam na forum, milo słyszeć, że kurs Ci się podoba 🙂

GPIO_PinState to typ wyliczeniowy, który ma być używany w miejscach, o których wspomniałeś - takie było po prostu założenie twórców tej biblioteki. Więc, jeśli chcemy tworzyć programy zgodnie z dokumentacją to powinniśmy korzystać właśnie z tego typu wyliczeniowego. Jeśli wstawisz tam bezpośrednio 1/0 to postępujesz niezgodnie ze standardem biblioteki. Oprócz tego kompilatory mogą zgłaszać błędy/ostrzeżenia, ponieważ w miejscu na GPIO_PinState podajesz inny typ danych. Jednak ogólnie masz rację, właściwie wychodzi na to samo, bo podglądając deklarację tego typu wyliczeniowego znajdziemy coś takiego:

/** 
* @brief  GPIO Bit SET and Bit RESET enumeration 
*/
 typedef enum
 {
   GPIO_PIN_RESET = 0,
   GPIO_PIN_SET
 }GPIO_PinState;
 /**

Warto jednak trzymać się wytycznych przewidzianych przez projektantów biblioteki. W skrajnym przypadku można sobie wyobrazić, że za jakiś czas biblioteka zostanie przerobiona w taki sposób, że wcale nie będzie tam 1/0 tylko coś zupełnie innego. Jeśli Twój kod będzie bazował na takich ręcznych wstawkach wartości to wtedy nie zadziała poprawnie, jeśli będzie użyty GPIO_PinState to wszystko zadziała poprawnie 🙂 

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

Dlaczego, żeby zmienić stan logiczny np pinu PA5 nie mogę po prostu napisać jak dawniej:
PORTA |= (1<<PA5);
czy
PORTA &= ~(1<<PA5);

przecież to język C, lecz muszę wprowadzać dziwolągi np HAL_GPIO_... itd itp ???

Link do komentarza
Share on other sites

@lzo witam na forum 🙂 W kursie występują takie funkcje i struktury, ponieważ jest to kurs programowania STM32 z wykorzystaniem biblioteki HAL, która właśnie zastępuje tego zapisy, które zaproponowałeś odpowiednimi funkcjami i strukturami. Ma to ułatwić przenoszenie programów między różnymi układami danego producenta oraz wykorzystywanie bardziej zaawansowanych peryferiów. Korzystanie z takiej biblioteki nie jest przymusowe - nadal możesz programować układy tak jak chcesz, czyli metodą "na rejestrach". 

Link do komentarza
Share on other sites

Hej,

Odpowiedzi do zadań (albo i nie :P)
1. Obecnie nie wiem. Próbowałem zrobić to sprzętowo w taki sposób, aby PIN LED1 ustawić jako GPIO output level na HIGH i jakoś automagicznie myślałem, że będzie jakaś inwersja tego sygnału, ale nic to nie dało. Czy do zadania 1 wymagane jest dołozenie na płytce stykowej jakiegoś kolejnego elementu? 😛

2. To już próbowałem wcześniej dla testów i faktycznie tak to działa.

3. Tutaj mój kod:
 

bool is_button_pressed(int button){
	switch (button) {
	case 0:
		if (HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port, USER_BUTTON_Pin) == GPIO_PIN_RESET) {
			return true;
		} else {
			return false;
		}
	case 1:
		if (HAL_GPIO_ReadPin(USER_BUTTON2_GPIO_Port, USER_BUTTON2_Pin) == GPIO_PIN_RESET) {
			return true;
		} else {
			return false;
		}
	case 2:
		if (HAL_GPIO_ReadPin(RESET_BUTTON_GPIO_Port, RESET_BUTTON_Pin) == GPIO_PIN_RESET) {
			return true;
		} else{
			return false;
		}

	default:
		return false;
	}
}



int led = 0;
    led_set(led, true);

    while (1)
    {
  	if (is_button_pressed(0)) {
  		// Po wcisnieciu przycisku wylacz diodę
  		led_set(led, false);

  		// Zwieksz zawartosc zmiennej led
  		led++;
  		// Sprawdz czy nie przekracza zakresu
  		if (led >= 10) {
  		  led = 0;
  		}

  		// Wlacz kolejna diode
  		led_set(led, true);

  		// czekamy na zwolnienie przycisku
  		while (is_button_pressed(0)) {}
  	}

  	if (is_button_pressed(1)) {
  		// Po wcisnieciu przycisku wylacz diodę
  		led_set(led, false);

  		// Zmniejsz zawartosc zmiennej led
  		led--;
  		// Sprawdz czy nie przekracza zakresu
  		if (led < 0) {
  		  led = 9;
  		}

  		// Wlacz kolejna diode
  		led_set(led, true);

  		// Wait
  		HAL_Delay(20);

  		// czekamy na zwolnienie przycisku
  		while (is_button_pressed(1)) {}
  	}

  	if (is_button_pressed(2)) {
  		// Po wciśnięciu przycisku RESET wyłącz aktualną diodę

  		led_set(led, false);

  		// Ustawi wartość zmiennej LED na 0 (pierwsza dioda)
  		led = 0;

  		// Włącz pierwszą diode
  		led_set(led, true);

  		HAL_Delay(20);

  		while (is_button_pressed(2)) {}
  	}
    /* USER CODE END WHILE */




 

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

15 godzin temu, FTNewbie napisał:

Czy do zadania 1 wymagane jest dołozenie na płytce stykowej jakiegoś kolejnego elementu? 😛

Nie, wystarczą elementy, które są na płytce - kombinuj dalej 😉

Link do komentarza
Share on other sites

Cytat

1. Wróć do przykładu, w którym dioda włączała się na 200 ms i gasła na 800 ms. Zastanów się, jak odwrócić działanie tego programu bez zmieniania jego kodu. 

Resztę zrobię potem, najpierw muszę przeinstalować środowisko bo sypie błędami przy tworzeniu nowego projektu 😬

zad1.PNG

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

Treker
Ta treść została wynagrodzona przez moderatora!

Elvadom otrzymał odznakę: "Odkrywca (podanie odp. na własne pytanie)"

Wracam trochę później niż planowałem, ale są sukcesy ☺️
Zadanie 2 - działa.
Zadanie 3:
W funkcji is_button_pressed dodałem taki kod:

	case 3:
	if (HAL_GPIO_ReadPin(USER_B_RESET_GPIO_Port, USER_B_RESET_Pin) == GPIO_PIN_RESET){
		return true;
	} else {
		return false;
	}

A w głównym programie dopisałem to:
 

	  if (is_button_pressed(3)) {
		  for(int i = 0; i < 10; i++){
			  led_set(i, false);

		  }
		  led = 10;
		  while(is_button_pressed(3))
		  {}
	  }

Musiałem wpisać led = 10, ponieważ jak ustawiłem ją na 0, po resecie przyciskiem USER_B_RESET, USER_BUTTON2 działał prawidłowo, włączała się ostatnia LED, ale jak najpierw klikałem USER_BUTTON to zaczynał od drugiej diody. Przy ustawieniu tej wartości na 9, po resecie  USER_BUTTON2 włączał diodę przedostatnią, za to USER_BUTTON działał prawidłowo. Przy wpisaniu 10 działa zgodnie z założeniem.


*Edit:

Znowu pojawił mi się ten sam problem ze środowiskiem. To znaczy po wyłączeniu STM32CubeIDE i włączeniu po jakimś czasie brakuje perspektywy CubeMX i nie da się jej włączyć. Rozwiązanie znalazłem TUTAJ [LINK], a konkretnie podziałało według tego. rozwiazanie.thumb.PNG.3f228bfb0df1c7fadb6f93520ce042f6.PNG
Podobno od którejś wersji jest ten błąd.

Edytowano przez Elvadom
  • Pomogłeś! 1
Link do komentarza
Share on other sites

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...

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.