Use Push Button to Control LEDs of STM32F4 Discovery Board – Digital Input pins with HAL Driver

In this tutorial, we will learn to interface a Push button with the STM32F4 Discovery board. To use a push button with  STM32F4, we will configure GPIO pins of STM32F407VG microcontroller as a digital input pin. In the last tutorial, we learned to use GPIO pins as digital output pins by blinking the onboard LEDs of Discovery board. In this Push button tutorial, we will control onboard LEDs of STM32F4 Discovery board with an onboard push button using Keil uvision IDE and HAL GPIO drivers. 

Push button interfacing with STM32F4 discovery Board

Push Button Interfacing with STM32F4 Discovery board

When we want to interface a push button with a microcontroller, we actually want to read the state of the push button either is pressed or not pressed state. When a push button is pressed or unpressed, it provides either logic high and logic low output depending on the configuration mode in which the push button circuit is designed. 

There are two configuration modes to interface a push button with  STM32F4 Discovery board. Let’s discuss both these modes one by one.

Pull-Up Mode

In Pull-up mode, when a push button is not pressed, a logic high input appears on the STM32F4 GPIO pin. Because a 5V signal appears on the input terminal through an R1 resistor. On the contrary, when the push button is pressed, metallic contacts of the push button make contact with the ground terminal and the input terminal. Therefore, a logic low input reflects on the digital input pin of the STM32F4 Discovery board. In short, by reading this state of the push button with a digital input pin of a microcontroller, we can identify whether a push button is pressed or not. The following schematic diagram shows the connection of a push button with a pull-up resistor. 

Schematic Pullup resistor STM32F4

Pull-Down Mode

In Pull-down mode, when a push button is not pressed, a logic low input appears on STM32F4 GPIO pin. Because a ground reference signal appears on the input terminal through a R1 resistor. On the contrary, when the push button is pressed, metallic contacts of the push button make contact with the +5V signal and the input terminal. Therefore, a logic high input reflects on the digital input pin of STM32F4 Discovery board. The following schematic diagram shows the connection of a push button with a pull-up resistor.

Pull down resistor with Push button Schematic

Internal Pull-up and Pull-down Resistors STM32F4

STM32F407VG GPIO ports also have internal pull-up and pull-down resistors which can be configured through the PUPDR register. In HAL libraries, these internal pull-ups and pull-down resistors can be configured through the GPIO_InitTypeDef struct by passing corresponding values to Pull member of the GPIO_InitTypeDef C struct. 

typedef struct
{
  uint32_t Pin;       /*!< Specifies the GPIO pins to be configured.
                           This parameter can be any value of @ref GPIO_pins_define */

  uint32_t Mode;      /*!< Specifies the operating mode for the selected pins.
                           This parameter can be a value of @ref GPIO_mode_define */

  uint32_t Pull;      /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
                           This parameter can be a value of @ref GPIO_pull_define */

  uint32_t Speed;     /*!< Specifies the speed for the selected pins.
                           This parameter can be a value of @ref GPIO_speed_define */

  uint32_t Alternate;  /*!< Peripheral to be connected to the selected pins. 
                            This parameter can be a value of @ref GPIO_Alternate_function_selection */
}GPIO_InitTypeDef;

The values which can be passed to Pull member are: 

#define  GPIO_NOPULL        0x00000000U /*!< No Pull-up or Pull-down activation */  
#define  GPIO_PULLUP        0x00000001U  /*!< Pull-up activation                */
#define  GPIO_PULLDOWN      0x00000002U /*!< Pull-down activation        */

But for the demonstration purpose, we can use external pull-up and pull-down resistors with GPIO pins of STM32F4 discovery board. 

OnBoard Push Button STM32F4 Discovery Board

The discovery board comes with one user button connected with pin zero of PORTA GPIO. We will use this push button as a digital input to control onboard LEDs on the discovery board. 

As you can see in the following schematic diagram, the onboard user push button is connected with PA0 digital pin through a pull-down resistor. This means when the push button is not pressed, we will get an active low signal at the PA0 pin. Similarly, when it is pressed, we will get an active high signal on the PA0 pin. 

OnBoard Push Button STM32F4 Discovery Board-c

To use this button, we should configure the PA0 pin of GPIOA as a digital input pin. 

Controlling LEDs with Push Button STM32F4

For demonstration purposes, we will control onboard four LEDs of STM32F4 discovery board with a push button. As you can see in the figure shown below a blue color push button is available along with four user LEDs. 

