GPIO LED Control – Accessing Register Directly

To open the program tutorial, I will show you how to control LED on STM32F411VET Discovery Board by accessing register directly.

It helps you to understand how to use schematic and datasheet in embedded programming.

1. Preparation

I hope you prepared all necessary thing in Introduction to Microcontroller Development.

Now let start our implementation!

2. Create new project

  • Start Keil-ARM program and choose Project -> New Project
  • Choose Save Location and Project Name
  • Choose device name, type STM32F411VEx in blank space
  • Click device and OK
  • Right click to Target 1 and choose Manage Project Items…
  • Change target name and group name and add main.c file under User folder
  • You can also add main.c by right click on User folder -> Add New Item to Group ‘User’
  • Add choose C File (.c) then add main.c file
  • Now we can start adding our code

3. How to use schematic and datasheet

3.1. STM32F411E Discovery Schematic explain to control LED

Now you can see 4 LED on board is turned ON or OFF by controlling 4 pins from 12 to 15 of PORT-D.

3.2. STM32F411xE chip datasheet explain to control LED

  • Enable clock for PORT-D:
    • Access RCC_AHB1ENR register (section 6.3.9)
    • Set GPIODEN bit to 1
  • Set pin mode to general purpose output mode
    • Access GPIOD_MODER register (section 8.4.1)
    • Set MODER12 to MODER 15 value to 01 as general purpose output mode
  • Set output push-pull type
    • Access GPIOD_OTYPER register (section 8.4.2)
    • Set OT12 to OT15 to 0 as output push-pull
  • Set no pull-up, pull-down
    • Access GPIOD_PUPDR register (section 8.4.4)
    • Set PUPDR12 to PUPDR15 value to 00 as no pull-up, pull-down
  • Set or reset GPIO pin value to turn on or off LED
    • Access GPIOD_BSRR register (section 8.4.7)
    • If you want to output high value to LED pins, set 1 to BS12 -> BS15
    • If you want to output low value to LED pins, set 1 to BR12 -> BR15

Now you understand how to control LED by reviewing schematic and datasheet. Let implement our code.

4. GPIO LED blink code

  • First we have to include file for register definition:
#include "stm32f411xe.h"
  • LED position should be defined next, we knew they are PD12 -> PD15:
#define LED0 (1<<12)
#define LED1 (1<<13)
#define LED2 (1<<14)
#define LED3 (1<<15)
  • Define LED_Init function:
void LED_Init(void)
{
    /* Enable portD clock */
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
    /* Set pin 12, 13, 14, 15 as general purpose output mode (push-pull) */
    GPIOD->MODER |= (GPIO_MODER_MODER12_0 |
                     GPIO_MODER_MODER13_0 |
                     GPIO_MODER_MODER14_0 |
                     GPIO_MODER_MODER15_0 );
	
    /* Use push-pull output */ 
    GPIOD->OTYPER = 0; 
    /* No pull up, no pull down */
    GPIOD->PUPDR = 0;
    return;
}
  • Define Delay function to support LED blinking:
void Delay(uint32_t time)
{
    uint32_t delay = 0;
    for(delay = 0; delay < time; delay++)
    {
        __NOP();
    }
}
  • Main function with super loop to blink LED
int main(void)
{
    /* Init LED */
    LED_Init();

    /* Supper loop to blink LED */
    while(1)
    {
        /* Turn on LED0 */ 
        GPIOD->BSRR = LED0;
        Delay(500000);
        /* Turn off LED0 */
        GPIOD->BSRR = (uint32_t)LED0 << 16;
        Delay(500000);
    }
    return 0;
}
  • You can see the highlights are set and reset control LED0 pin
  • This is our full main.c:
#include "stm32f411xe.h"

/* LED in position portD pin 12, 13, 14, 15 */ 
#define LED0 (1<<12)
#define LED1 (1<<13)
#define LED2 (1<<14)
#define LED3 (1<<15)

void LED_Init(void);
void Delay(uint32_t time);

int main(void)
{
    /* Init LED */
    LED_Init();

    /* Supper loop to blink LED */
    while(1)
    {
        /* Turn on LED0 */ 
        GPIOD->BSRR = LED0;
        Delay(500000);
        /* Turn off LED0 */
        GPIOD->BSRR = (uint32_t)LED0 << 16;
        Delay(500000);
    }
    return 0;
}

void LED_Init(void)
{
    /* Enable portD clock */
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
    /* Set pin 12, 13, 14, 15 as general purpose output mode (push-pull) */
    GPIOD->MODER |= (GPIO_MODER_MODER12_0 |
                     GPIO_MODER_MODER13_0 |
                     GPIO_MODER_MODER14_0 |
                     GPIO_MODER_MODER15_0 );
	
    /* Use push-pull output */ 
    GPIOD->OTYPER = 0; 
    /* No pull up, no pull down */
    GPIOD->PUPDR = 0;
    return;
}

void Delay(uint32_t time)
{
    uint32_t delay = 0;
    for(delay = 0; delay < time; delay++)
    {
        __NOP();
    }
}

5. Build

  • Choose Options for Target to control the build:
  • Choose compiler version 6:
  • Choose debugger ST-Link:
  • Click Setting and tick on Reset and Run option:
  • Click Rebuild and see success result:

6. Flash and Run

  • Connect your board to PC USB port through USB type B cable
  • Choose Download to flash your image into board
  • Now you can see Green LED is blinking.
  • What a good felling to see it!
IMG-2770

7. Conclusion

It is very simple version of GPIO controlling but help us understand the typical process of Microcontroller Programming, then we can continue our work with other features easier.

If there is any question, please let me know in the comment.

Hope you enjoy and see you in my next post.

Leave a Reply

Your email address will not be published. Required fields are marked *