【STM32嵌入式系统设计与开发】——5独立按键应用


STM32资料包:
百度网盘下载链接:链接:https://pan.baidu.com/s/1mWx9Asaipk-2z9HY17wYXQ?pwd=8888
提取码:8888


一、任务描述

在这里插入图片描述

二、任务实施

观察流水灯电路图,电流/端口 -------->按键判断是否按下--------->GND,DK0 -DK4按键有按下PC4 - PC7端口收到上拉输入,从而控制led灯。
请添加图片描述

1、SingleKey工程文件夹创建

步骤1:复制工程模板“1_Template”重命名为“3_SingleKey”
在这里插入图片描述
步骤2:修改项目工程名,先删除projects文件夹内除了Template.uvprojx文件外的所有内容并修改为“SingleKey.uvprojx”。并删除output/obj和output/lst中的所有文件。
在这里插入图片描述
步骤3:运行“SingleKey.uvprojx”打开目标选项“Options for Target”中的“Output”输出文件,并修改可执行文件名称为“SingleTest”点击“OK”保存设置。最后点击“Rebuild”编译该工程生成SingleTest文件。
在这里插入图片描述
步骤4:复制“2_LEDTest”中的"1_LED"文件复制到hardware中。
在这里插入图片描述
步骤5:新建“2_SingleKey”文件,并在该文件夹下新建“SingleKey.c”和“SingleKey.h”两个文件。
在这里插入图片描述
步骤6:工程组文件中添加“led.c”和“SingleKey.c”文件。
在这里插入图片描述
步骤7:目标选项添加添加头文件路径
在这里插入图片描述

2、函数编辑

(1)主函数编辑

在这里插入图片描述

步骤1:端口初始化准备

//函数初始化,端口准备
	delay_init(); //启动滴答定时器,延时函数
	LED_Init();   //板载LED初始化
    ExpKeyInit(); //开发板按键初始化

在这里插入图片描述

步骤2:循环工作代码编辑,读取按键并判断按键模式,按下则点亮led灯,否则LED灯熄灭

while(1)
{	 								
    KeyValue = ExpKeyScan(0); // 读取按键状态
    
    if(KeyValue)              // 如果按键按下
    {
        LED = 0;              // 点亮LED
        delay_ms(200);        // 延时200毫秒
    }                         
    else                      // 如果按键未按下
    {
        LED = 1;             // 关闭LED
        delay_ms(200);       // 延时200毫秒
    }
}

在这里插入图片描述

(2)LED IO初始化函数(LED_Init())

void LED_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;                  // 定义 GPIO 初始化结构体变量
    
    /* 时钟使能 */	
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能 GPIOA 时钟
    
    /* 引脚配置 */	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;             // 将板载 LED 连接的引脚设置为 PA8
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      // 设置引脚为推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     // 设置引脚的输出速度为 50MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure);                // 应用以上配置到 GPIOA 上
    
    GPIO_SetBits(GPIOA, GPIO_Pin_8);                      // 将 GPIOA 的引脚 PA8 设置为高电平,使得板载 LED 灭
}

在这里插入图片描述

(3)开发板按键初始化函数(ExpKeyInit())

初始化PA4 - PA7端口,并为上拉输入。

/*********************************************************************
 @Function  : 初始化开发板按键GPIO
 @Parameter : None 
 @Return    : None
**********************************************************************/
void ExpKeyInit(void) // 初始化按键GPIO
{ 
    GPIO_InitTypeDef GPIO_InitStructure;

    /* 使能GPIOC时钟 */	
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

    /* 配置GPIO引脚为上拉输入模式 */	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;  // 将开发板四个按键连接到PC4~PC7
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入模式
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}

在这里插入图片描述

(4)按键扫描的函数(ExpKeyScan())

根据按键按下的情况返回相应的按键值。注意函数中的响应优先级,优先级由高到低分别为 DK1、DK2、DK3、DK4。

/*********************************************************************
 @Function  : 按键扫描函数
 @Parameter : mode : 连按模式
                0:不支持连按
                1:支持连按
 @Return    : 按键值
 @Read      : 注意此函数有响应优先级, DK1 > DK2 > DK3 > DK4 !!
**********************************************************************/
uint8_t ExpKeyScan(uint8_t mode)
{	 
    static uint8_t key_up = 1; // 按键按松开标志
    if (mode) // 如果支持连按
        key_up = 1;  

    if (key_up && (DK1 == 0 || DK2 == 0 || DK3 == 0 || DK4 == 0))
    {
        delay_ms(10); // 去抖动 
        key_up = 0;
        if (DK1 == 0) return DK1_PRES;
        else if (DK2 == 0) return DK2_PRES;
        else if (DK3 == 0) return DK3_PRES;
        else if (DK4 == 0) return DK4_PRES;
    }
    else if (DK1 == 1 && DK2 == 1 && DK3 == 1 && DK4 == 1)
        key_up = 1; 	    
 	return NO_PRES; // 无按键按下
}

在这里插入图片描述

3、宏定义

(1)源文件添加头文件

步骤1:按键功能文件中添加相关头文件,源文件报错消失部分

#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include ".\delay\delay.h"
#include "SingleKey.h"

在这里插入图片描述
步骤2:主函数添加所需的led和SingleKey头文件,主源文件部分报错消失

/***********Hardweare***************/
#include "led.h"
#include "SingleKey.h"

在这里插入图片描述

(2)按键头文件编辑

步骤1:创建一个宏定义保护

#ifndef _SINGLEKEY_H
#define _SINGLEKEY_H





#endif

在这里插入图片描述
步骤2:添加宏定义

#define DK1  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_4)//DK1->PC4
#define DK2  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)//DK2->PC5
#define DK3  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_6)//DK3->PC6
#define DK4  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_7)//DK4->PC7

#define NO_PRES   0 //没有按键按下
#define DK1_PRES 	1	//DK1按下
#define DK2_PRES	2	//DK2按下
#define DK3_PRES 	3	//DK3按下
#define DK4_PRES	4	//DK4按下

在这里插入图片描述
步骤3:添加函数声明
在这里插入图片描述
步骤4:添加数据类型和宏的头文件

#include <stdint.h>

在这里插入图片描述

4、知识链接

(1)GPIO的8种工作模式

在这里插入图片描述

(2)输入模式

VDD:VDD 表示电源的正极或供电端。在数字电路中,VDD 通常是电路中逻辑高
电平的参考电压,也就是正电源电压。例如,在大多数逻辑电路中,VDD 可能是 3.3V 或 5V。

VSS:VSS 表示电源的负极或地端。在数字电路中,VSS 通常是电路中逻辑低电平的参考电压,也就是地线或接地。在电源供电方案中,VSS 通常被连接到地,作为电路的参考地。

步骤1:(GPIO_Mode_AIN) 模拟输入
用于连接模拟传感器或其他模拟设备,接收模拟信号输入。通常不适用于数字控制。
在这里插入图片描述

步骤2:(GPIO_Mode_IN_FLOATING)浮空输入
用于连接外部设备的传感器、开关等。当外部设备未激活时,GPIO 引脚处于高阻态。
在这里插入图片描述
步骤3:(GPIO_Mode_IPD) 下拉输入
用于连接需要下拉电阻的开关或按钮。当开关未接通时,引脚保持低电平。
在这里插入图片描述
步骤4:(GPIO_Mode_IPU) 上拉输入
用于连接需要上拉电阻的开关或按钮。当开关未接通时,引脚保持高电平。
在这里插入图片描述

(2)输出模式

步骤1:(GPIO_Mode_Out_OD) 开漏输出
用于与其他设备共享总线,如 I2C、SPI 等。通常需要外部上拉电阻,适用于多设备共享总线的场景。
在这里插入图片描述
步骤2:(GPIO_Mode_Out_PP) 推挽输出
用于控制外部设备的开关,如 LED、电机、继电器等。适用于需要提供电流的输出设备。
在这里插入图片描述
步骤3:(GPIO_Mode_AF_OD) 复用开漏输出
与复用推挽输出类似,但在低电平时将引脚接地。通常用于需要多个设备共享总线的场景。
在这里插入图片描述
步骤4:(GPIO_Mode_AF_PP) 复用推挽输出
用于连接到外设的复用功能,例如串口通信、定时器输出等。同时具有推挽输出和外设复用功能。
在这里插入图片描述

5、工程测试

在这里插入图片描述

最近更新

  1. TCP协议是安全的吗?

    2024-03-20 11:04:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-20 11:04:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-20 11:04:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-20 11:04:01       20 阅读

热门阅读

  1. docker离线安装

    2024-03-20 11:04:01       21 阅读
  2. Android 12 SystemUI调试

    2024-03-20 11:04:01       19 阅读
  3. 模拟计算机和数字计算机

    2024-03-20 11:04:01       16 阅读
  4. 服务器时间不准确的风险

    2024-03-20 11:04:01       18 阅读
  5. Python基础----冒泡排序和二分查找(持续更新中)

    2024-03-20 11:04:01       20 阅读
  6. LeetCode题练习与总结:组合总和Ⅱ

    2024-03-20 11:04:01       20 阅读
  7. HTTP与TCP的特点

    2024-03-20 11:04:01       18 阅读
  8. C++ 面试100问--完结(十一)

    2024-03-20 11:04:01       17 阅读
  9. C++ 中的 Pimpl 惯用法

    2024-03-20 11:04:01       19 阅读
  10. etcd 和 Redis 的对比:特点与适用场景

    2024-03-20 11:04:01       19 阅读
  11. CCF编程能力等级认证GESP—C++6级—20240316

    2024-03-20 11:04:01       19 阅读
  12. 【VSTO开发】selectionRange.PasteExcelTable解析

    2024-03-20 11:04:01       17 阅读
  13. out.as_ptr() as *mut libc::c_char

    2024-03-20 11:04:01       18 阅读