OnBoard Push Button discovery board

In the last tutorial, we learned to control these LEDs by configuring GPIO pins of PORTD as digital output pins. If you don’t know how to configure GPIO pins as a digital output pins, you should read that tutorial from this link: 

Push Button Code STM32F4

In this series of tutorials on the STM32F4 discovery board, we are using Keil uvision IDE and HAL drivers from STMicroelectronics to write programs for the STM32F4 discovery board. Therefore, you should have installed Keil uvision on your system. 

You can read this guide on how to download and install keil MDK for ARM on your system: 

  • Download and Install Keil uvision
  • Getting started with Keil uvision 

Program

This code controls on-board LEDs of the STM32F4 board with an onboard push button. When you press and hold the push button, all four LEDs turn on (green, yellow, red, and blue). But as soon as you release the push button, LEDs turn off. This code gives you a demo to use GPIO pins of STM32F4 as digital output and digital input. For LEDs, we configure PORTD pins as digital output pins and for push-button PA0 pin as a digital input pin. 

/* Code to control onboard LEDs of STM32F4 discovery board with onboard push button */
/* Include header file of STM32F4 series microcontroller */
#include "stm32f4xx_hal.h"

/* Function protoypes to configure GPIO pins as digital output and digital input */
void Init_OnBoard_LEDs(void);
void configure_Button(void);
void Delay_ms(volatile int time_ms); //ms delay function 

/* main code to call initialize functions, read state of push button and controlling LEDs */
int main(void)
{
Init_OnBoard_LEDs(); // calls LEDs GPIO pins initialization function 
configure_Button(); // call Push button GPIO pins initialization function 
GPIO_PinState state; // Define a enum struct which contain boolean states 
   while(1)
   {
		
state = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0); // read state of push button and save it in "state" variable
 // if state is high, turn on  LEDs
    if(state)
	{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET);
	}
// if state is low, turn off LEDs
    else
       {
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);
       }
   }
}

/* Function to configure PD12-PD15 pin of as digital output pins */
void Init_OnBoard_LEDs(void)
{
	 __HAL_RCC_GPIOD_CLK_ENABLE(); //Enable clock to GPIOD
	GPIO_InitTypeDef BoardLEDs; // declare a variable of type struct GPIO_InitTypeDef
	BoardLEDs.Mode = GPIO_MODE_OUTPUT_PP; // set pin mode to output 
	BoardLEDs.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; // select pins PD12-PD15 
	HAL_GPIO_Init(GPIOD, &BoardLEDs); // initialize PD12-PD15 pins by passing port name and address of BoardLEDs struct
}

/* Function to configure PA0 pin of as adigital input pin */
void configure_Button(void)
{
	__HAL_RCC_GPIOA_CLK_ENABLE(); //Enable clock to GPIOA
	GPIO_InitTypeDef PushButton;  // declare a variable of type struct GPIO_InitTypeDef
	PushButton.Mode = GPIO_MODE_INPUT; // set pin mode to input
	PushButton.Pin = GPIO_PIN_0;  // select pin PA0 only
	PushButton.Pull = GPIO_NOPULL; // set no internal pull-up or pull-down resistor
	HAL_GPIO_Init(GPIOA, &PushButton); //  initialize PA0 pins by passing port name and address of PushButton struct
}

/* ms delay function */
void Delay_ms(volatile int time_ms)
{
	      int j;
        for(j = 0; j < time_ms*4000; j++)
            {}  /* excute NOP for 1ms */
}

Now upload this code to Discovery board and observe the output.

How Code Works?

First of all, we have used the same code from our previously published tutorial on LED Blinking for STM32F4 discovery board. In that tutorial, we toggled onboard LEDs by using HAL_GPIO_WritePin() and HAL_GPIO_TogglePin() functions of HAL GPIO drivers. There are few changes we make in this tutorial that is we are controlling these LEDs with a push button.

To include a push-button function in our code, we define a configure_Button() function. This function configures the PA0 pin of PORTA of STM32F4 as a digital input pin. 

Configure GPIO Pins as Digital Input Pins

First enable the clock to the respective GPIO port. This line enables the clock to GPIOA. 

__HAL_RCC_GPIOA_CLK_ENABLE(); //Enable clock to GPIOA

