cancel
Showing results for 
Search instead for 
Did you mean: 

How to turn on a LED modyfing registers directly?

FGiai.1
Associate II

Hi to all,

I'm trying to use the Nucleo F446RE board to switch on an external LED. by using directly the registers

IN particular, I have connected the pin PA5 in series with a resistor, a LED and finally with the GND of the board.

The code uses is shown before. Initially I have activated the AHB1 internal pheripheral. Then, I enabled and forced to HIGH the pin PA5 of the board.

int main(int argc, char* argv[])
{
	/** AHB1 **/
	volatile uint32_t *RCC_AHB1ENR = 0x0;
	RCC_AHB1ENR = (uint32_t*)(0x40023800 + 0x30);
	*RCC_AHB1ENR = *RCC_AHB1ENR | 0x1;
 
	/** GPIOA **/
	volatile uint32_t *GPIOA_MODER = 0x0, *GPIOA_ODR = 0x0;
	GPIOA_MODER = (uint32_t*)0x40020000;
	*GPIOA_MODER = *GPIOA_MODER | 0x400;
	GPIOA_ODR = (uint32_t*)(0x40020000 + 0x14);
	*GPIOA_ODR = *GPIOA_ODR | 0x20;
	
	/** Infinite loop **/
	while (1);
}

The code is correctly compiled and loaded on the board, bu the problem is that the LED doesn't turn on. Can someome suggest how to modify the code? There are some other registers to modify? Something else to do?

Thank you very much in advance.

13 REPLIES 13

> Didn't find a hint in the ref man that this is needed.

Because it's an erratum workaround.

 0693W000000W3ioQAC.png

IMO the Cube writers don't quite understand the rationale of that workaround: you are supposed to read register from the just-enabled peripheral, not from RCC; but as GPIOs are on the same AHB bus as RCC, in this particular case, this works.

JW

I see, thanks. Would be nice having cross references in the source code.

FGiai.1
Associate II

Hi to all,

Thanks for the answers.

I have a new version of the code. In this case, the code would turn on the PA8 pin.

int main(int argc, char* argv[])
{
	/** RCC **/
	/* RCC */
	volatile uint32_t *RCC = 0x0;
	RCC = (uint32_t*)0x40023800;
	/* RCC_AHB1ENR */
	volatile uint32_t *RCC_AHB1ENR = 0x0;
	RCC_AHB1ENR = (uint32_t*)(0x40023800 + 0x30);
	*RCC_AHB1ENR |= 0x1;
 
	/** GPIOA **/
	/* GPIOA */
	volatile uint32_t *GPIOA = 0x0;
	GPIOA = (uint32_t*)0x40020000;
	/* GPIOA_MODER */
	volatile uint32_t *GPIOA_MODER = 0x0;
	GPIOA_MODER = (uint32_t*)(0x40020000 + 0x00);
	*GPIOA_MODER |= 1 << 16;
	*GPIOA_MODER &= ~(0 << 17);
	/* GPIOA_ODR */
	volatile uint32_t *GPIOA_ODR = 0x0;
	GPIOA_ODR = (uint32_t*)(0x40020000 + 0x14);
	*GPIOA_ODR |= 1 << 8;
}

I think that the code works well because connecting with a wire PA8 and PA5 pins, the green led on the board (that connected to the PA5 pin) switche on. However, when i connect PA8 pin to external circuit composed by resistor - LED - board GND, the LED doesn't turn on (I tried both the polarizations of the LED and also to remove the resistor but nothing changed).

There is maybe some additional register to set? Maybe the generated voltage is not sufficiently high?

I have an additional question. In this code, I wrote drectly all the memory locations. But, (consider for example the GPIOA_ODR register), if I want to calculate the memory location of a register summing the boundary adress and the offset, how can I do? I tried in the following way but I think it is not correct because in this way the code shown before doesn't work anymore. Can you help also with this?

volatile uint32_t *GPIOA = 0x0;
GPIOA = (uint32_t*)0x40020000;
 
volatile uint32_t *GPIOA_ODR = 0x0;
GPIOA_ODR = (uint32_t*)(GPIOA + 0x14);

I don't know why but using this code doesn't work, while simply sobstituting in line 5 GPIOA with 0x40020000 works. the Do you know how to calculate correctly?

To compile I'm using Eclipse and to load the code on the board I'm using CubeProgrammer.

In the second code, instead of 0014 (line 5) consider 0x14...