Skocz do zawartości
Komentator

Kurs STM32 - #4 - Sterowanie portami GPIO w praktyce

Pomocna odpowiedź

dzami97, witam na forum 🙂 Czego dokładnie nie rozumiesz? Czy chodzi o operator "przesunięcie bitowe.

Udostępnij ten post


Link to post
Share on other sites

Treker, Ok, czyli mam rozumieć że GPIOx_SetBits(GPIOC ,1) ustawia pin zero portu x w stan wysoki, (GPIOx,"10") pin pierwszy, "100" pin drugi itd? Oczywiście jest to zapis binarny więc pewnie nie można go użyć w kompilatorze tak jak ja to zrobiłem czyli "10000" lub "10" stąd ta funkcja przesunięcia bitowego od "1" czyli jedynki na najmłodszym bicie. Z czego to wynika? Czy jest to odwołanie do rejestru? Kiedyś czytałem o rejestrze GPIOx_ODR. Czy on działa właśnie tak tzn jedynka na odpowiednim miejscu 16bitowego rejestru wyzwala stan wysoki w przypadku skonfigurowania portu wcześniej jako wyjście? Pytanie jeszcze o dokumentacje, gdzie najlpiej szukać opisu pinów i ich funkcji alternatywnych(który dokumnet ew. strona)? Czy w Eclipsie da się rozwinąć liste funkcji biblioteki na pasku po prawej lub lewej stronie? W Keilu była taka możliwość, w zakładce GPIO po rozwinięciu miałeś wszystkie funkcje dotyczące portów.

dzięki i pozdrawiam

Udostępnij ten post


Link to post
Share on other sites
Oczywiście jest to zapis binarny więc pewnie nie można go użyć w kompilatorze tak jak ja to zrobiłem czyli "10000" lub "10" stąd ta funkcja przesunięcia bitowego od "1" czyli jedynki na najmłodszym bicie. Z czego to wynika?

Jeśli wpisujesz "10000" to jest to traktowane jako liczba dziesiętna. Zapis binarny musi być poprzedzony stosownym przedrostkiem. Najczęściej korzysta się jednak z przesunięć bitowych, ponieważ jest to najwygodniejsze 🙂

Udostępnij ten post


Link to post
Share on other sites

Udało mi się zrobić licznik Johnsona.

	uint32_t counter = 0;

int setBits = 0b0000000001;
int resetBits = 0b0000000000;
while (1) {
	GPIO_SetBits(GPIOC, setBits << counter);
	GPIO_ResetBits(GPIOC, resetBits << counter);

	counter++;
	if (counter >= 10) {
		setBits = setBits ^ 0b0000000001;
		resetBits = resetBits ^ 0b0000000001;
		counter = 0;
	}
	delay_ms(1000);
}

Brakowało mi ustawiania pinów tak jak w AVR gdzie jeśli podałem 0 to zapisywał do rejestru 0 a jeśli 1 to zapisywał jeden. Dzięki temu mógłbym tylko negować zbiór bitów.

Ale tutaj mamy dwie procedury jedną do ustawiania 1 i jedną do ustawiania 0 więc musiałem zrobić dwa zbiory bitów.

Czy da się to zrobić jakoś lepiej?

[ Dodano: 14-02-2018, 17:34 ]

I mam jeszcze pytanie odnośnie przerwań.

Po co na początku konfigurować numer linii:

exti.EXTI_Line = EXTI_Line13;

Skoro później i tak muszę podać port i numer pinu?

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);

Rozumiem, że numer linii 13 jest dlatego że przycisk jest pod pinem 13 tak?

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Cześć

Mam olbrzymią prośbę. Czy ktoś mógłby pomóc mi przerobić podany w kursie kod do komunikacji USART na STMF401RE ? 

Nie mogę sobie poradzić. Nie mogę znaleźć RCC_APB2Periph_AFIO, nie wiem czym to zastąpić.

Z góry bardzo dziękuję. 

Pozdrawiam

Edytowano przez Protektor28

Udostępnij ten post


Link to post
Share on other sites

Nic dziwnego, że coś takiego nie istnieje - wklejasz do M4 kod napisany dla M3. Chociaż różnic nie ma znowu tak wiele, to jednak nie uda Ci się nic zdziałać bez zaglądania do datasheeta. Porównaj sobie chociażby sposób podłączenia RCC do GPIO:

M3 F1.thumb.jpg.4d05570db28899b08e0cce8444a2e73b.jpg

M4 F4.thumb.jpg.01f768012176b1675bfc1d278272389b.jpg

A tutaj masz poprawiony kod do nadawania:

#include "stm32f4xx.h"

void send_char(char c){
	while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
	USART_SendData(USART2, c);
}

void send_string(const char* s){
	while (*s)
	send_char(*s++);
}

int main(void){
	GPIO_InitTypeDef gpio;
	USART_InitTypeDef uart;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE);
