STM32F103RCT6开发板M3单片机教程04--按键检测


原画图讲解


本教程使用是(光明谷SUN_STM32mini开发板


首先了硬件连接原理,STM32F103RCT6开发板是mini最小系统板,板子在没并有按键。需要自行用面包板搭建。

硬件连接:  

PC10 -> KEY1 (MCU内部上拉) --> GND   (低电平有效)

PC11 -> KEY2(MCU内部上拉) --> GMD    (低电平有效)

程序设计

有两种方法:

方法1、不断检测引脚(PC10, PC11)电平, 当检测到引脚(PC10, PC11)为低电平时,则有按键按下;

方法2、中断检测,设置引脚(PC10, PC11)下降沿触中断,在中断函数里,判断是哪个引脚发生的中断。

现在我们用方法1,编写代码。下集我们用中断方法。

编写代码

  • 复制上节工程文件夹打开(这个方法比较方便)
  • 新建源文件key.c,添加key.c到BSP(Grounp),并编辑
    /**********************************************************************************
    
    * 文件名  :key.c
    
    * 描述    :按键扫描(系统滴答时钟SysTick实现扫描延时)
    
    * 实验平台:Sun_STM32Min系统板
    
    * 硬件连接:  PC10 -> KEY1  --> GND   
    
    *             PC11 -> KEY2 --> GMD      
    
    * 库版本  :ST_v3.5
    
    
    
    * Version    Date       Auther      Reversed History
      ----------------------------------------------------------------------------
    
      V1.0.0    2021-11-07  Lojam Fan  Fisrt Created
      
    
    * (C) Sunshine Silicon Corporation
    *  Website: http://www.sunsili.com  http://sunsili.taobao.com http://bbs.sunsili.com
    *  E-Mail : fan@sunsili.com
    
    **********************************************************************************/
    
    
    #include "key.h"
    #include "SysTick.h"
    
    /*******************************************************************************
    * 函数名  : Key_GPIO_Config
    * 描述    : KEY IO配置
    * 输入    : 无
    * 输出    : 无
    * 返回    : 无
    * 说明    : KEY(1~2)的IO口分别是:PC10,PC11
    
    *******************************************************************************/
    
    void Key_GPIO_Config(void)
    {
            GPIO_InitTypeDef  GPIO_InitStructure;                                //定义一个GPIO_InitTypeDef类型的GPIO初始化结构体        
    
            RCC_APB2PeriphClockCmd(KEY_RCC, ENABLE);                        //使能GPIOA的外设时钟 
            GPIO_InitStructure.GPIO_Pin = KEY1 | KEY2;                        //选择要初始化的GPIOA引脚(PA15,PA14)
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                //设置引脚工作模式为上拉输入            
    
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //设置引脚输出最大速率为50MHz
            GPIO_Init(KEY_PORT, &GPIO_InitStructure);                        //调用库函数中的GPIO初始化函数,初始化GPIOA中的PA15,PA14引脚
    }
    
    
    /*******************************************************************************
    * 函数名  : Key_Detection
    * 描述    : 按键按下检测
    * 输入    : GPIOx:按键对应的GPIO,GPIO_Pin:对应按键端口
    * 输出    : 无
    * 返回    : KEY_DOWN(0):对应按键按下,KEY_UP(1):对应按键没按下
    * 说明    : KEY(1~2)的IO口分别是:PC10,PC11
    
    *******************************************************************************/
    
    u8 Key_Down_Detection(GPIO_TypeDef* GPIOx, u16 GPIO_Pin)
    {                        
    
            if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_DOWN)        //检测是否有按键按下
            {
                    Delay_nMs(10);        //延时消抖               
    
                    if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_DOWN)        //检测是否有按键按下
                   {
                            while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_DOWN);        //等待按键释放 
    
                            return KEY_DOWN;        
    
                    }
                    else
                    {
                            return KEY_UP;
                    }
            }
            else
            {
                    return KEY_UP;
            }
    }
    
    
    
    /*******************************************************************************
    * 函数名  : Key_Down_Scan
    * 描述    : 按键按下扫描
    * 输入    : 无
    * 输出    : 0:没有按键按下,
                1:按键按下
    * 返回    : 无
    * 说明    : KEY(1~2)的IO口分别是:PC10,PC11
    *******************************************************************************/
    
    u8 Key_Down_Scan(void)
    {
            u16 downflag=0;
            u8 value=0;
    
            downflag=GPIO_ReadInputData(KEY_PORT);
    
            if((downflag & 0x0c00) != 0x0c00)        //检测是否有按键按下
            { 
                    Delay_nMs(10);        //延时消抖       
    
                    downflag = GPIO_ReadInputData(KEY_PORT) & 0x0c00;        
    
                    if(downflag != 0x0c00 )        //检测是否有按键按下 
                    {
                            if((downflag & 0x0400) == 0) value |= 0x01;
                            if((downflag & 0x0800) == 0) value |= 0x02;    
                    }
            }  
    
            return value;
    }
    
    
    
    
    /******************* (C) COPYRIGHT SUNSHINE SILICON  **************************
    
    ********************        END OF FILE key.c        *******************/

  • 新建源文件key.h,并编辑
    /**********************************************************************************
    
    * 文件名  :led.c
    
    * 描述    :led 应用函数库         
    
    * 实验平台:Sun_STM32Min系统板
    
    * 硬件连接:  PA5 -> LED1    板子上没有 要用杜绑线外接
    
    *             PA6 -> LED2   板子上没有 要用杜绑线外接  
    
    *             PA7 -> LED3   板子上没有 要用杜绑线外接
    
    *             PA8 -> LED4   板子有直接观察
    
    * GPIO置低电平亮LED
    
    
    
    * 库版本  :ST_v3.5
    
    
    
    * Version    Date       Auther      Reversed History
    
      ----------------------------------------------------------------------------
    
      V1.0.0    2021-11-07  Lojam Fan  Fisrt Created
    
      
    
    * (C) Sunshine Silicon Corporation
    
    *  Website: http://www.sunsili.com  http://sunsili.taobao.com http://bbs.sunsili.com
    
    *  E-Mail : fan@sunsili.com
    
    **********************************************************************************/
    
    
    
    #include "Led.h"
    
               
    
    /*******************************************************************************
    
    * 函数名  : LED_GPIO_Config
    
    * 描述    : LED IO配置
    
    * 输入    : 无
    
    * 输出    : 无
    
    * 返回    : 无
    
    * 说明    : LED(1~4)的IO口分别是:PB5,PB6,PB7,PB8
    
    *******************************************************************************/
    
    void LED_GPIO_Config(void)
    
    {
    
            GPIO_InitTypeDef  GPIO_InitStructure;                                //定义一个GPIO_InitTypeDef类型的GPIO初始化结构体
    
            
    
            RCC_APB2PeriphClockCmd(LED_RCC, ENABLE);                        //使能GPIOB的外设时钟        
    
            
    
            GPIO_InitStructure.GPIO_Pin = LED_ALL;                                //选择要初始化的GPIOB引脚(PB5,PB6,PB7,PB8)
    
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //设置引脚工作模式为通用推挽输出                 
    
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //设置引脚输出最大速率为50MHz
    
            GPIO_Init(LED_PORT, &GPIO_InitStructure);                        //调用库函数中的GPIO初始化函数,初始化GPIOB中的PB5,PB6,PB7,PB8引脚
    
    
    
            LED_ALL_OFF();                                                                                //关闭ALL_LED                                          
    
    }
    
    
    
    /*点亮LED1.PA5*/
    
    void LED1_ON(void)
    
    {
    
            GPIO_ResetBits(LED_PORT,LED1);
    
    }
    
    
    
    /*关闭LED1.PA5*/
    
    void LED1_OFF(void)
    
    {
    
            GPIO_SetBits(LED_PORT,LED1);
    
    }
    
    
    
    /*点亮LED2.PA6*/
    
    void LED2_ON(void)  
    
    {
    
            GPIO_ResetBits(LED_PORT,LED2);
    
    }
    
    
    
    /*关闭LED2.PA6*/
    
    void LED2_OFF(void)
    
    {
    
            GPIO_SetBits(LED_PORT,LED2);
    
    }
    
    
    
    /*点亮LED3.PA7*/
    
    void LED3_ON(void)   
    
    {
    
            GPIO_ResetBits(LED_PORT,LED3);
    
    }
    
    
    
    /*关闭LED3.PA7*/
    
    void LED3_OFF(void)  
    
    {
    
            GPIO_SetBits(LED_PORT,LED3);
    
    }
    
    
    
    /*点亮LED4.PA8*/
    
    void LED4_ON(void)
    
    {
    
            GPIO_ResetBits(LED_PORT,LED4);
    
    }
    
    
    
    /*关闭LED4.PA8*/
    
    void LED4_OFF(void)
    
    {
    
            GPIO_SetBits(LED_PORT,LED4);
    
    }
    
    
    
    /*点亮ALL_LED*/
    
    void LED_ALL_ON(void)
    
    {
    
            GPIO_ResetBits(LED_PORT,LED_ALL);
    
    }
    
    /*关闭ALL_LED*/
    
    void LED_ALL_OFF(void)  
    
    {
    
            GPIO_SetBits(LED_PORT,LED_ALL);
    
    }
    
    
    
    
    
    /******************* (C) COPYRIGHT SUNSHINE SILICON  **************************
    
    ********************        END OF FILE led.c        *******************/

  • 编辑main.c
    /**********************************************************************************
    
    * Sun STM32 mini Demo
    
    
    
    *   Description
    
       
    
        Uart Demo
    
    
    
       
    
    * Version    Date       Auther      Reversed History
    
      ----------------------------------------------------------------------------
    
      V1.0.0    2021-11-07  Lojam Fan  Fisrt Created
    
      
    
    * (C) Sunshine Silicon Corporation
    
    *  Website: http://www.sunsili.com  http://sunsili.taobao.com http://bbs.sunsili.com
    
    *  E-Mail : fan@sunsili.com
    
    
    
    **********************************************************************************/
    
    
    
    #include "stm32f10x.h"
    
    #include "usart.h"
    
    #include "SysTick.h"
    
    #include "led.h"
    
    #include "key.h"
    
    #include <stdio.h>
    
    
    
    
    
    extern vu8 Usart1_R_Buff[USART1_REC_MAXLEN];        //串口1数据接收缓冲区
    
    extern vu8 Usart1_R_State;                                                //串口1接收状态
    
    extern vu16 Usart1_R_Count;                                                //当前接收数据的字节数         
    
    
    
    
    
    /*******************************************************************************
    
    * 函数名  : main
    
    * 描述    : 主函数,用户程序从main函数开始运行
    
    * 输入    : 无
    
    * 输出    : 无
    
    * 返回值  : int:返回值为一个16位整形数
    
    * 说明    : 无
    
    *******************************************************************************/
    
    int main(void)
    
    {
    
        u8 keyVal;
    
        SysTick_Init_Config();
    
            USART1_Init_Config(115200);//USART1初始化配置
    
        LED_GPIO_Config();
    
        Key_GPIO_Config();
    
        printf ("*===================================================*\n");
    
        printf ("*  *  Name: Sun STM32 mini Demo Code.    *************\n");
    
        printf ("*  * (C) Sunshine Silicon Corporation    *************\n");
    
        printf ("*  *  Website: http://www.sunsili.com    *************\n");
    
        printf ("*  *   E-Mail : fan@sunsili.com          *************\n");
    
        printf ("*===================================================*\n");
    
        printf ("* Sun STM32 mini Key Demo code .*\n");
    
       
    
            while (1)
    
            {
    
            keyVal = Key_Down_Scan();
    
                    if(Usart1_R_State == 1)//一帧数据接收完成
    
                    {
    
                            USART1_SendData((u8 *)Usart1_R_Buff, Usart1_R_Count);   //USART1发送数据缓冲区数据(发送刚接收完成的一帧数据)
    
                            Usart1_R_State =0;
    
                            Usart1_R_Count =0;
    
                    }
    
            if(keyVal)
    
            {
    
                printf("KeyVal:%d\r", keyVal);
    
                if(keyVal & 0x01) LED3_ON();            
    
                else if(keyVal & 0x02) LED4_ON();            
    
            }
    
            else LED_ALL_OFF();
    
            }
    
    }
    
    
    
    
    
    
    
    /******************* (C) COPYRIGHT SUNSHINE SILICON  **************************
    
    ********************        END OF FILE main.c        *******************/

  • 编译调试

     方法不再重复,经过前两节练习,大家应该是会了.
     连接串口打印,输出按键值。按下按键对应灯会亮。

查看原文,可以下载工程源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/253511.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB图像处理技巧

MATLAB图片处理------动态绘图 1. 动态绘图2. XXXXX 1. 动态绘图 主要用到四个函数&#xff0c;分别为getframe、frame2im、rgb2ind以及imwrite&#xff1a; 1.getframe&#xff1a;获取当前绘图窗口的图片作为影片帧&#xff1b; 2.frame2im&#xff1a;从单个影片帧 F 返回索…

数据仓库与数据挖掘c5-c7基础知识

chapter5 分类 内容 分类的基本概念 分类 数据对象 元组(x,y) X 属性集合 Y 类标签 任务 基于有标签的数据&#xff0c;学习一个分类模型&#xff0c;通过这个分类模型&#xff0c;可以把一组属性x映射到一个特定的类别y上 类别y 提前设定好的--如&#xff1a;学生…

安全密码(字符串)

#include <stdio.h> #include <stdbool.h> #include <string.h> bool is_secure_password(const char* password); int main() {int M;char password[51];// 读取输入中的密码数量 Mscanf("%d", &M);// 处理每个密码for (int i 0; i < M; …

Linux+Docker+Gitee+Jenkins自动化部署.NET Core服务

目录 一、安装Jenkins 1、跟新yum包 2、查询镜像 3、拉取镜像 4、创建Jenkins工作目录&#xff0c;并将容器内目录挂载到此目录上 5、启动Jenkins容器 二、Jenkins配置 1、Jenkins安装gitee码云插件 2、创建私人令牌 3、Jenkins添加全局凭据 4、系统配置 三、构建任…

5.5 Linux Apache服务

1、概念介绍 a. Web 服务简介 WEB服务器也称为WWW(WORLD WIDE WEB&#xff0c;万维网)服务器&#xff0c;主要功能是提供网上信息浏览服务。 常用web服务器&#xff1a;httpd&#xff08;apache&#xff09;、nginx、tomcat、IIS 客户端&#xff1a;IE、firefox、chrome b…

第15章 《乐趣》Page355~375 代码简化版

运行效果&#xff1a;全屏了 简化之后的代码如下&#xff1a; //main.cpp #include <iostream> #include <SDL2/SDL.h> #include "sdl_initiator.hpp" #include "sdl_error.hpp" #include "sdl_window.hpp" #include "sdl_sur…

2023年国家基地“楚慧杯”网络空间安全实践能力竞赛 Web方向 题解wp

前言&#xff1a;三小时的比赛&#xff0c;和强网同时结束还要当场交wp&#xff0c;汗流浃背&#xff0c;烧起来了啊啊啊啊~ eaaeval 目录扫出备份文件 源码如下 <?php class Flag{public $a;public $b;public function __construct(){$this->a admin;$this->b …

设计模式——策略模式

引言 策略模式是一种行为设计模式&#xff0c; 它能让你定义一系列算法&#xff0c; 并将每种算法分别放入独立的类中&#xff0c; 以使算法的对象能够相互替换。 问题 一天&#xff0c; 你打算为游客们创建一款导游程序。 该程序的核心功能是提供美观的地图&#xff0c; 以…

STM32F103RCT6开发板M3单片机教程06--定时器中断

前言 除非特别说明&#xff0c;本章节描述的模块应用于整个STM32F103xx微控制器系列&#xff0c;因为我们使用是STM32F103RCT6开发板是mini最小系统板。本教程使用是&#xff08;光明谷SUN_STM32mini开发板&#xff09; STM32F10X定时器(Timer)基础 首先了解一下是STM32F10X…

如何开发一个prompt?prompt的使用有哪些原则?

提示词使用原则 如何开发一个跟自己预期结果接近的提示词&#xff1f;有哪些基本原则&#xff1f; 提示词迭代开发 写提示词时&#xff0c;第一次尝试是值得的&#xff0c;反复完善提示&#xff0c;获得越来越接近你想要的结果 原文来源于B站吴恩达提示工程教学公开课。…

Jenkins----基于 CentOS 或 Docker 安装部署Jenkins并完成基础配置

查看原文 文章目录 基于 CentOS7 系统部署 Jenkins 环境基于 Docker 安装部署 Jenkins环境配置 Jenkins 中文模式配置用户名密码形式的 Jenkins 凭据配置 ssh 私钥形式的 Jenkins 凭据配置 Jenkins 执行任务的节点 基于 CentOS7 系统部署 Jenkins 环境 &#xff08;1&#xff…

数据库交付运维高级工程师-腾讯云TDSQL

数据库交付运维高级工程师-腾讯云TDSQL上机指导&#xff0c;付费指导&#xff0c;暂定99

并发编程中常见的设计模式

文章目录 一、 终止线程的设计模式1. 简介2. Tow-phase Termination&#xff08;两阶段终止模式&#xff09;—优雅的停止线程 二、避免共享的设计模式1. 简介2. Immutability模式—想破坏也破坏不了3. Copy-on-Write模式4. Thread-Specific Storage模式—没有共享就没有伤害 三…

[数据集][目标检测]人员持刀数据集VOC+YOLO格式6923张1类别重制版

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;6923 标注数量(xml文件个数)&#xff1a;6923 标注数量(txt文件个数)&#xff1a;6923 标注…

C# WPF上位机开发(函数运行时间分析)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 上位机除了基本功能和稳定性之外&#xff0c;还有一个要注意的就是运行效率的问题。如果我们想提高软件的运行效率&#xff0c;单位时间做更多的工…

【idea】解决sprintboot项目创建遇到的问题

目录 一、报错Plugin ‘org.springframework.boot:spring-boot-maven-plugin:‘ not found 二、报错java: 错误: 无效的源发行版&#xff1a;17 三、java: 无法访问org.springframework.web.bind.annotation.CrossOrigin 四、整合mybatis的时候&#xff0c;报java.lang.Ill…

Spring Boot+Mybatis设置sql日志打印

在全局配置文件添加以下内容&#xff1a;logging.level.com.demo.mapperdebug&#xff0c;com.demo.mapper&#xff1a;src下的mapper路径&#xff0c;debug&#xff1a;设置日志打印级别为debug&#xff0c;亦可设置为&#xff1a;ERROR、WARN、INFO application.properties …

安装android studio

记录一下安装android studio的过程&#xff1a; 1.首先安装android studio到某一文件夹后&#xff0c;在C盘用户目录下可以看到.android文件夹。C:\Users\22515\AppData\Local\Google目录下也会出现AndroidStudio2022.2文件夹。&#xff08;注意&#xff1a;用户名&#xff0c…

【精选】SpringMVC处理响应及注解开发

SpringMVC处理响应 配置视图解析器 SpringMVC默认情况下会在控制器执行完成后跳转到视图页面&#xff0c;视图解析器能找到相应的视图&#xff0c;之前的404异常就是由于没有配置视图解析器导致找不到视图。 在SpringMVC中提供了13个视图解析器&#xff0c;用于支持不同的视图…