描述

本文利用按钮来控制LED灯的开与关。

  • 研发平台:淘宝上购买的野火店铺的一款单片机,名字叫骄阳开发板,核心芯片是
    stm32F407IGT6

该单片机我要使用其中除了复位按钮的其他5个按钮,第1个按钮控制全部4个灯的状态翻转,后4个按钮分别控制4个灯

思路

我们依旧使用CubeMX来创建一个工程,选择我们使用的芯片型号,并在CubeMX的帮助下设置管脚
具体的思路就是

  1. 打开CubeMX,按照你的芯片型号构建一个空白工程
  2. 利用单片机的原理书,找到led和按钮分别对应的管脚,并在CubeMX中完成配置
  3. 代码中进行修改,一个按钮控制一个灯

步骤

  1. 打开CubeMX软件,选择左上角的“File”——“New Project”,建造一个新的工程
  2. 选择你的芯片类型,我的是F407IGT6,因此选择的是“F407IGTx”,双击确定
  3. 接下来你就会进入核心的芯片管脚编辑界面了
  4. 找到你使用单片机的原理图,找到LED的部分,确定每一个灯的控制管脚。
  5. 以我单片机的原理图为例,四个灯的管脚分别为PA15、PE2、PG15、PB8。如有不清楚请按照上一篇文章来进行配置stm32控制LED灯(Develop文章1.1)
  6. 找到你使用单片机的原理图,找到按钮的部分,确定每一个按钮的控制管脚。可以看到,我使用的单片机有6个按钮,名字分别为SW2~SW7。原理图上说的很清楚,SW7是复位按钮,SW2-SW6是普通的按钮。
  7. 以我单片机的原理图为例,5个按钮的管脚分别为PA0、PG2、PC13、PG3、PG4。
  8. 将这5个管脚均设置为GPIO_Input,GPIO Pull-up/Pull-down选项设置为“No pull-up and no pull-down”
  9. 按钮和LED灯均设置好后,上方菜单栏界面选择“Project Manager”一栏,进行工程配置。注意,要将Toolchain/IDE“” 选择“MDK-ARM”,这样才是使用keil来创建代码
  10. 生成代码后,打开工程,在main.c文件中添加一段函数

    int get_key_status(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
    {
    if (HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == GPIO_PIN_SET)
    {
        while(HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == GPIO_PIN_SET);
        return 1;
    }
    else
    {
        return 0;
    }
    }
    

    代码的含义是来读取按钮的状态,按钮弹开就是RESET,返回0;按钮被按下没松开前,一直不返回值,直到再次弹开,会返回1
    我把这段代码添加在了main函数前面,以保证在main函数中使用不会报错

  11. 在主循环while中再添加如下的代码

    if (get_key_status(GPIOA, GPIO_PIN_0))
        {
            HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_15);
            HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_2);
            HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_15);
            HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
        }
        if (get_key_status(GPIOG, GPIO_PIN_2))
        {
            HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_15);
        }
        if (get_key_status(GPIOC, GPIO_PIN_13))
        {
            HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_2);
        }
        if (get_key_status(GPIOG, GPIO_PIN_3))
        {
            HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_15);
        }
        if (get_key_status(GPIOG, GPIO_PIN_4))
        {
            HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
        }
    

    HAL_GPIO_TogglePin能够翻转指定管脚的电平

  12. 构建工程并编译,将代码下载到单片机中。按钮从左数一共6个,按钮一共4个。按钮第一个是复位按钮。按下第2个按钮,全部四个led灯的状态被翻转;按下第3、4、5、6个按钮,4个led灯的状态逐个被翻转

纯代码来实现同样的目的

当我们不想通过CubeMX来配置,只是想通过手写代码的方式来实现相同的功能该怎么做呢?
写板级支持包呗
实际上,就是写几个头文件和c文件,在代码中将CubeMX做的事情用代码写出来

这里我们为了实现按钮控制led灯,我们添加4个文件到工程中,能实现相同的目的。这四个文件分别是:led.h、led.c、key.h和key.c

led.h

#ifndef __LED_H__
#define __LED_H__

#include "stm32f4xx.h"

void LED_init(void);
void LED_on(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void LED_off(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void LED_reverse(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

#endif

led.c

#include "../include/led.h"

void LED_init()
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin : PE2 */
  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  /*Configure GPIO pin : PA15 */
  GPIO_InitStruct.Pin = GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PG15 */
  GPIO_InitStruct.Pin = GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

  /*Configure GPIO pin : PB8 */
  GPIO_InitStruct.Pin = GPIO_PIN_8;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void LED_on(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
    HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_RESET);
}

void LED_off(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
    HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_SET);
}

void LED_reverse(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
    HAL_GPIO_TogglePin(GPIOx, GPIO_Pin);
}

key.h

#ifndef __KEY_H__
#define __KEY_H__

#include "stm32f4xx.h"
void key_init(void);
int get_key_status(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

#endif

key.c

#include "../include/key.h"


void key_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();

  /*Configure GPIO pin : PA0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PG2 */
  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

  /*Configure GPIO pin : PC13 */
  GPIO_InitStruct.Pin = GPIO_PIN_13;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

      /*Configure GPIO pin : PG3 */
  GPIO_InitStruct.Pin = GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

      /*Configure GPIO pin : PG4 */
  GPIO_InitStruct.Pin = GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
}

int get_key_status(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
    if (HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == GPIO_PIN_SET)
    {
        while(HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == GPIO_PIN_SET);
        return 1;
    }
    else
    {
        return 0;
    }
}

总结

本文利用CubeMX和代码两种方式,完成了野火骄阳开发板,按钮控制led灯的功能