Wątek przeniesiony 2018-11-07 16:06 z C/C++ przez Marooned.

STM32F411 - programowanie rejestrów.

0

Witam zacząłem się uczyć programowania STM32 i chciałem zamigać diodą korzystając z rejestrów.
Robiłem to z pomocą reference manuala. Płytka to STM32F411VET6 - Discovery.

Mam taki kod:

#include "stm32f4xx.h"

int main(void){

	
	RCC->APB1ENR |= RCC_AHB1ENR_GPIODEN;

	GPIOD->MODER |= GPIO_MODER_MODE15_0;

	GPIOD->OTYPER |= GPIO_OTYPER_OT15;

	GPIOD->OSPEEDR |= GPIO_OSPEEDR_OSPEED15_0;

	GPIOD->PUPDR &= ~GPIO_PUPDR_PUPDR15_0;

	while(1){
		uint32_t wait;
		GPIOD->ODR |= GPIO_ODR_OD15;
		for (wait = 0; wait < 1000000; wait++){}
		GPIOD->ODR &= ~GPIO_ODR_OD15;
		for (wait = 0; wait < 1000000; wait++){}
	}

}

Dodane pliki:

pliki.png

Ktoś mógłby mi wytłumaczyć co tu źle zrobiłem, że nie działa?

0

Po pierwsze powinieneś sobie zdawać sprawę, że kompilator może ci usunąć te pętle for bo one nic nie robią (zasada "As If").
Po drugie "nie działa" nie wyjaśnia problemu. Pamiętaj, że liczba osób, który mają ten hardware jest dość ograniczona, więc musisz napisać coś więcej niż: "nie działa".

Szybkie googlowanie i czy to nie powinno to wyglądać bardziej tak:

HAL_GPIO_WritePin(GPIOD, GPIO_ODR_OD15, GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOD, GPIO_ODR_OD15, GPIO_PIN_RESET);
HAL_Delay(1000);
0

Nie powinno tak wyglądać, ponieważ ja chciałem to zrobić bezpośrednio na rejestrach a nie na HAL'u.
Nie działa znaczy, że dioda nie miga.

1

Marku, STM32 programowałem ostatnio 5 lat temu, ale ich biblioteka HAL (wtedy nazwana Standard Peripheral Library) była totalnie bezsensownie zrealizowana i wśród znających się lepiej na embedded uchodziła za antywzorzec.
Sądząc z wpadek na poziomie elementarnym:
https://community.st.com/thread/35956-does-usb-device-code-for-stm32-really-allocate-dynamic-memory-from-interrupts
to nadal obowiązuje.

@Raziel295 nie chce mi się teraz do noty patrzeć, ale zwróć uwagę, że piszesz RCC_AHB1ENR_GPIODEN do rejestru APB2ENR.
Na pewno tak?

EDIT: Marek oczywiście ma rację, że ta pętla może zostać wyoptymalizowana. Możesz zadeklarować jej zmienną sterującą jako volatile, to pomoże, ale oczywiście to zła praktyka i najlepiej będzie użyć jakiegoś timera.

EDIT2: spojrzałem do noty, GPIOD "wisi" na magistrali AHB, nie APB, więc tu pierwszy błąd.

0

@alagner:
Niestety po poprawce wciąż nie działa.

1

Nie pamiętam schematu tej płytki... GPIO ma być open-collector (jak u Ciebie) czy push-pull?
EDIT: i generalnie jaki jest objaw? Diodka świeci cały czas przygaszonym światłem?

EDIT2: jeżeli płytka to https://www.st.com/content/ccc/resource/technical/document/user_manual/70/fe/4a/3f/e7/e1/4f/7d/DM00039084.pdf/files/DM00039084.pdf/jcr:content/translations/en.DM00039084.pdf
to wyjście powinno być push-pull, a masz iloczyn na drucie.

0

Gdzie u mnie jest open-collector w PUPDR? Chciałem mieć push-pull, żeby migać diodą. Z tego co wiem to po resecie ta GPIO jest ustawione jako pływające więc trzeba chyba zresetować, żeby nie dodać do siebie tych bitów i nie wyszło coś zupełnie innego.

1
GPIO port output type register (GPIOx_OTYPER) (x = A..E and H)

Bits15:0 OTy:Portxconfigurationbits(y=0..15)
These bits are written by software to configure the output type of the I/O port.
0: Output push-pull (reset state) 
1: Output open-drain
0

Zrobiłem :D Zadziałało! Dzięki za pomoc :) Było open-collector zamiast push-pull :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1