STM32CubeMX Tutorial Series: GPIO

From Waveshare Wiki
Jump to: navigation, search
Abstract: This chapter presents how to use the GPIO of stm32, and how to control the LED with key pressing.

Open a new project on STM32CubeMX, then select the chip STMF746IGT6 and High Speed Clock (HSE)

Stm32cubemx-tutorial-series-1.png

Select the corresponding buttons and LED pins, according to the schematic of the development board Open746I-C. (Available from http://www.waveshare.com)

Stm32cubemx-tutorial-series-2.png

PA0,PG2,PG3,PD4,PD5 and PD11 are input pins for button pressing, which should be set to GPIO_INPUT mode. PB6,PB7,PH4 and PI8 are LED output control pins, which should be set to GPIO_OUTPUT mode.

Stm32cubemx-tutorial-series-3.png

Click the option Clock Configuration to set the system clock to 216M.

Stm32cubemx-tutorial-series-4.png

Click Configuration->GPIO to set the corresponding pins. The 5-way button pin should be set to pull-up input mode. The button WakeUp has been connected with an external pull-down resistor, so it do not need any settings. (R6 is a pull-down resistor, and R5 and C3 compose a RC filter for anti-jitter.) LED pin should be set to low speed push-pull output mode with no pull-up nor pull-down setting (default mode).

Stm32cubemx-tutorial-series-5.png

Click the icon Stm32cubemx-tutorial-series-6.png to generate the report. Then, the software will tell you to build a new project. You can input a project name and select the storage path. IDE select MDK-ARM V5.

Stm32cubemx-tutorial-series-7.png

In the Code Generator tab, specify the Generated files by selecting the option Generated peripheral initialization as a pair of'.c/.h' files per IP.

Stm32cubemx-tutorial-series-8.png

Click the icon Stm32cubemx-tutorial-series-9.png to generate the code. And then, click the button Open Project. Now, the peripheral initialization of the project is finish.

Click the button Build, and wait for a while. The Build Output message box will output 0 Error(s), 0 warning(s).

Stm32cubemx-tutorial-series-10.png

At the end of the file gpio.c, add the following functions between the lines USER CODE BEGIN 2 and USER CODE END 2. (User code should be added between the lines USER CODE BEGIN N and USER CODE END N, or else the new added code will be removed on next code regeneration.)


/* USER CODE BEGIN 2 */
  
/**
  * @brief  Turns selected LED On.
  * @param  Led: LED to be set on
  *          This parameter can be one of the following values:
  *            @arg  LED1
  *            @arg  LED2
  *            @arg  LED3
  *            @arg  LED4
  * @retval None
  */
void BSP_LED_On(Led_TypeDef Led)
{
  HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_SET);
}
  
/**
  * @brief  Turns selected LED Off.
  * @param  Led: LED to be set off
  *          This parameter can be one of the following values:
  *            @arg  LED1
  *            @arg  LED2
  *            @arg  LED3
  *            @arg  LED4
  * @retval None
  */
void BSP_LED_Off(Led_TypeDef Led)
{
  HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_RESET);
}
  
/**
  * @brief  Toggles the selected LED.
  * @param  Led: LED to be toggled
  *          This parameter can be one of the following values:
  *            @arg  LED1
  *            @arg  LED2
  *            @arg  LED3
  *            @arg  LED4
  * @retval None
  */
void BSP_LED_Toggle(Led_TypeDef Led)
{
  HAL_GPIO_TogglePin(GPIO_PORT[Led], GPIO_PIN[Led]);
}
  
/**
  * @brief  Returns the current joystick status.
  * @retval Code of the joystick key pressed
  *          This code can be one of the following values:
  *            @arg  WAKEUP
  *            @arg  JOY_NONE
  *            @arg  JOY_CTR
  *            @arg  JOY_DOWN
  *            @arg  JOY_LEFT
  *            @arg  JOY_RIGHT
  *            @arg  JOY_UP
  */