//	RCC_APB1PeriphClockCmd(RCC_APB1Periph_AFIO, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);


	GPIO_StructInit(&gpio);
	gpio.GPIO_Pin = GPIO_Pin_2;
	gpio.GPIO_Mode = GPIO_Mode_AF;
	GPIO_Init(GPIOA, &gpio);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);

	gpio.GPIO_Pin = GPIO_Pin_3;
	gpio.GPIO_Mode = GPIO_Mode_AF;
	GPIO_Init(GPIOA, &gpio);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);

	USART_StructInit(&uart);
	uart.USART_BaudRate = 115200;
	USART_Init(USART2, &uart);
	USART_Cmd(USART2, ENABLE);

	while (1) {
		send_string("Hello world!\r\n");
	}
}

i odbierania danych:

#include "stm32f4xx.h"

void send_char(char c){
	while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
	USART_SendData(USART2, c);
}

void send_string(const char* s){
	while (*s)
	send_char(*s++);
}

int main(void){
	GPIO_InitTypeDef gpio;
	USART_InitTypeDef uart;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE);
//	RCC_APB1PeriphClockCmd(RCC_APB1Periph_AFIO, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);


	GPIO_StructInit(&gpio);
	gpio.GPIO_Pin = GPIO_Pin_2;
	gpio.GPIO_Mode = GPIO_Mode_AF;
	GPIO_Init(GPIOA, &gpio);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);

	gpio.GPIO_Pin = GPIO_Pin_3;
	gpio.GPIO_Mode = GPIO_Mode_AF;
	GPIO_Init(GPIOA, &gpio);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);

	USART_StructInit(&uart);
	uart.USART_BaudRate = 115200;
	USART_Init(USART2, &uart);
	USART_Cmd(USART2, ENABLE);

	while (1) {
		 if (USART_GetFlagStatus(USART2, USART_FLAG_RXNE)) {
		     char c = USART_ReceiveData(USART2);
		     switch (c)
		     {
		         case 'a':
		             send_string("Odebrano komunikat A!\r\n");
		             break;
		         case 'b':
		             send_string("Odebrano komunikat B!\r\n");
		             break;
		         default:
		             send_string("Nieznany komunikat:(\r\n");
		             break;
		     }
		 }
	}
}

Nie sprawdzałem, ale powinno działać.

  • Lubię! 1
  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites

Bardzo dziękuję Nawyk !

Program działa. Jedyną rzecz (czego nie rozumiem) jaką należy zmienić to USART_BaudRate . Jeśli chcę by nadawał z wartością 115200 to muszę wpisać (przynajmniej w moim wypadku) wartość trzy razy większą: USART_BaudRate = 345600. Doszedłem do tego sprawdzając po kolei wszystkie możliwe prędkości po stronie komputera, bo pojawiały się "krzaczki". 

Jestem ogromnie wdzięczny i jeszcze raz bardzo dziękuję.

Pozdrawiam :)))

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Luzik 🙂 Pewnie masz domyślne ustawienia w PLL (dla 25 MHz zamiast dla kwarcu 8 MHz). Na APB1 (od USART2) powinieneś mieć 42 MHz

#define PLL_M      8
#define PLL_N      336
#define PLL_P      2
#define PLL_Q      7

A tak to wygląda w całej okazałości (swoją drogą - polecam CubeMX):

pll.thumb.jpg.80249ae47c0eacc597e195b610061ed9.jpg

edit:

Właśnie przyjrzałem się Twojej płytce i widzę, że tam w ogóle nie ma wlutowanego HSE 😄 W każdym razie masz coś namieszane w ustawieniach zegarka, a objawy 25/8 akurat zgadzałyby się z Twoim problemem 🙂

Edytowano przez Nawyk
  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Cześć 🙂

Mam pytanie odnośnie GPIO. Jakie parametry muszę wprowadzić na pin

by był on w stanie wysokiej impedancji?

 

Pozdrawiam

Udostępnij ten post


Link to post
Share on other sites

Cześć.

Wyglądałoby to tak: 

gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;

Stan wysokiej impedancji zwany jest właśnie jako floating. Jeżeli piszesz kod to warto użyć skrótu "lewy_ctrl+spacja", pozwoli on na uzyskanie podpowiedzi o możliwych opcjach w danej funkcji itd.

Szybka odpowiedź, ale jestem nowy na forum. 😉

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@MaciejZyskowski, witam na forum 😉 Widzę, że to Twoje pierwsze kroki na Forbocie, oto najważniejsze informacje na start:

  • Chcesz przywitać się z innymi członkami naszej społeczności? Skorzystaj z tematu powitania użytkowników.
  • Opis najciekawszych funkcji, które ułatwiają korzystanie z forum znajdziesz w temacie instrukcja korzystania z forum - co warto wiedzieć?
  • Poszczególne posty możesz oceniać (pozytywnie i negatywnie) za pomocą reakcji - ikona serca w prawym dolnym rogu każdej wiadomości.
12 godzin temu, MaciejZyskowski napisał:

Szybka odpowiedź, ale jestem nowy na forum.

Witamy - miło, że od razu zaczynasz od pomocy innym 😉

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Po skopiowaniu programu i probie budowania wyskakuja mi takie bledy (pierwsze zdjecie).

bledy2.PNG

bledy.PNG

PS. Jak w edycji usunac dodane zdjecie?

Edytowano przez danielbr3

Udostępnij ten post


Link to post
Share on other sites

Z jakiej płytki korzystasz? Projekt masz skonfigurowany na mikrokontroler F303, a kurs jest dla F103.

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!

Gość
Napisz odpowiedź...

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