Skocz do zawartości

Kurs STM32 - #4 - Sterowanie portami GPIO w praktyce


Komentator

Pomocna odpowiedź

Hej, mam pytanie z serii "nie bangla"

Posługuję się płytką z F411RE, dostosowałem przykład do niej zdaje się, i nadal nie działa. Oto kod:

int main(void)
{
GPIO_InitTypeDef gpio; // obiekt gpio z konfiguracja portow GPIO

RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // uruchomienie zegara modulu GPIO
//problem solved - powinno byc RCC_AHB1PeriphClockCmd
GPIO_StructInit(&gpio); 			// domyslna konfiguracja
gpio.GPIO_Pin 	= GPIO_Pin_5; 		// konfigurujemy pin 5
gpio.GPIO_Mode = GPIO_Mode_OUT; 	// jako wyjscie
gpio.GPIO_OType = GPIO_OType_PP; 	// push pull
gpio.GPIO_Speed = GPIO_Fast_Speed;	// nfs
GPIO_Init(GPIOA, &gpio); 			// inicjalizacja modulu GPIOA

GPIO_SetBits(GPIOA, GPIO_Pin_5);

while(1);;;
}

dioda perfidnie nawet nie chce mrugnąć. Z góry dzięki za pomoc, i z dołu za kurs:)

Link do komentarza
Share on other sites

Tak na szybko odpowiadając:

* Sok, kurs dotyczy STM32F103RB, jeśli masz problem z innym mikrokontrolerem, załóż proszę oddzielny temat. Nie sposób niestety napisać kursu dla wszystkich wersji STM32 na raz

* MacGyver, poprawną odpowiedź podał Chumanista - SysTick jest układem licznikowym, który z określoną częstotliwością zwiększa wbudowany rejestr. Gdy doliczy do zadanej wartości wywołuje przerwanie i zaczyna od nowa. Jeśli częstotliwość zegara systemowego wynosi 64MHz, to SysTick doliczy do 64000000 w 1 sekundę. Więc podając SystemCoreClock / 1000 dostajemy 1/1000s, czyli 1ms - bez szczególnej inteligencji ze strony funkcji SysTick_Config (jej inteligencja to odjęcie 1 od wyniku, więc nie musimy o tym pamiętać przekazując parametr)

* argens, - w zadaniu 4.2 używasz pętli while w procedurze obsługi przerwania. Nie należy tak robić! Przerwania należy obsługiwać jak najszybciej, ewentualne czasochłonne procedury przenosząc do programu głównego. Program 4.3 wygląda dużo lepiej (np. przesunięcie bitowe zamiast 10 razy tego samego w kolejnych if-ach). Natomiast program 4.4 jest straszny! Używanie kopiuj-wklej powinno być zakazane w konstytucji! Pomyśl czy nie da się tego napisać krócej (podpowiem - da się!).

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,

Mam problem ze zrozumieniem dość prostego fragmentu kodu a mianowicie początku fukcji

realizującej przerwanie:

olatile uint32_t timer_ms = 0; 

void SysTick_Handler()
{
if(timer_ms){				
	timer_ms--;
}

}

a mianowicie skoro zmiennej timer_ms zostało przypisane 0 to jak dochodzi do wejścia w pętlę

if(timer_ms). Wydaje się to niemożliwe gdyż wartość w nawiasie będzie 0 czyli False.

Pytanie nr 2 to zakładając, że weszliśmy do pętli if(timer_ms). Jaką wartość przyjmie zmienna timer_ms po odjęciu od 0 liczby 1. Czy przyjmuje ona górną wartość zakresu i zlicza w kolejnych dekrementacjach w dół?

Dzięki za wszelką pomoc.

Pozdrawiam,

Link do komentarza
Share on other sites

a mianowicie skoro zmiennej timer_ms zostało przypisane 0 to jak dochodzi do wejścia w pętlę

if(timer_ms). Wydaje się to niemożliwe gdyż wartość w nawiasie będzie 0 czyli False.

W innym miejscu kodu (chyba funkcja delay...?) ustawiasz wartość zmiennej timer_ms na żądaną ilość milisekund, o ile dobrze pamiętam. 🙂

Pytanie nr 2 to zakładając, że weszliśmy do pętli if(timer_ms). Jaką wartość przyjmie zmienna timer_ms po odjęciu od 0 liczby 1. Czy przyjmuje ona górną wartość zakresu i zlicza w kolejnych dekrementacjach w dół?

