STM32F401RE-Nucleo LED和BUTTON的例子

时间:2015-04-07 16:05:32

标签: stm32

我正在尝试在我的新Nucleo板上运行一个简单的程序,

当我按下用户按钮(蓝色按钮)时,我制作了这个程序以打开和关闭绿色指示灯,

#include "stm32f4xx.h"
#include "stm32f4xx_nucleo.h"
#include "system_stm32f4xx.h"
#include "stm32f4xx_hal_gpio.h"
#include "stm32f4xx_hal_rcc.h"

GPIO_InitTypeDef GPIO_InitStructure; 

int main(void) {

    HAL_Init(); 

    __GPIOA_CLK_ENABLE();
    GPIO_InitStructure.Pin   = GPIO_PIN_5;
    GPIO_InitStructure.Mode  = GPIO_MODE_OUTPUT_PP;    
    GPIO_InitStructure.Pull  = GPIO_PULLUP;
    GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;  
    HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);    

    __GPIOC_CLK_ENABLE();
    GPIO_InitStructure.Pin   = GPIO_PIN_13;
    GPIO_InitStructure.Mode  = GPIO_MODE_INPUT;
    GPIO_InitStructure.Pull  = GPIO_PULLDOWN;
    GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);

    while (1) {
        if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)) {         
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); 
        } else {
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
        }
    }
}

但我得错了结果:

  • 当我按下用户按钮时,没有任何反应,
  • 当我一直按下用户按钮并重新启动时(通过按下黑色按钮),我得到了很好的结果,

似乎程序只在第一次运行时检查蓝色按钮的状态,我不知道为什么,

如果您对问题的来源有任何想法,或者您有一个正在运行的程序按下按钮按下按钮,请帮助我。

6 个答案:

答案 0 :(得分:3)

我有同样的问题,这就是我如何解决它:

while (1) {
        int stateOfPushButton = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13);
        if ( stateOfPushButton == 1 ) {         
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); 
        } else {
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
        }
    }

答案 1 :(得分:1)

GPIO_PULLDOWN模式更改为GPIO_FLOATING(或类似名称)!

答案 2 :(得分:1)

设置按钮的GPIO Pull to PULLUP:

#include "stm32f4xx.h"
#include "stm32f4xx_nucleo.h"
#include "system_stm32f4xx.h"
#include "stm32f4xx_hal_gpio.h"
#include "stm32f4xx_hal_rcc.h"

GPIO_InitTypeDef GPIO_InitStructure; 

int main(void) {

    HAL_Init(); 

    __GPIOA_CLK_ENABLE();
    GPIO_InitStructure.Pin   = GPIO_PIN_5;
    GPIO_InitStructure.Mode  = GPIO_MODE_OUTPUT_PP;    
    GPIO_InitStructure.Pull  = GPIO_PULLUP;
    GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;  
    HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);    

    __GPIOC_CLK_ENABLE();
    GPIO_InitStructure.Pin   = GPIO_PIN_13;
    GPIO_InitStructure.Mode  = GPIO_MODE_INPUT;
    GPIO_InitStructure.Pull  = GPIO_PULLUP;
    GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);

    while (1) {
        if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)) {         
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); 
        } else {
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
        }
    }
}

答案 3 :(得分:1)

每当您将代码下载到板上时,微控制器都处于RESET模式,这就是为什么您的代码似乎无法使用的原因。按下“ BLACK RESET”按钮后,它将从main()运行您的代码,一切正常。

请记住,每次在微型计算机上刷新新代码时都要重设。

答案 4 :(得分:0)

如果你的按钮是我的机械2状态开关之类的更高电流,那么你想要使用这段代码:

GPIO_InitStructure.Pull  = GPIO_PULLUP;

并添加一个int变量也不会有什么问题,只需确保在启动main while函数之前只对变量进行一次初始化,否则最终会导致内存泄漏。

我也发现你不熟悉功能,请尝试以下方法:

int main(void) {

    /* Configure the system clock */
    SystemClock_Config();

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    HAL_Init();
    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        /* start your stuff*/
        /* doping stuff*/
        /* end your stuff*/
    }

}

/* System Clock Configuration*/
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  __HAL_RCC_PWR_CLK_ENABLE();

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
      Error_Handler();
  }
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                        |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
      Error_Handler();
  }

  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /*Configure GPIO pins : P_BUT_Pin R_BUT_Pin O_BUT_Pin I_CSW_Pin */
  GPIO_InitStruct.Pin = P_BUT_Pin|R_BUT_Pin|O_BUT_Pin|I_CSW_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /*Configure GPIO pins : P_LED_Pin R_LED_Pin O_LED_Pin C_LED_Pin */
  GPIO_InitStruct.Pin = P_LED_Pin|R_LED_Pin|O_LED_Pin|C_LED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOD, P_LED_Pin|R_LED_Pin|O_LED_Pin|C_LED_Pin, 
GPIO_PIN_RESET);

}

如果您不自信,请考虑使用以下工具:[http://www.st.com/en/development-tools/stm32cubemx.html]

答案 5 :(得分:0)

如果使用的是Keil MDK,请转到目标选项->调试->选择要使用的调试器,然后单击设置->在下载功能中,选中“重置并运行”,以便每次刷新时重置并运行代码在您的Nucleo板上。

您的代码和GPIO设置可以在使用我的Nucleo-F401RE的CubeMX IDE上运行,如果您使用的是IDE,只需在Keil中启用“重置并运行”。