cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103C6 HAL_GPIO_ReadPin() doesn't work properly (I think).

RedRabbit90
Associate II

Hi there.

I'm trying to read a button status using STM32F103C6 (fake BluePill) with STM32CubeIDE 1.13.1 and/or using Labcenter Proteus to simulate. However, the reading does not work correctly. I would like some help to understand what is missing.

My poor code:

 

#include "stm32f1xx_hal.h"
 
#define LED_Pin GPIO_PIN_13
#define LED_GPIO_Port GPIOC
#define BUTTON_Pin GPIO_PIN_1
#define BUTTON_GPIO_Port GPIOA
int main(void)
{
  HAL_Init();
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
 
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
 
  GPIO_InitStruct.Pin = LED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);
 
  GPIO_InitStruct.Pin = BUTTON_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(BUTTON_GPIO_Port, &GPIO_InitStruct);
 
  while (1)
  {
  if(HAL_GPIO_ReadPin(BUTTON_GPIO_Port, BUTTON_Pin)== GPIO_PIN_RESET){
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
  }else{
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
  }
  HAL_Delay(100);
  }
}
 
The schematic is so basic: button pin in GND, 1K resistor Pull UP.

Thanks in advance.


1 ACCEPTED SOLUTION

Accepted Solutions
RedRabbit90
Associate II

After trying for a long time, I got a solution out of nowhere...
Now it's only working in the real hardware (probably Proteus is not simulating correctly). The code is basically the same.

#include "stm32f1xx_hal.h"
 
#define LED_Pin GPIO_PIN_13
#define LED_GPIO_Port GPIOC
#define BUTTON_Pin GPIO_PIN_1
#define BUTTON_GPIO_Port GPIOA
 
int main(void)
{
  HAL_Init();
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
 
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(LED_B1_GPIO_Port, LED_B1_Pin, GPIO_PIN_SET);
 
  GPIO_InitStruct.Pin = LED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);
 
  GPIO_InitStruct.Pin = BUTTON_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP; // The concept is different for other types of MCUs.
  HAL_GPIO_Init(BUTTON_GPIO_Port, &GPIO_InitStruct);
  
  while (1)
  {
  if(HAL_GPIO_ReadPin(BUTTON_GPIO_Port, BUTTON_Pin)){
  HAL_GPIO_WritePin(LED_Pin, LED_GPIO_Port, GPIO_PIN_SET);   
  }else{
  HAL_GPIO_WritePin(LED_Pin, LED_GPIO_Port, GPIO_PIN_RESET);   
  }
  HAL_Delay(100);
  }
}

Thanks for help me!

View solution in original post

5 REPLIES 5
TDK
Guru

Your code is fine, and there's no bug in HAL_GPIO_ReadPin.

Recheck your connections. Remove the button and jump PA1 directly to GND to verify that works.

Toggle the LED separately to verify that it works.

If you feel a post has answered your question, please click "Accept as Solution".
RedRabbit90
Associate II

Hi TDK...

"Toggle the LED separately to verify that it works."
It was the first item that I did, the toggle the LED separately is worked fine!

"Recheck your connections. Remove the button and jump PA1 directly to GND to verify that works."
It was the second item that I did, before open this topic.

I even changed to the multiple pins ofs buttons, PA0,PA1, PA2,PA3,PA4,PA5,PA6,PA7,PB1... same issue.

Thanks.

Okay, good. If both of those tests worked, that would indicate the problem is with your button or button wiring.

If you feel a post has answered your question, please click "Accept as Solution".
RedRabbit90
Associate II

After trying for a long time, I got a solution out of nowhere...
Now it's only working in the real hardware (probably Proteus is not simulating correctly). The code is basically the same.

#include "stm32f1xx_hal.h"
 
#define LED_Pin GPIO_PIN_13
#define LED_GPIO_Port GPIOC
#define BUTTON_Pin GPIO_PIN_1
#define BUTTON_GPIO_Port GPIOA
 
int main(void)
{
  HAL_Init();
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
 
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(LED_B1_GPIO_Port, LED_B1_Pin, GPIO_PIN_SET);
 
  GPIO_InitStruct.Pin = LED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);
 
  GPIO_InitStruct.Pin = BUTTON_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP; // The concept is different for other types of MCUs.
  HAL_GPIO_Init(BUTTON_GPIO_Port, &GPIO_InitStruct);
  
  while (1)
  {
  if(HAL_GPIO_ReadPin(BUTTON_GPIO_Port, BUTTON_Pin)){
  HAL_GPIO_WritePin(LED_Pin, LED_GPIO_Port, GPIO_PIN_SET);   
  }else{
  HAL_GPIO_WritePin(LED_Pin, LED_GPIO_Port, GPIO_PIN_RESET);   
  }
  HAL_Delay(100);
  }
}

Thanks for help me!

The wire and button is ok! Checked twice.