蓝桥杯电子赛_零基础利用按键实现不同数字的显现

目录

一、前提

按键的原理图

二、代码配置

bsp_key.c文件

疑问

main.c文件

 main.c文件的详细讲解

功能实现

注意事项


一、前提

按键这一板块主要是以记忆为主,我直接给大家讲解代码去实现我要配置的功能。本次我要做的项目是板子上的按键有S4~S19,我希望任意一个按键可以显示对应的两位数,按下两个不同的按键可以一前一后各显示出两位数字,也就是生成四位数字,再按下另外一个按键实现清零的功能。

按键的原理图

这是板子上按键的原理图,如果要切换独立按键和矩阵键盘,那么我们需要将板子上J5部分的小插口的东西插到对应的位置上去,本项目是在KBD上,12是KBD矩阵键盘,23是BTN独立按键,如下图:

那么如何扫描呢?答:先锁定行,再锁定列,举个例子:假如说,我现在想要扫描S4这个按键,我们先要锁定从左往右数第一列连接对应的引脚是P44,S4对应的行是P33

二、代码配置

我们这里只用到Timer、init、seg、key,led,本文章没写的代码可以去我这个蓝桥杯第一个系列观看,里面有很详细的代码简介

bsp_key.c文件

#include "bsp_key.h"//函数名:按键码值读取函数
//入口参数:无
//返回值:按键的码值
//函数功能:返回按键码
unsigned char Key_Read(void)
{unsigned int Key_NEW;unsigned char Key_Value;//返回值P44 = 0;P42 = 1;P35 = 1;P34 = 1;//第一列扫描Key_NEW = P3 & 0X0F; //P3 = 0000 1000---P37~P30,高位无效,只看P33~P30P44 = 1;P42 =0;P35 = 1;P34 = 1;//第二列扫描Key_NEW = (Key_NEW << 4) | (P3 & 0X0F); //将原来的数值挪到次4位,本次数值放到最低4位,占用了8位P44 = 1;P42 =1;P35 = 0;P34 = 1;//第三列扫描Key_NEW = (Key_NEW << 4) | (P3 & 0X0F); //将原来的数值挪到次次4位,本次数值放到最低4位,占用了12位P44 = 1;P42 =1;P35 = 1;P34 = 0;//第三列扫描Key_NEW = (Key_NEW << 4) | (P3 & 0X0F); //将原来的数值挪到次次次4位,本次数值放到最低4位,占用了16位switch(~Key_NEW)//Key_Value的数值对应按键的编号{case 0X8000:Key_Value = 4;break;case 0X4000:Key_Value = 5;break;case 0X2000:Key_Value = 6;break;case 0X1000:Key_Value = 7;break;case 0X0800:Key_Value = 8;break;case 0X0400:Key_Value = 9;break;case 0X0200:Key_Value = 10;break;case 0X0100:Key_Value = 11;break;case 0X0080:Key_Value = 12;break;case 0X0040:Key_Value = 13;break;case 0X0020:Key_Value = 14;break;case 0X0010:Key_Value = 15;break;case 0X0008:Key_Value = 16;break;case 0X0004:Key_Value = 17;break;case 0X0002:Key_Value = 18;break;case 0X0001:Key_Value = 19;break;default :Key_Value = 0;}return Key_Value;}

疑问

在中switch中,为什么进行Key_New的取反?

答:一般来说,按键配置的时候,我们配置的是上拉输入,在没按按键的时候,对应的是高电平,按下去,是低电平,那么我们通过取反,就是按下去成为高电平1,利用哪个地方是1,进行选择对应的case

main.c文件

#include "bsp_init.h"
#include "bsp_seg.h"
#include "Timer0.h"
#include "bsp_key.h"
#include "bsp_key.h"
#include "STDIO.H"/* 函数声明 */
void	Key_Proc(void);//按键处理
void	Seg_Proc(void);//显示处理/* 全局变量 */unsigned char seg_buf[8];//放置字符串转换后的段码到数组
unsigned char seg_string[10];//放置字符串
unsigned char pos = 0;//中断显示专用unsigned char Key_Value;//读取按键的数值存储变量
unsigned char Key_Down,Key_Old;unsigned char num_buffer[2] = {0, 0}; // 存储2个按键编号
unsigned char num_count = 0; // 当前存储的数字个数unsigned char Seg_Show_Num;//准备显示出来的数值
void main()
{Cls_Peripheral();Timer0Init();		//1毫秒@12.000MHzEA = 1;while(1){Key_Proc();//按键处理Seg_Proc();//显示处理}}/* Timer0 interrupt routine */
void tm0_isr() interrupt 1 
{Seg_Disp( seg_buf, pos );if(++pos ==8) pos = 0;
}
/* Key_Proc */
void	Key_Proc(void)//按键处理,底层数据变更
{Key_Value = Key_Read();//读取按键按下的编号Key_Down = Key_Value & (Key_Old ^ Key_Value);//^异或(0000^0101)= 0101 0101 & 0101 = //0101 如果按键发生了下降沿的变化,输出结果和本次按键数值相同//^异或(0101^0101)= 0000 0101 & 0000 = //0000 如果按键发生了下降沿的变化,输出结果和本次按键数值相同Key_Old = Key_Value;if(Key_Down)//如果捕捉到下降沿跳变{if (num_count < 2) // 如果存储的按键个数小于2{num_buffer[num_count++] = Key_Down; // 存储按键编号}else // 如果已经存储了两个按键编号{// 清零操作num_count = 0; // 清空按键个数     }}	
}/* Seg_Proc */
void	Seg_Proc(void)//显示处理,显示信息生成
{if (num_count == 1) // 如果只存储了一个按键编号{// 显示第一个按键编号的两位数字sprintf(seg_string, "    %02d", (unsigned int)num_buffer[0]);}else if (num_count == 2) // 如果存储了两个按键编号{// 显示两个按键编号的四位数字sprintf(seg_string, "    %02d%02d", (unsigned int)num_buffer[0], (unsigned int)num_buffer[1]);}else // 如果没有存储任何按键编号{// 显示全0sprintf(seg_string, "    0000");}Seg_Tran( seg_string,seg_buf);}

 main.c文件的详细讲解

假如说,我现在按下去了S4,那么检测到了S4处有下降沿,并且将这个数值给一个变量Key_Val,然后这个变量就给到了Seg_Show_Num,此刻还是一个二进制数,无法显示到数码管上,然后将这个Seg_Show_Num通过sprintf转化成字符串,字符串在Seg_Disp函数下,将段码转化成能看懂的数字,最后利用定时器中断每1ms进行刷新数码管上的东西

  1. 显示逻辑调整:                                                                                                                      在Seg_Proc函数中:

    • 如果num_count为0,显示全0。

    • 如果num_count == 2,显示两个按键编号的四位数字(如0405)。

    • 如果num_count == 1,只显示第一个按键编号的两位数字(如04)。

  2. 按键逻辑调整

    Key_Proc函数中:
    • 如果num_count == 2,按下任意按键清零。

    • 如果num_count < 2,存储按键编号。

  3. 数码管显示位数调整

    数码管的动态扫描范围为8位,显示内容通过sprintf格式化为8位数码管的显示格式。
功能实现
  • 按下第一个按键

    • 显示该按键对应的两位数字(如04)。

  • 按下第二个按键

    • 显示两个按键对应的四位数字(如0405)。

  • 按下任意第三个按键

    • 清零显示内容,显示0000

注意事项

确保按键编号S4S19与实际硬件的按键编号一致。

如果按键编号不是从419的连续数字,需要根据实际硬件调整按键编号的判断逻辑。

显示内容前面有4个空格,确保显示内容在8位数码管的中间位置。如果需要调整显示位置,可以修改sprintf中的空格数量。

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

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

相关文章

Python常用高阶函数全面解析:通俗易懂的指南

Python常用高阶函数全面解析&#xff1a;通俗易懂的指南 一、什么是高阶函数&#xff1f; 高阶函数(Higher-order Function)是指能够接受其他函数作为参数&#xff0c;或者将函数作为返回值的函数。在Python中&#xff0c;函数是一等公民&#xff0c;可以像普通变量一样传递和…

Flume之选择器:复制和多路复用(比喻化理解

Flume 的选择器决定了Source 如何将数据分发到多个 Channel。这就像 “快递员如何分配包裹到不同的运输通道”&#xff0c;有两种策略&#xff1a;复制和多路复用。 一、复制&#xff08;Replicating Selector&#xff09;&#xff1a;每个 Channel 都送一份 核心逻辑 将同一…

yolov5 安卓运行

参考博客&#xff1a; 通过Android Studio 将yolov5部署到手机端(新手最新适用版)_怎么将yolo部署手机-CSDN博客 总体跟随参考博客走是没问题&#xff0c;有些细节需要注意&#xff1a; 1 jdk 版本选择&#xff0c;jdk需要17&#xff0c;新版的Android Studio 选择jdk版本方式…

day021-定时任务

文章目录 1. cron1.1 检查是否安装1.2 检查是否开机自启动1.3 配置文件与相关命令1.4 配置文件格式 2. 案例2.1 同步时间2.2 定时备份/etc和/var/log目录2.3 定时巡检脚本 3. 练习三剑客过滤3.1 去重统计ip数量3.2 去重统计第7列 用户访问的url的数量3.3 去重统计第9列 状态码与…

关于(stream)流

Stream 是 Java 8 引入的一个强大的功能&#xff0c;用于处理集合&#xff08;Collection&#xff09;或数组中的数据。它提供了一种声明式的编程方式&#xff0c;可以极大地简化对数据的操作&#xff0c;例如过滤、排序、映射和聚合等。 1. 什么是 Stream 流&#xff1f; 定义…

结课作业自选01. 内核空间 MPU6050 体感鼠标驱动程序(二)(完整实现流程)

目录 一. 题目要求-内核空间 MPU6050 体感鼠标驱动程序 二. 伪代码及程序运行流程 三. 主要函数详解&#xff08;根据代码流程进行详解&#xff09; 3.1 module_i2c_driver宏&#xff08;对应“1”&#xff09; 3.2 mpu_of_match设备树匹配表&#xff08;对应“2”&#x…

5G 核心网切换机制全解析:XN、N2 与移动性注册对比

摘要 本文深入探讨了 5G 核心网中的三种关键切换方式:基于 XN 接口的切换、基于 N2 接口的切换以及移动性注册更新机制。通过对比分析它们的原理、应用场景和技术差异,帮助读者全面理解 5G 网络中用户移动性管理的核心技术。 1. 引言 随着 5G 技术的广泛应用,用户对网络连…

用深度学习提升DOM解析——自动提取页面关键区块

一、时间轴&#xff1a;一次“抓不到重点”的二手车数据爬虫事故 2025/03/18 09:00 产品经理希望抓取懂车帝平台上“北京地区二手车报价”作为竞品监测数据源。我们初步使用传统XPath方案&#xff0c;试图提取车型、年限、里程、价格等数据。2025/03/18 10:00 初版脚本运行失败…

React与Vue的内置指令对比

React 与 Vue 不同&#xff0c;它没有内置的模板指令系统。React 采用了 JavaScript 优先 的声明式方式&#xff0c;使用 JSX 语法将 HTML 和 JavaScript 结合在一起。因此&#xff0c;React 中没有类似 Vue 的 v-if、v-for、v-bind 等内置指令。 React 中的替代方案 条件渲染…

Spring声明式事务源码全链路剖析与设计模式深度解读

Spring声明式事务源码全链路剖析与设计模式深度解读 作者&#xff1a;AI 日期&#xff1a;2025-05-22 一、前言 Spring事务是企业级开发的基石&#xff0c;但“为什么有时事务失效&#xff1f;”、“不同传播行为背后发生了什么&#xff1f;”、“Spring事务源码到底如何实现&…

云原生安全基础:深入探讨容器化环境中的权限隔离与加固策略

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 在云原生环境中&#xff0c;容器化技术&#xff08;如 Docker 和 Kubernetes&#xff09;的广泛应用带来了灵活性与效率&#xff0c;但也引入了新的安全挑…

如何在 ONLYOFFICE 演示文稿中调整段落首行缩进

在制作演示文稿时&#xff0c;保持内容的一致性与可读性至关重要&#xff0c;而段落首行缩进作为格式设置的关键环节&#xff0c;直接影响着整体呈现效果。在本文中&#xff0c;我们将介绍如何通过创建 ONLYOFFICE 宏&#xff0c;快速设置演示文稿中所有段落的首行缩进。 关于 …

[Asp.Net]GridView、Repeater 导出Excel长数字显示成科学计数

类似身份证纯数字的格式时 &#xff0c;excel默认是数字格式 变成了科学计数法 &#xff0c; GridView:RowDataBound 添加e.Row.Cells[2].Attributes.Add(“style”, “vnd.ms-excel.numberformat:;”); protected void GridView1_RowDataBound(object sender, GridViewRowE…

Ntfs!NtfsReadBootSector函数分析之nt!CcGetVacbMiss中得到一个nt!_VACB结构

第一部分&#xff1a; 1: kd> g Breakpoint 3 hit nt!CcGetVacbMiss: 80a1a19e 6a30 push 30h 1: kd> kc # 00 nt!CcGetVacbMiss 01 nt!CcGetVirtualAddress 02 nt!CcMapData 03 Ntfs!NtfsMapStream 04 Ntfs!NtfsReadBootSector Ntfs…

Linux10正式版发布,拥抱AI了!

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验 Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、MySQL、PG、高斯…

关于 SSE(Server-Sent Events)过程的简要解剖

Js前端&#xff1a;发送普通请求 fetch(...) .then(()>{}) .catch(()>{})Java后端&#xff1a;接收请求后调用请求处理函数&#xff0c;函数返回一个emiiter对象 public SseEmitter handleRequest(...) {// 创建一个 SseEmitter 对象&#xff0c;用于发送 SSE 事件SseE…

PyTorch 中unsqueeze(-1)用法

unsqueeze(-1) 是 PyTorch 中的一个张量操作&#xff0c;用于‌在指定维度上增加一个长度为1的维度‌&#xff08;即扩展维度&#xff09;。具体解析如下&#xff1a; 功能说明 ‌作用位置‌ -1 表示在张量的‌最后一个维度‌后添加新维度。 &#xff08;等价于 dimlen(tensor.…

RTC技术

什么是RTC RTC&#xff08;Real time communication&#xff09;实时通信&#xff0c;是实时音视频的一个简称&#xff0c;我们常说的RTC技术一般指的是WebRTC技术&#xff0c;已经被 W3C 和 IETF 发布为正式标准。由于几乎所有主流浏览器都支持 WebRTC 标准 API &#xff0c;…

vue+cesium示例:3Dtiles三维模型高度调整(附源码下载)

接到一位知识星友的邀请&#xff0c;实现他需要3Dtiles三维模型的简单高度调整需求&#xff0c;适合学习Cesium与前端框架结合开发3D可视化项目。 demo源码运行环境以及配置 运行环境&#xff1a;依赖Node安装环境&#xff0c;demo本地Node版本:推荐v18。 运行工具&#xff1a;…

详解3DGS

4 可微分的3D高斯 splatting 核心目标与表示选择 我们的目标是从无法线的稀疏SfM点出发&#xff0c;优化出一种能够实现高质量新视角合成的场景表示。为此&#xff0c;我们选择3D高斯作为基本图元&#xff0c;它兼具可微分的体表示特性和非结构化的显式表示优势&#xff0c;既…