Getting started with STM32L053: GPIO Input

In the previous guide (here), we took a look at GPIO output using STM32L053, now we shall see how to develop GPIO input driver.

In this guide, we shall cover the following:

  • Input modes.
  • Develop the GPIO input driver.
  • Code to toggle the LED using push-button.
  • Code.
  • Demo.

1. Input modes:

GPIO input modes include

  • high impedance
  • pull-up
  • pull-down

Floating, High Impedance, Tri-Stated

Floating, high impedance, and tri-stated are three terms that mean the same thing: the pin is just flopping in the breeze. Its state is indeterminate unless it is driven high or low externally. You only want to configure a pin as floating if you know it will be driven externally. Otherwise, configure the input using pulling resistors.

Pull Up/Down

If an input is configured with an internal pull-up, it will be high unless it is externally driven low. Pull-down inputs do the opposite ( they’re low unless driven high).

2.Develop GPIO input driver:

Before we start developing the GPIO input driver, we need to figure out which pin is the push-button of Nucleo-64 is connected to.

According to the user manual of the STM32 Nucleo-64, the push-button is connected to pin PC13.

Hence, we start off by enabling clock access to GPIOC as following:

	/*Enable clock access to GPIOC*/
	RCC->IOPENR |= RCC_IOPENR_GPIOCEN;

Then configure the pin as input by reseting bit 26-27 of MODER register as following:

GPIOC->MODER&=~ GPIO_MODER_MODE13;

In order to read the GPIO state, we can use GPIOC->IDR as following:

GPIOC->IDR&GPIO_IDR_ID13 

This will return either 1 if the button is not pressed and 0 if the button is pressed.

3. Code to toggle the LED using push-button:

To make the guide interesting, we shall toggle the LED with each press of the push button.

We start by enabling clock access to GPIOA and set PA5 as output:

	/*Enable clock access to GPIOA*/
	RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
	/*Set PA5 as output pin*/
	GPIOA->MODER |= GPIO_MODER_MODE5_0;
	GPIOA->MODER  &=~GPIO_MODER_MODE5_1;

Then we need a variable to hold the state:

uint8_t state;

in while (1) loop:

First we check if the button is pressed and the state is 0 as following:

if ((GPIOC->IDR&GPIO_IDR_ID13)==0&&(state==0))
			

If the button is pressed and state is 0, perform the following:

  • Set state to 1.
  • Turn on LED.
  • Wait until the button is released.
			{
			state=1;
			GPIOA->BSRR=GPIO_BSRR_BS_5;
			while((GPIOC->IDR & GPIO_IDR_ID13)==0);
			}

Then we check if the button is pressed and the state is 1, if the conditions are met, perform the following:

  • Set state to 0.
  • Turn off the LED.
  • wait until the button is released.
	if ((GPIOC->IDR & GPIO_IDR_ID13)==0&&(state==1))
			{
			state=0;
			GPIOA->BSRR=GPIO_BSRR_BR_5;
			while((GPIOC->IDR & GPIO_IDR_ID13)==0);
			}

4. Code:

The entire code as following:

#include  "stm32l0xx.h"

uint8_t state;


int main(void)
{
	/*Enable clock access to GPIOA*/
	RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
	/*Enable clock access to GPIOC*/
	RCC->IOPENR |= RCC_IOPENR_GPIOCEN;

	/*Set PA5 as output pin*/
	GPIOA->MODER |= GPIO_MODER_MODE5_0;
	GPIOA->MODER  &=~GPIO_MODER_MODE5_1;
	/* Set PC13 as input*/
	GPIOC->MODER&=~ GPIO_MODER_MODE13;

	while(1)
	{
		if ((GPIOC->IDR&GPIO_IDR_ID13)==0&&(state==0))
			{
			state=1;
			GPIOA->BSRR=GPIO_BSRR_BS_5;
			while((GPIOC->IDR & GPIO_IDR_ID13)==0);
			}

		if ((GPIOC->IDR & GPIO_IDR_ID13)==0&&(state==1))
			{
			state=0;
			GPIOA->BSRR=GPIO_BSRR_BR_5;
			while((GPIOC->IDR & GPIO_IDR_ID13)==0);
			}

	}

}

5. Demo:

Happy coding 🙂

Add Comment

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