Jeśli typ zmiennej określa, że zmienna ta przyjmuje wyłącznie wartości nieujemne, to kiedy od jej wartości zerowej odejmiemy jeden, otrzymujemy górną wartość zakresu, czyli dokładnie tak, jak mówisz. 🙂 Zauważ, że w tej funkcji to się nie stanie - dekrementujemy zmienną tylko wtedy, kiedy jest różna od zera. 😉

EDIT: "zakładając, że weszliśmy do pętli if(timer_ms)" - to nie jest pętla, tylko warunek. 🙂

Pozdrawiam.

Link do komentarza
Share on other sites

Elvis, przynajmniej mamy z saper152 potwierdzenie, że się nigdzie nie pomyliłem. 🙂

Wybacz za lekki offtop, ale ciekawy jestem. Kiedy piszesz posta i ktoś w międzyczasie doda odpowiedź, zostajesz o tym poinformowany? Wiem, że na niektórych forach tak to działa.

Link do komentarza
Share on other sites

Wybacz za lekki offtop, ale ciekawy jestem. Kiedy piszesz posta i ktoś w międzyczasie doda odpowiedź, zostajesz o tym poinformowany? Wiem, że na niektórych forach tak to działa.

Niestety u nas jeszcze tego nie ma 🙁

Link do komentarza
Share on other sites

moj sposób na licznik Johnona,

/**

******************************************************************************

* @file main.c

* @author Ac6

* @version V1.0

* @date 01-December-2013

* @brief Default main function.

******************************************************************************

*/

#include "stm32f10x.h"

volatile uint32_t timer_ms = 0;

volatile uint32_t i = 0;

void SysTick_Handler()

{

if (timer_ms) {

timer_ms--;

}

}

void delay_ms(int time)

{

timer_ms = time;

while (timer_ms) {};

}

int main(void)

{

GPIO_InitTypeDef gpio;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

GPIO_StructInit(&gpio);

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.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOC, &gpio);

SysTick_Config(SystemCoreClock / 1000);

uint32_t x = 0b0000111000;

while (1)

{

GPIO_SetBits(GPIOC, x);

delay_ms(500);

GPIO_ResetBits(GPIOC , x);

delay_ms(500);

if((x << 1) > 0b1111111111)

{

x = (x << 1) & 0b1111111110;

}

else

{

x = (x << 1) | 0b0000000001;

}

}

}

__________

Komentarz dodany przez: Treker

Kody programów, dla lepszej czytelności, należy umieszczać w tagach .

Popraw to proszę 🙂

Link do komentarza
Share on other sites

Wybaczcie, że pytam, ale jakoś nie umiem znaleźć informacji, albo jestem ślepy. Które konkretnie piny to port C? A które to port B i port A? Jakoś nie umiem dostrzec tego szczegółu w datasheecie ,a podejrzewam , że dowolnie sobie nie można podłączyć kabelków do pinów i założyć "tu jest właśnie pin 10 portu C". Ktoś mógłby pomóc?

EDIT:

Nie było pytania, jestem ślepy, wszystko jest na karteczce z pudełka z płytką.

Post zostawię, może komuś się przyda 😋

Mam natomiast inne pytanie, gdzie w takim razie można taki opis znaleźć, jakby tak się zgubiła ta kartka z pudełka?

Link do komentarza
Share on other sites

 GPIO_SetBits(GPIOC, 1 << led); //włącz diode

Ktoś byłby tak miły w przystępny sposób wyjaśnić co dzieję się w tej linijce?

Wiem, że to jest przesunięcie bitowe (a tak przynajmniej mi się wydaje), ale nie bardzo rozumiem jak to działa w tym przykładzie.

Link do komentarza
Share on other sites

W przypadku AVR popularne jest makro _BV(), które działa dokładnie jak ten przykład.

Napierw popatrzmy jak są zdefinowane stałe odpowiedzialne za odwoływanie do dopowiednich pinów:

#define 	GPIO_Pin_0   ((uint16_t)0x0001)
#define 	GPIO_Pin_1   ((uint16_t)0x0002)
#define 	GPIO_Pin_2   ((uint16_t)0x0004)
#define 	GPIO_Pin_3   ((uint16_t)0x0008)

Jest ich 16, ale mam nadzieję że ten fragment pokazuje jaki jest schemat: i-ty pin odpowiada wartości 2^i. Najłatwiej 2^i policzyć właśnie przez przesunięcie bitowe. Czyli 1 << i.

Możmy to łatwo sprawdzić:

1 << 0 = 1 ( = 2 ^ 0)

1 << 1 = 2 ( = 2 ^ 1)

1 << 2 = 4 ( = 2 ^ 2)

1 << 3 = 8 ( = 2 ^ 3)

1 << 4 = 16 ( = 2 ^ 4)

itd.

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