4
votes

So I'm currently following a course for the STM32 Microprocessor however, I seem to fail at even the most basic thing: turning a LED on. The complete code is at the bottom of this post.

Important:

  • The hardware is functioning properly.
  • I am using a STM32L432KC.

First of all, we have to figure out on what pin the built-in LED is. According to the manufacturers manual, the LED should be on pin D13 (PB3). enter image description here


Okay so we're looking for PB3. According to the datasheet of the STM32L432KC, PB3 is on the B port and therefore connected to the high performance bus as suggested in the image below. enter image description here


Cool. So our bus is AHB2 and we're working with GPIOB. Now we have to enable the clock on that bus using the RCC_AHB3ENR register. Now, this is the part where I'm probably going to make mistakes (as this post otherwise wouldn't exist), so please pay close attention. If I understand correctly, I want bit 1 to be set to 1 as this indicates that 'GPIOBEN' is set to 'IO port B clock enabled.'. enter image description here enter image description here

This leads me to believe that I should set the bus register as follows:

RCC->AHB2ENR |= 0x2;

Next up I have to set the mode of the GPIO pin to output. According to the course and my documentation, this is done using GPIOx_MODER. enter image description here

This leads me to believe that I should set the GPIO mode as follows:

GPIOB->MODER |= 0x40;

And last but not least to turn the actual LED on we have to set the output data register which is GPIOx_ODR. enter image description here

This leads me to believe that I should set the data as follows:

GPIOB->ODR = 0x8;

I'm not sure where I'm going wrong but this is the first time I'm working with registers on such a deep level. I must be overlooking something but I've tried multiple examples and had no success. All help is appreciated. This is the complete code:

// PB3 - User LED
// RCC->AHB2ENR
// GPIOx_MODER
// GPIOx_ODR

#include "stm32l4xx.h"

int main(void)
{
    RCC->AHB2ENR |= 0x2;
    GPIOB->MODER |= 0x40;

    while(1)
    {
        GPIOB->ODR = 0x8;
    }
}
1

1 Answers

2
votes

Your mode register is not configured correctly. Your line of code

GPIOB->MODER |= 0x40;

can only set bits, it cannot clear them. And you have too many bits set, as the reset value of each pair is 11 and the entire register is FFFF FFFF for ports C-E, FFFF FEBF for port B.

You should use

GPIOB->MODER = (GPIOB->MODER & 0xFFFFFF3F) | 0x00000040;

although because the reset state is guaranteed, this will also work:

GPIOB->MODER &= 0xFFFFFF7F; // equivalently, ~0x0080

The note in the documentation of 11 analog mode (reset state) is not accurate for all pins. Several are in 10 alternate function mode at reset, including PB3. So you need to both clear one bit and set one.