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
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.
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.
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.
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.
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: