STM32CubeMX系列 | 按键输入

发布时间:2023-03-20  

按键输入

1. 实验介绍

本实验介绍如何使用STM32F103的IO口作为输入使用。IO口作为输入使用时,是通过读取IDR的内容来读取IO口的状态的。 本实验利用板载的4个按键,来控制板载的两个LED的亮灭和蜂鸣器。其中KEY_UP控制蜂鸣器;K1控制D1,按一次亮再按一次灭;K2控制D2,按一次亮再按一次灭;K3同时控制D1和D2,按一次它们的状态就翻转一次

2. 硬件设计

用到的硬件资源有:

  • 指示灯D1、D2

  • 蜂鸣器BUZ

  • 4个按键:KEY_UP、K1、K2、K3

硬件连接原理图如下,注意K1、K2、K3是低电平有效的,而KEY_UP是高电平有效,并且外部都没有上下拉电阻,所以需要在STM32F1内部设置上下拉; STM32F103芯片单个IO口最大输出电流是25mA,而蜂鸣器的驱动电流是30mA左右,整个芯片的输出电流最大为150mA,如果在蜂鸣器上就消耗30mA,那么芯片的其他IO口及外设电流就比较拮据了,因此此处不会直接使用IO口驱动蜂鸣器,而是通过三极管把电流放大后再驱动蜂鸣器,这样IO口只需提供不到1mA的电流就可以控制蜂鸣器

3. 软件设计

3.1 STM32CubeMX设置

  • RCC设置外接HSE,时钟设置为72M

  • PC0和PC1设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平

  • PB5设置为GPIO推挽输出、高速模式

  • PA0设置为GPIO输入模式、下拉模式;PE2/PE3/PE4设置为GPIO输入模式、上拉模式

  • 输入工程名,选择工程路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码

3.2 MDK-ARM软件编程

  • 在gpio.c文件中可以看到PC0/PC1/PB5/PA0/PE2/PE3/PE4管脚的初始化函数

void MX_GPIO_Init(void)

{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */

  __HAL_RCC_GPIOE_CLK_ENABLE();     //开启GPIOE时钟

  __HAL_RCC_GPIOC_CLK_ENABLE();     //开启GPIOC时钟

  __HAL_RCC_GPIOA_CLK_ENABLE();     //开启GPIOA时钟

  __HAL_RCC_GPIOB_CLK_ENABLE();     //开启GPIOB时钟

  /*Configure GPIO pin Output Level */

  HAL_GPIO_WritePin(GPIOC, LED1_Pin|LED2_Pin, GPIO_PIN_SET);    //LED1/LED2默认输出是电平为高电平

  /*Configure GPIO pin Output Level */

  HAL_GPIO_WritePin(BUZ_GPIO_Port, BUZ_Pin, GPIO_PIN_RESET);    //BUZ默认输出是电平为低电平    

  /*Configure GPIO pins : PEPin PEPin PEPin */

  GPIO_InitStruct.Pin = K_LEFT_Pin|K_DOWN_Pin|K_RIGHT_Pin;      //PE2/PE3/PE4

  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;                       //输入

  GPIO_InitStruct.Pull = GPIO_PULLUP;                           //上拉

  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  /*Configure GPIO pins : PCPin PCPin */

  GPIO_InitStruct.Pin = LED1_Pin|LED2_Pin;                      //PC0/PC1

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;                   //推挽输出

  GPIO_InitStruct.Pull = GPIO_PULLUP;                           //上拉

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;                 //高速

  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PtPin */

  GPIO_InitStruct.Pin = K_UP_Pin;                               //PA0

  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;                       //输入

  GPIO_InitStruct.Pull = GPIO_PULLDOWN;                         //下拉

  HAL_GPIO_Init(K_UP_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : PtPin */

  GPIO_InitStruct.Pin = BUZ_Pin;                                //PB5

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;                   //推挽输出

  GPIO_InitStruct.Pull = GPIO_NOPULL;                           //无上下拉

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;                 //高速

  HAL_GPIO_Init(BUZ_GPIO_Port, &GPIO_InitStruct);

}

在工程的应用文件目录下创建key.c文件,编写按键相关函数

/***********************************************************

*函 数 名: KEY_Scan(uint8_t mode)

*功    能: 按键处理函数

*形    参: mode:0 不支持连续按;1 支持连续按

*返 回 值: 返回按键值   0:表示未有按键按下

*                     1:KEY_RIGHT按下   2:KEY_DOWN按下

*                     3:KEY_LEFT按下    4:KEY_UP按下

***********************************************************/

uint8_t KEY_Scan(uint8_t mode)

{

    static uint8_t key = 1;     //按键松开标志

    if(mode == 1){              //支持连按

        key = 1;

    }


    if(key&&(KEY_UP==1||KEY_DOWN==0||KEY_LEFT==0||KEY_RIGHT==0)){

        HAL_Delay(10);          //按键消抖

        key = 0;

        if(KEY_UP==1)           return K_UP_PRES;

        else if(KEY_DOWN==0)    return K_DOWN_PRES; 

        else if(KEY_LEFT==0)    return K_LEFT_PRES; 

        else if(KEY_RIGHT==0)   return K_RIGHT_PRES; 

    }

    else if(KEY_UP==0&&KEY_DOWN==1&&KEY_LEFT==1&&KEY_RIGHT==1){

        key = 1;

    }


    return 0;

}

在工程的头文件目录下创建key.h文件,编写相关声明

#ifndef _KEY_H_

#define _KEY_H_


#include "stm32f1xx.h"


//操作HAL库函数读取IO口状态

#define KEY_RIGHT   HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)

#define KEY_DOWN    HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)

#define KEY_LEFT    HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2)

#define KEY_UP      HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)

//定义按键按下时的键值

#define KEY_RIGHT_PRES  1

#define KEY_DOWN_PRES   2

#define KEY_LEFT_PRES   3

#define KEY_UP_PRES     4


uint8_t KEY_Scan(uint8_t mode);


#endif

在main.c函数中编写相关程序

int main(void)

{

  /* USER CODE BEGIN 1 */

    uint8_t key;

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */

  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */

  MX_GPIO_Init();

  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

  while (1)

  {

        key = KEY_Scan(0);

        switch(key){

            case KEY_UP_PRES:

                HAL_GPIO_WritePin(GPIOB,BUZ_Pin,GPIO_PIN_SET);

                HAL_Delay(300);

                HAL_GPIO_WritePin(GPIOB,BUZ_Pin,GPIO_PIN_RESET);

                HAL_Delay(300);

                break;

            case KEY_LEFT_PRES:

                HAL_GPIO_TogglePin(GPIOC,LED1_Pin);

                break;

            case KEY_DOWN_PRES:

                HAL_GPIO_TogglePin(GPIOC,LED2_Pin);

                break;

            case KEY_RIGHT_PRES:

                HAL_GPIO_TogglePin(GPIOC,LED1_Pin);

                HAL_GPIO_TogglePin(GPIOC,LED2_Pin);

                break;

        }

        HAL_Delay(10);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

  }

  /* USER CODE END 3 */

}

4. 下载验证

编译无误后下载到开发板,按下KEY_UP蜂鸣器响一下;K1控制D1,按一次亮再按一次灭;K2控制D2,按一次亮再按一次灭;K3同时控制D1和D2,按一次它们的状态就翻转一次


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>