Skocz do zawartości
Lay-Z

Problem z zadaniem 4.1 kursu stm32 F1 HAL (lekcja #4)

Pomocna odpowiedź

Napisano (edytowany)

Hej, próbuję przerobić kurs STM32 F1 HAL i na samym początku pojawiły się problemy, a mianowicie od kilku dni próbuję zrobić zadanie 4.1, jednak wszystkie próby kończą się niepowodzeniem. Ma może ktoś zrobione to zadanie i chciałby się nim podzielić oraz sposobem jego rozwiązania? Poniżej mój kod.

Z góry dziękuję!

#include "stm32f1xx.h"

int main(void)
{
SystemCoreClock = 8000000; // taktowanie 8Mhz

HAL_Init();

__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();


GPIO_InitTypeDef gpio; // obiekt gpio będący konfiguracją portów GPIO
gpio.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
gpio.Mode = GPIO_MODE_IT_RISING;
gpio.Pull = GPIO_PULLUP; // rezystory podciągające są wyłączone
gpio.Speed = GPIO_SPEED_FREQ_LOW; // wystarczą nieskie częstotliwości przełączania
HAL_GPIO_Init(GPIOC, &gpio); // inicjalizacja modułu GPIOC

gpio.Pin = GPIO_PIN_13; 	// konfigurujemy pin 13
gpio.Mode = GPIO_MODE_INPUT; 	// jako wejście
gpio.Pull = GPIO_PULLUP;		// włączamy rezystor podciągający
HAL_GPIO_Init(GPIOC, &gpio);	// port GPIOC

while (1) {
   if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET)
   {
	   uint32_t led = 0;
		  HAL_GPIO_WritePin(GPIOC, 1 << led, GPIO_PIN_SET); //włącz diode
		  HAL_Delay(150);
		  HAL_GPIO_WritePin(GPIOC, 1 << led, GPIO_PIN_RESET); //wyłącz diode
		  if (++led >= 10)
		  { // przejdz do nastepnej
			 led = 0;
		  }
		  else
		  {
			  uint32_t led = 10;
						  HAL_GPIO_WritePin(GPIOC, 1 << led, GPIO_PIN_SET); //włącz diode
						  HAL_Delay(150);
						  HAL_GPIO_WritePin(GPIOC, 1 << led, GPIO_PIN_RESET); //wyłącz diode
						  if (--led >= 10)
						  { // przejdz do nastepnej
							 led = 10;
		  }

  }
}
}
}
Edytowano przez Lay-Z
Zapomniałem dodać kodu

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Zakładam, że konfiguracja jest poprawna. Z tego co rozumiem to po wciśnięciu przycisku czyli zwarciu pinu do masy zaczyna się w ogóle coś dziać. A jak nic nie wciskamy to wszystko ma być zgaszone tak? Przedstawiony kod działa w taki sposób, że zapalasz diodę o numerze 0 na porcie C, po 150ms ją gasisz, sprawdzasz czy led jest 10 lub więcej. Ale nie jest więc wykonuje się ten dziwny else i wtedy ustawia od razu led na 10 czyli 1010 (pewnie miga 2 i 4 dioda) a potem od razu spełniany jest kolejny warunek i led ustawia się na 10 i wraca na początek.

Coś mi się wydaje, że jest dość mocno namieszane i chyba trzeba to wszystko stworzyć od początku 🙂

Treść zadania:

"Przygotuj program, który zmienia kolejność zapalania diod w linijce LED po naciśnięciu przycisku."

 

Zacznij od zapalania diody od 0 do 7 co np. 300ms. Jak będzie chciał przejść na 8 to znów zacznij od 0. Jak to zadziała to odczytaj gdzieś sobie stan przycisku. Jak poprawnie wykrywa to zrób sobie zmienną, że każde naciśnięcie przycisku zmienia jej stan z 0 na 1 i odwrotnie z 1 na 0 (taki prosty automat stanów). Gdy to Ci będzie działać to w warunku if else dla tej zmiennej skopiuj sobie te zapalanie tyle, że w drugą stronę i to wszystko.

 

