Search code examples
embeddedstm32cpu-registersgpioled

Built-in led won't turn on STM32F303RE Nucleo board


I am trying to turn the led (LD2 in schematic) inside the nucleo board on using only registers with the STM32CubeIDE.

Schematic for the STM32F303RE board.

The user manual states the following addresses for the clock, mode and data registers:

Led pin: PA5

Address of the Clock control register: RCC_AHBENR
[base address] + [offset] ===> [Result]
  0x4002 1000  +   0x14   ===> 0x40021014

Address of the GPIOA mode register
0x4800 0000 + 0x00 ===> 0x48000000

Address of the GPIOA output data register
0x4800 0000 + 0x14 ===> 0x48000014

I am using the following code to set/clear the registers in the board:

#include <stdint.h>

int main(void)
{
    uint32_t *pClkCtrlReg = (uint32_t*)0x40021014;
    uint32_t *pPortAModeReg = (uint32_t*)0x48000000;
    uint32_t *pPortAOutReg = (uint32_t*)0x48000014;

    //1. enable the clock for GPIOA peripheral in the AHBENR
    *pClkCtrlReg |= 0x00020000;

    //2. configure the mode of the IO pin as output
    //a. clear the 24th and 25th bit positions
    *pPortAModeReg &= 0xFCFFFFFF;
    //b set 24th bit position as 1
    *pPortAModeReg |= 0x01000000;

    //3. SET 12th bit of the output data register to make I/O pin-12 as HIGH
    *pPortAOutReg |= 0x20;



    while(1);
}

Using the register viewer from the IDE, I can see that the PA5 is set as output, but physically, my led is not turning on.

Position 6 is the bit that is turned on

I do not know what I am doing wrong. I am suspecting that the pin PA5 is wrong, but i tried PA12 too and it does not work. Can someone please help me out here?


Solution

  • I ran through your code with reference manual in hand. RM0316 STM32F303 Reference manual.

    You activate clock to GPIO Port A correctly (also, GPIOA registers would also read all 0x00 is it hadn't been activated).

    Then you set GPIO mode as, quoting you:

    //2. configure the mode of the IO pin as output
    //a. clear the 24th and 25th bit positions
    *pPortAModeReg &= 0xFCFFFFFF;
    //b set 24th bit position as 1
    *pPortAModeReg |= 0x01000000;
    

    You work with bits 24 and 25. Which are these:

    enter image description here

    So you set the mode for pin A12, not A5. For GPIOA Pin 5 you need to manipulate bits 10 and 11.

    //clear pin5 bits
    *pPortAModeReg &= ~(0x03 << 10); //take 0b11, shift it to position 10, flip all bits, AND with original state of register
    

    And follow it with setting those bits to "General purpose output mode" 01, which you also do for wrong bits:

    //b set 10th bit position as 1
    *pPortAModeReg |= (0x01 << 10);
    

    I checked all the registers GPIO has, there shouldn't be anything else you need to set. If things still don't work, please post the contents of all GPIOA registers.

    EDIT: also, try using bit set/reset registers. Note that they are read only, so no "|=" for them, only "=". Writing 0 to them doesn't do anything. So you need to write only (0x01<<5) straight to the GPIOA BSRR register.

    GPIOA->BSRR = (1U<<5); //or however you want to address that register