Define a variable name “PushButton” with a type of C struct GPIO_InitTypeDef. As discussed in the previous tutorial, the GPIO_InitTypeDef C struct is used to initialize and configure GPIO pins. 

GPIO_InitTypeDef PushButton;  // declare a variable of type struct GPIO_InitTypeDef

Select the pin mode as an input by using a Mode member of variable “PushButton”. 

PushButton.Mode = GPIO_MODE_INPUT; // set pin mode to input

The mode can be defined with one the following options according to the requirement.

#define  GPIO_MODE_INPUT                        0x00000000U   /*!< Input Floating Mode                   */
#define  GPIO_MODE_OUTPUT_PP                    0x00000001U   /*!< Output Push Pull Mode                 */
#define  GPIO_MODE_OUTPUT_OD                    0x00000011U   /*!< Output Open Drain Mode                */
#define  GPIO_MODE_AF_PP                        0x00000002U   /*!< Alternate Function Push Pull Mode     */
#define  GPIO_MODE_AF_OD                        0x00000012U   /*!< Alternate Function Open Drain Mode    */

#define  GPIO_MODE_ANALOG                       0x00000003U   /*!< Analog Mode  */
    
#define  GPIO_MODE_IT_RISING                    0x10110000U   /*!< External Interrupt Mode with Rising edge trigger detection          */
#define  GPIO_MODE_IT_FALLING                   0x10210000U   /*!< External Interrupt Mode with Falling edge trigger detection         */
#define  GPIO_MODE_IT_RISING_FALLING            0x10310000U   /*!< External Interrupt Mode with Rising/Falling edge trigger detection  */
 
#define  GPIO_MODE_EVT_RISING                   0x10120000U   /*!< External Event Mode with Rising edge trigger detection               */
#define  GPIO_MODE_EVT_FALLING                  0x10220000U   /*!< External Event Mode with Falling edge trigger detection              */
#define  GPIO_MODE_EVT_RISING_FALLING           0x10320000U   /*!< External Event Mode with Rising/Falling edge trigger detection       */

Select the PA0 pin of PORTA for a digital input function. 

PushButton.Pin = GPIO_PIN_0;  // select pin PA0 only

Disable internal pull-up and pull-down registers. Because the onboard LED of STM32F4 discovery board has an external pull-down resistor. 

PushButton.Pull = GPIO_NOPULL; // set no internal pull-up or pull-down resistor

Now call the HAL_GPIO_Init() function by passing a port name and address of a structure to initialize PA0 as a digital input pin. 

HAL_GPIO_Init(GPIOA, &PushButton); //  initialize PA0 pins by passing port name and address of BoardLEDs struct

HAL GPIO Pin Read Function 

Second new HAL GPIO driver function used in this example code is a HAL_GPIO_ReadPin(). This routine reads the state of a specified input pin of a GPIO port and returns a state value in boolean form either 0 or 1. 

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

The first argument to HAL_GPIO_ReadPin() is a GPIO port name (x=A,B,….H,I) and the second argument is a pin number of a select GPIO port. 

The return value of this function is a boolean value of 0 or 1 and it is of enumeration type with values of 0 and 1. 

/** 
  * @brief  GPIO Bit SET and Bit RESET enumeration 
  */
typedef enum
{
  GPIO_PIN_RESET = 0,
  GPIO_PIN_SET
}GPIO_PinState;
/**

Inside the main function, first we call Init_OnBoard_LEDs() and configure_Button() rountines to initialize GPIO pins.

Init_OnBoard_LEDs(); // calls LEDs GPIO pins initialization function 
configure_Button(); // call Push button GPIO pins initialization function 

 Define a variable of type GPIO_PinState enum which is used to hold states of GPIO pins. 

GPIO_PinState state; // Define a enum struct which cotain boolean states 

Inside the while(1) loop, which will execute indefinitely, first reads the state PA0 pin with HAL_GPIO_ReadPin() and stores the return value in the “state” variable. 

state = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0); // read state of push button and save it in "state" variable

if the state is high, turn on LEDs by setting PD12-PD15 pins of PORTD and calling HAL_GPIO_WritePin(). 

if(state)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET);
}

if the state is low, turn off LEDs by clearing PD12-PD15 pins of PORTD and calling HAL_GPIO_WritePin(). 

else
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);
}

In summary:

In this tutorial, we learned to use GPIO pins of STM32F4 discovery board as digital input pins using Keil uvision and HAL GPIO driver.

Related Articles:

Leave a Comment