//czytaj stan przycisku - na kazde wcisniecie ma sie zmieniac z kierunek_prawo na kierunek_lewo i odwrotnie

if(kierunek_prawo)

{

//zapalaj w prawo

}
else

{

//zapalaj w lewo

}

 

Edytowano przez eldesigner

Udostępnij ten post


Link to post
Share on other sites

Przepraszam za tak długą zwłokę, ale pomimo wielu prób podejmowanych w kolejnych dniach mój kod nadal nie działa, i nie mogę wymyślić co dalej robić. 😞 

Udostępnij ten post


Link to post
Share on other sites

Napisałem wszystko od nowa i jakoś ruszyło, tylko żeby zapętlało w drugą stronę strzelam że trzeba użyć swego rodzaju switcha który przełącza stany zamiast definiować na sucho stan niski czy wysoki (1 i 0), tylko tutaj rodzi się kolejny problem, bo nie wiem jak miało by to wyglądać 😞. Byłbym bardzo wdzięczy za pomoc. Z góry dziękuję za wszelkie chęci!

#include "stm32f1xx.h"

int main(void)
{
    SystemCoreClock = 8000000; // taktowanie 8Mhz

    HAL_Init();

    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();

   GPIO_InitTypeDef gpio; // obiekt gpio będący konfiguracją portów GPIO
   gpio.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|
   GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
   gpio.Mode = GPIO_MODE_OUTPUT_PP; // jako wyjście
   gpio.Pull = GPIO_NOPULL; // rezystory podciągające są wyłączone
   gpio.Speed = GPIO_SPEED_FREQ_LOW; // wystarczą nieskie częstotliwości przełączania
   HAL_GPIO_Init(GPIOC, &gpio); // inicjalizacja modułu GPIOC

    uint32_t led = 10;
   while (1) {
	   if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == 0)
	   {
      HAL_GPIO_WritePin(GPIOC, 1 << led, GPIO_PIN_SET); //włącz diode
      HAL_Delay(150);
      HAL_GPIO_WritePin(GPIOC, 1 << led, GPIO_PIN_RESET); //wyłącz diode
      if (--led >= 10) { // przejdz do nastepnej
         led = 10;
      }
	   }
	   else
	   {
		   HAL_GPIO_WritePin(GPIOC, 1 << led, GPIO_PIN_SET); //włącz diode
		         HAL_Delay(150);
		         HAL_GPIO_WritePin(GPIOC, 1 << led, GPIO_PIN_RESET); //wyłącz diode
		         if (++led >= 10) { // przejdz do nastepnej
		            led = 0;
		         }
	   }
   }
}

 

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

@Lay-Z inicjalizacja GPIO wygląda dobrze, użycie punkcji HAL też, ale zastanawiam się czy wybór pinu jest poprawny. W IDE możesz podejrzeć co oznacza np. GPIO_PIN_0 (u mnie jest to wartość: ((uint16_t)0x0001) i każdy kolejny to 2, 4, itd... czyli operacja 1<<n jest ok, ale może podmień to uint32_t?

Mniejsza o to skoro działa. Z tym przełączaniem potrzebujesz albo przerwanie zewnętrzne od przycisku - tu polecam zaznajomić się z CubeIDE fajnie to działa. Albo przy pollingu jak teraz dodaj dodatkową zmienną stanu która pamięta to co było ostatnio - dodaj coś w stylu lastState = state na końcu pętli i sprawdzaj w kolejnym obiegu czy:

state = HAL_GPIO_ReadPin....

if (lastState != state ....

oznacza to że coś się zmieniło czyli wystąpiło zbocze.

Wszystko to możesz też załatwić przerwaniem od GPIO 😉 

image.thumb.png.4f894ca80654a865514364fcf323fd24.png

Nie sugeruje się listą peryferiów, to jest na F4. Następnie w kodzie nadpisujesz funkcję:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
	HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);
}