JOYState_TypeDef BSP_JOY_GetState(void)
{ 
  /* Check the pressed keys */ 
    if(HAL_GPIO_ReadPin(WAKEUP_GPIO_Port,WAKEUP_Pin) == GPIO_PIN_SET)
  {
    return (JOYState_TypeDef) WAKEUP;
  }
  else if(HAL_GPIO_ReadPin(CTR_GPIO_Port,CTR_Pin) == GPIO_PIN_RESET)
  {
    return (JOYState_TypeDef) JOY_CTR;
  }
  else if(HAL_GPIO_ReadPin(DOWN_GPIO_Port,DOWN_Pin) == GPIO_PIN_RESET)
  {
    return (JOYState_TypeDef) JOY_DOWN;
  }
  else if(HAL_GPIO_ReadPin(LEFT_GPIO_Port,LEFT_Pin) == GPIO_PIN_RESET)
  {
    return (JOYState_TypeDef) JOY_LEFT;
  }
  else if(HAL_GPIO_ReadPin(RIGHT_GPIO_Port,RIGHT_Pin) == GPIO_PIN_RESET)
  {
    return (JOYState_TypeDef) JOY_RIGHT;
  }
  else if(HAL_GPIO_ReadPin(UP_GPIO_Port,UP_Pin) == GPIO_PIN_RESET)
  {
    return (JOYState_TypeDef) JOY_UP;
  }
  else
  {
    return (JOYState_TypeDef) JOY_NONE;
  } 
}
/* USER CODE END 2 */

The three function shown above are used to turn on the LED, turn off the LED, and switch the LED state. And the rest one is used to read the state of the key. Add the array variables of LED1-LED4 pins in front of the file gpio.c.


/* USER CODE BEGIN 1 */
GPIO_TypeDef* GPIO_PORT[] = {LED1_GPIO_Port,
                             LED2_GPIO_Port,
                             LED3_GPIO_Port,
                             LED4_GPIO_Port};
  
const uint16_t GPIO_PIN[] = {LED1_Pin,
                             LED2_Pin,
                             LED3_Pin,
                             LED4_Pin};
/* USER CODE END 1 */

In front of the file gpio.h, add two enumeration type variables, Led_TypeDefand JOYState_TypeDef. And declare the new added functions.

/* USER CODE BEGIN Private defines */
typedef enum
{
  LED1 = 0,
  LED2 = 1,
  LED3 = 2,
  LED4 = 3
}Led_TypeDef;
  
typedef enum
{
  JOY_NONE  = 0,
  JOY_CTR   = 1,
  JOY_DOWN  = 2,
  JOY_LEFT  = 3,
  JOY_RIGHT = 4,
  JOY_UP    = 5,
  WAKEUP    = 6
}JOYState_TypeDef;
/* USER CODE END Private defines */
  
void MX_GPIO_Init(void);
  
/* USER CODE BEGIN Prototypes */
void BSP_LED_On(Led_TypeDef Led);
void BSP_LED_Off(Led_TypeDef Led);
void BSP_LED_Toggle(Led_TypeDef Led);
JOYState_TypeDef BSP_JOY_GetState(void);
/* USER CODE END Prototypes */

In the main.c file, add the applicationcode into the while loop under the main routine. The switch case statement should be used in the code. And BSP_JOY_GetState() can judge whether there is keypressing. If there is, change the states of LED1~LED4 according to the pressed key.

/* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */
  
  /* USER CODE BEGIN 3 */
    switch(BSP_JOY_GetState())
    {
      case JOY_UP:
        BSP_LED_On(LED1);break;
      case JOY_RIGHT:
        BSP_LED_On(LED2);break;
      case JOY_DOWN:
        BSP_LED_On(LED3);break;  
      case JOY_LEFT:
        BSP_LED_On(LED4);break;
      case JOY_CTR:
      case WAKEUP:
        BSP_LED_On(LED1);
        BSP_LED_On(LED2);
        BSP_LED_On(LED3);
        BSP_LED_On(LED4);
        break;
      default:
        BSP_LED_Off(LED1);
        BSP_LED_Off(LED2);
        BSP_LED_Off(LED3);
        BSP_LED_Off(LED4);
        break;
    }
  }
/* USER CODE END 3 */

Compile the program again. In case of no error, click the icon Stm32cubemx-tutorial-series-11.png to download the program to the Open746I-C development board. Ifthere is error(s) signaled, click the icon Stm32cubemx-tutorial-series-12.png to modify the optionDebug of Option for Target.(In the figure above, ST-LINK is selected)

Stm32cubemx-tutorial-series-13.png

Click Settings->Flash Download, and check the option Reset and Run. Then, the program will auto start up after downloaded to the development board. You do not need to press the reset key or power up the device again.

Stm32cubemx-tutorial-series-14.png

When finished the configuration above, you can download the program and look forward to the result. By pressing different keys, LED1~LED2 will show different states. The program described above can server as a template, which we can modify it for future use.