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

news2024/11/27 6:23:11


原画图讲解


本教程使用是(光明谷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        *******************/

  • 编译调试

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

创投课程第五期 | 超越比特币:探索BTC生态的无限可能

协会邀请了来自水滴资本&#xff08;Waterdrip Capital&#xff09;的投资总监——Elaine&#xff0c;作为VC创投课程第5期的嘉宾&#xff0c;在北京时间12月17日(周日)晚上21:00 PM-22:00 PM&#xff0c;届时将与所有对Web3投资、创业心怀热忱的朋友们共同探讨《超越比特币&am…

TCP/IP详解——DNS 流量分析

文章目录 1. DNS 流量分析1.1 DNS 基本概念1.2 DNS 系统特性1.3 DNS 效率问题1.4 域名的组成1.5 域名解析系统1.5.1 域名解析过程 1.6 DNS 记录种类1.7 DNS 的报文格式1.7.1 DNS 报文中的基础结构部分1.7.2 DNS 查询报文中的问题部分1.7.3 DNS 响应报文中的资源记录部分1.7.4 示…

Unity中URP下的菲涅尔效果实现(个性化修改)

文章目录 前言一、我们修正一下上篇文章中&#xff0c;可能遗留的Bug1、N向量 变为 单位向量2、使颜色范围在合理区间 二、实现菲涅尔效果强弱可自定义调节三、修改菲涅尔效果颜色1、在属性面板定义颜色属性2、在常量缓冲区申明该参数3、在片元着色器中&#xff0c;用颜色和菲涅…

数据结构 AVL树概念以及实现插入的功能(含Java代码实现)

为啥要有avl树 avl树是在二叉搜索树下的一种进阶形式,是为了防止二叉搜索树在极端情况下产生的链表化的场景,从而在二叉搜索树的基础上,加上了某些条件来阻止这种极端情况的产生,但不是保证完全平衡,而是放开了一定的条件,使得这种情况不那么难以满足.(条件:左右子树的高度差的…

【Vulnhub 靶场】【IA: Keyring (1.0.1)】【中等】【20210730】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/ia-keyring-101,718/ 靶场下载&#xff1a;https://download.vulnhub.com/ia/keyring-v1.01.ova 靶场难度&#xff1a;中等 发布日期&#xff1a;2021年07月30日 文件大小&#xff1a;1.1 GB 靶场作者&#xf…

Day63力扣打卡

打卡记录 寻找最近的回文数&#xff08;模拟&#xff09; 链接 class Solution:def nearestPalindromic(self, n: str) -> str:m len(n)candidates [10 ** (m - 1) - 1, 10 ** m 1]selfPrefix int(n[:(m 1) // 2])for x in range(selfPrefix - 1, selfPrefix 2):y …

ArcMap自定义脚本工具箱迁移至ArcGIS pro

本文记录了将ArcMap10.7创建的自定义脚本工具箱&#xff08;.tbx&#xff09;迁移至ArcGIS pro的过程 ArcGIS Pro使用的是python版本与ArcMap不同&#xff0c;前者为python3&#xff0c;后者为python2。由于python3 和 python2 的部分语法不兼容&#xff0c;以及一些地理处理工…

性能测试之Artillery(示例及指标)

官方文档&#xff1a;https://www.artillery.io/docs/get-started/first-test PS:文档挺详细&#xff0c;教程比较全 示例 config:http:extendedMetrics: truetarget: http://127.0.0.1:8005phases:- duration: 10 # 持续时间arrivalRate: 10 # 每秒创建10个用户rampTo: 100 …

【漏洞复现】CVE-2023-6848 kodbox远程命令执行

漏洞描述 kodbox 是一个网络文件管理器。它也是一个网页代码编辑器,允许您直接在网页浏览器中开发网站。您可以在基于 Linux、Windows 或 Mac 的平台上在线或本地运行 kodbox。唯一的要求是要有 PHP 5及以上。 kalcaddle kodbox 中发现漏洞,最高版本为 1.48。它已被宣布为关…

LV.13 D5 uboot概述及SD卡启动盘制作 学习笔记

一、uboot概述 1.1 开发板启动过程 开发板上电后首先运行SOC内部iROM中固化的代码(BL0)&#xff0c;这段代码先对基本的软硬件环境(时钟等...)进行初始化&#xff0c;然后再检测拨码开关位置获取启动方式&#xff0c;然后再将对应存储器中的uboot搬移到内存&#xff0c;然后跳…

目标跟踪 MOT数据集和可视化

目录 MOT15数据集格式简介 gt可视化 本人修改的GT可视化代码&#xff1a; MOT15数据集格式简介 以下内容转自&#xff1a;【目标跟踪】MOT数据集GroundTruth可视化-腾讯云开发者社区-腾讯云 MOT15数据集下载&#xff1a;https://pan.baidu.com/s/1foGrBXvsanW8BI4eybqfWg?…

机器学习算法---时间序列

类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统计学检验箱…

vue3中ref及reactive的说明

目录 1.响应式说明 2.vue3的ref及reactive的使用 3.reactive响应式失效问题 4.总结 1.响应式说明 vue的响应式是vue框架中的核心概念之一&#xff0c;它是指当数据发生变化时&#xff0c;vue能够自动更新视图。vue2的响应式是基于Object.defineProperty进行实现的。 当你把…

安全密码(字符串)

#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; …

智慧校园2.0物联网管理平台建设方案:PPT全文22页,附下载

关键词&#xff1a;物联网解决方案&#xff0c;智慧校园解决方案&#xff0c;物联网平台建设方案&#xff0c;物联网应用技术 一、智慧校园2.0物联网管理平台建设背景 1、教育现代化和强国建设的需要&#xff1a;近年来&#xff0c;国家为了加快推进教育现代化、教育强国建设…

OpenSergo Dubbo 微服务治理最佳实践

*作者&#xff1a;何家欢&#xff0c;阿里云 MSE 研发工程师 Why 微服务治理&#xff1f; 现代的微服务架构里&#xff0c;我们通过将系统分解成一系列的服务并通过远程过程调用联接在一起&#xff0c;在带来一些优势的同时也为我们带来了一些挑战。 如上图所示&#xff0c;可…

Eclipse 自动生成注解,如果是IDEA可以参考编译器自带模版进行修改

IDEA添加自动注解 左上角选择 File -> Settings -> Editor -> File and Code Templates&#xff1b; 1、添加class文件自动注解&#xff1a; ​/*** <b>Function: </b> todo* program: ${NAME}* Package: ${PACKAGE_NAME}* author: Jerry* date: ${YEA…

Apache Flume(5):多个agent模型

可以将多个Flume agent 程序连接在一起&#xff0c;其中一个agent的sink将数据发送到另一个agent的source。Avro文件格式是使用Flume通过网络发送数据的标准方法。 从多个Web服务器收集日志&#xff0c;发送到一个或多个集中处理的agent&#xff0c;之后再发往日志存储中心&…

Maui blazor与sqlite开发一个增删改查

在android端增删改不能运行。也看不出来是什么&#xff0c;但运行到windows可以运行。 引入sqlite-net-pcl 开发Model using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.T…

深入探讨线程池及其关键参数

目录 引言 1. 线程池概述 2. 线程池的工作原理 3. 线程池的关键参数 4. 线程池的最佳实践 5. 实际应用场景 结论 引言 在并发编程领域&#xff0c;线程池是一种重要的工具&#xff0c;用于管理和重用线程&#xff0c;提高程序的性能和效率。线程池可以有效地管理线程的生…