Position: Index > Unclassified >

Implementing buttons on STM32F103ZET6

2017-11-29 11:15  
Declaration:We aim to transmit more information by carrying articles . We will delete it soon, if we are involved in the problems of article content ,copyright or other problems.

Last time we have made a good starting point with setting up a project template for STM32F103ZET6 development board using GNU tools. Using same project template we can move forward and start programing other elements. This time a quick note about adding button library. This is really modest implementation which simply initializes port pins and then reads their status.

Development board is equipped with four user programmable buttons named WAKEUP, TAMPER, USER1 and USER2. We are not going to care about meaning of names just use them as general purpose buttons for now.

For this we just need to create another pair of driver files buttons.c and buttons.h. In buttons.h file we simply define button ports and pins with some friendly names. Also as well we have to think about clocking proper peripheral buses.

#define BWAKEUP 			GPIO_Pin_0
#define BWAKEUPPORT			GPIOA
#define BWAKEUPPORTCLK		RCC_APB2Periph_GPIOA
#define BTAMPER 			GPIO_Pin_13
#define BTAMPERPORT			GPIOC
#define BTAMPERPORTCLK		RCC_APB2Periph_GPIOC
#define BUSER1 				GPIO_Pin_8
#define BUSER1PORT			GPIOA
#define BUSER1PORTCLK		RCC_APB2Periph_GPIOA
#define BUSER2 				GPIO_Pin_3
#define BUSER2PORT			GPIOD
#define BUSER2PORTCLK		RCC_APB2Periph_GPIOD

Next step is button initialization. In buttons.c we simply create function:

void ButtonsInit(void)
{
  //GPIO structure used to initialize Button pins
  GPIO_InitTypeDef GPIO_InitStructure;
  //Enable clock on APB2 pripheral bus where buttons are connected
  RCC_APB2PeriphClockCmd(BWAKEUPPORTCLK|BTAMPERPORTCLK|BUSER1PORTCLK|BUSER2PORTCLK,  ENABLE);
  //select pins to initialize WAKEUP and USER1 buttons
  GPIO_InitStructure.GPIO_Pin = BWAKEUP|BUSER1;
  //select floating input mode
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  //select GPIO speed
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(BWAKEUPPORT, &GPIO_InitStructure);
  //select pins to initialize TAMPER button
  GPIO_InitStructure.GPIO_Pin = BTAMPER;
  GPIO_Init(BTAMPERPORT, &GPIO_InitStructure);
  //select pins to initialize USER2 button
  GPIO_InitStructure.GPIO_Pin = BUSER2;
  GPIO_Init(BUSER2PORT, &GPIO_InitStructure);
}

Here we have to enable peripheral clocks for used ports withRCC_APB2PeriphClockCmdcommand. Then we can start setting up port pins. According to peripheral library we need to do this through structure variable where each field caries particular setting. These would be GPIO_Pins (all pins set for same port), then GPIO_Mode – we set it as input floating, and GPIO_Speed as max. Buttons aren’t connected to same port so we have to do initialization separately for each port with GPIO_Init function.

Lastly we write simple function that reads button state.

uint32_t ButtonRead(GPIO_TypeDef* Button_Port, uint16_t Button)
{
  return !GPIO_ReadInputDataBit(Button_Port, Button);
}

When pressed, buttons pulls port pin low so GPIO_ReadInputDataBit() function returns ’0′. Probably it is more logical to have ’1′ on click so we used NOT ‘!’operator to do so. And here is a simple demo code which lights different LED on each button press. Code still runs in super loop so don’t judge code efficiency its only for demonstration.

//Buttons Test
#include "stm32f10x.h"
#include "leds.h"
#include "buttons.h"
//delay function
void Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}
int main(void)
{
  //init leds
  LEDsInit();
  ButtonsInit();
while (1)
  {
	//read Wakeup button
	if (ButtonRead(BWAKEUPPORT, BWAKEUP))
	{
		//led 1 on
		LEDOn(1);
		//delay
		Delay(500000);
		//led 1 off
		LEDOff(1);
	}
	//read TAMPER button
	if (ButtonRead(BTAMPERPORT, BTAMPER))
	{
		//led 2 on
		LEDOn(2);
		//delay
		Delay(500000);
		//led 2 off
		LEDOff(2);
	}
	//read User1 button
	if (ButtonRead(BUSER1PORT, BUSER1))
	{
		//led 3 on
		LEDOn(3);
		//delay
		Delay(500000);
		//led 3 off
		LEDOff(3);
	}
	//read User2 button
	if (ButtonRead(BUSER2PORT, BUSER2))
	{
		//led 4 on
		LEDOn(4);
		//delay
		Delay(500000);
		//led 4 off
		LEDOff(4);
	}
  }
}

In real applications buttons check should be interrupt based. But we will get to that soon.

Project source code[420KB]


Reprinted Url Of This Article:
http://www.scienceprog.com/implementing-buttons-on-stm32f103zet6/