W mainie generator dodaje obsługę przerwania, jak widać na zborze rosnące, ale możesz zmienić:

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOG, LED_GREEN_Pin|LED_RED_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : PA0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : LED_GREEN_Pin LED_RED_Pin */
  GPIO_InitStruct.Pin = LED_GREEN_Pin|LED_RED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI0_IRQn);

}

 

Edytowano przez Gieneq

Udostępnij ten post


Link to post
Share on other sites

@Gieneq niestety pomimo wielu prób nie potrafię tego zrobić. Próbowałem użyć  HAL_GPIO_EXTI_Callback jednaj mój program nadal nie działał 😞. Nie mam już na to pomysłu 😞

Udostępnij ten post


Link to post
Share on other sites

@Lay-Z a jak wygląda u Ciebie main?

Udostępnij ten post


Link to post
Share on other sites

@Gieneq Pokażę cały kod. Wymyśliłem coś takiego ale jak zaczynam sobie while'a to w kolejnej linijce :

if (HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13)) //tutaj mi błąd wywala

mam błąd. Nie wiem jak ten program ma wyglądać, próbuję wszystkiego po kolei i nic.  Dodałem jeszcze do pliku stm32f1xx_it.c taki kawałek: 

void SysTick_Handler(void)
{
	HAL_IncTick();
	HAL_SYSTICK_IRQHandler();
#ifdef USE_RTOS_SYSTICK
	osSystickHandler();
#endif
}

a oto końcowy kod:

#include "stm32f1xx.h"

void EXTI15_10_IRQHandler(void)
{
	HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
}

int main(void)
{
	SystemCoreClock = 8000000; // taktowanie 8Mhz

	HAL_Init();

	__HAL_RCC_GPIOC_CLK_ENABLE();
	__HAL_RCC_GPIOA_CLK_ENABLE();

	GPIO_InitTypeDef gpio; // obiekt gpio będący konfiguracją portów GPIO
	gpio.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|
	GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
	gpio.Pin = GPIO_PIN_13;
	gpio.Mode = GPIO_MODE_OUTPUT_PP;; // jako wyjście
	gpio.Pull = GPIO_PULLUP; // rezystory podciągające są wyłączone
	gpio.Speed = GPIO_SPEED_FREQ_LOW; // wystarczą nieskie częstotliwości przełączania
	HAL_GPIO_Init(GPIOC, &gpio); // inicjalizacja modułu GPIOC

	HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

uint16_t led = 10;
	while (1) {

		if (HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13))
		{
		HAL_GPIO_WritePin(GPIOC, 1 << led, GPIO_PIN_SET); //włącz diode
		HAL_Delay(150);
		HAL_GPIO_WritePin(GPIOC, 1 << led, GPIO_PIN_RESET); //wyłącz diode
			if (--led >= 10) { // przejdz do nastepnej
			 led = 10;
			}
		}
			else
			{
				HAL_GPIO_WritePin(GPIOC, 1 << led, GPIO_PIN_SET); //włącz diode
				 HAL_Delay(150);
				 HAL_GPIO_WritePin(GPIOC, 1 << led, GPIO_PIN_RESET); //wyłącz diode
					 if (++led >= 10) { // przejdz do nastepnej
						led = 0;
						 }
			}


	}
}

 

Udostępnij ten post


Link to post
Share on other sites

Można by też sięgnąć do dokumentacji i skonfigurować odpowiednie rejestry na piechotę. Poniżej przykład dla stm8L.

// config PORTB
PB_DDR = 0xff; // all output
PB_CR1 = 0xff; // all push_pull
// buton pin : input floating with interrupt
PC1_CR2 = ENABLE;

procedura przerwania

@far @interrupt void buttonPress (void)
{ 
	static char pin;
	EXTI_P1IS1 = SET; 
	PB_ODR = ((unsigned char)(1<<pin));
	if(pin<8) ++pin; else pin=0;
	EXTI_P1F = CLEAR_W1; 
}

 

Udostępnij ten post


Link to post
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...