10天学会嵌入式技术之51单片机-day-3

第九章  独立按键

按键的作用相当于一个开关,按下时接通(或断开),松开后断开(或接通)。实物图、原理图、封装

9.2 需求描述

通过 SW1、SW2、SW3、SW4 四个独立按键分别控制 LED1、LED2、LED3、LED4
的亮灭,具体要求是,按一下(按下并松开)SW,LED 点亮,再按一下 SW,LED 熄灭。

9.3 硬件设计


9.3.1 实现思路

为实现上述需求,需要设法令单片机感知到按键被按下,也就是说在按键被按下时,
需要向单片机发送一个信号,当单片机收到该信号后,再执行控制 LED 的逻辑即可。
由于 51 单片机的 GPIO 引脚的默认均为高电平,因此只需将按键的一侧接入单片机的
某个 GPIO 引脚,另一侧接地。这样一来,当按键按下时,引脚直接接地,就相当于向单
片机发送了一个低电平信号。

9.3.2 硬件原理图

9.4 软件设计

9.4.1 初步实现

按照原理图,SW1 按下时,P4.2 引脚会被拉低;SW2 按下时,P4.3 引脚会被拉低;
SW3 被按下时,P3.2 引脚会被拉低;SW4 按下时,P3.3 引脚会被拉低。
因此只需检测上述引脚是否变为低电平即可,若检测到变为低电平,就执行控制 LED
的逻辑。需要注意的是,按键的检测需要持续进行,所以需要不停的检查上述引脚是否变
为低电平。

9.4.2 按键单次触发

当前代码的逻辑是,只要按键处在按下的状态,就触发控制 LED 的逻辑。为实现单次
触发,可以在按键按下后,等待按键抬起,并在抬起的一刻,执行控制 LED 的逻辑。

9.4.3 按键消抖

由于按键的抖动,单片机引脚的信号切换并不像我们想象的那样干脆,实际情况如下
图所示

9.4.4 规范代码

按照前文的编码规范,我们将检测按键的代码单独抽取到 Int 层,具体代码如下。

(1)Int_Key.h
 

#ifndef __INT_KEY_H__
#define __INT_KEY_H__
#include <STC89C5xRC.H>
#include "Util.h"
/**
* @brief 检测 SW1 按键是否按下
*
* @return bit 是或否
*/
bit Int_Key_IsSW1Pressed();
/**
* @brief 检测 SW2 按键是否按下
*
* @return bit 是或否
*/
bit Int_Key_IsSW2Pressed();
/**
* @brief 检测 SW3 按键是否按下
*
* @return bit 是或否
*/
bit Int_Key_IsSW3Pressed();
/**
* @brief 检测 SW4 按键是否按下
*
* @return bit 是或否
*/
bit Int_Key_IsSW4Pressed();
#endif /* __INT_KEY_H__ */

(2)Int_Key.c

#include "Int_Key.h"
#include <STC89C5xRC.H>
#include "Com_Util.h"
#define SW1 P42
#define SW2 P43
#define SW3 P32
#define SW4 P33bit Int_Key_IsSW1Pressed()
{if (SW1 == 0) {Com_Util_Delay1ms(10);if (SW1 == 0) {while (SW1 == 0);return 1;}}return 0;
}bit Int_Key_IsSW2Pressed()
{if (SW2 == 0) {Com_Util_Delay1ms(10);if (SW2 == 0) {while (SW2 == 0);return 1;}}return 0;
}bit Int_Key_IsSW3Pressed()
{if (SW3 == 0) {Com_Util_Delay1ms(10);if (SW3 == 0) {while (SW3 == 0);return 1;}}return 0;
}bit Int_Key_IsSW4Pressed()
{if (SW4 == 0) {Com_Util_Delay1ms(10);if (SW4 == 0) {while (SW4 == 0);return 1;}}return 0;
}

(3)Main.c

#include <STC89C5xRC.H>
#include "Int_Key.h"
#define LED1 P00
#define LED2 P01
#define LED3 P02
#define LED4 P03
void main()
{while (1) {if (Int_Key_IsSW1Pressed()) {LED1 = ~LED1;}if (Int_Key_IsSW2Pressed()) {LED2 = ~LED2;}if (Int_Key_IsSW3Pressed()) {LED3 = ~LED3;}if (Int_Key_IsSW4Pressed()) {LED4 = ~LED4;}}
}

 第 10 章 矩阵按键

按下按键矩阵中的 SW5 到 SW20 按键后,数码管显示对应的按键编号。

10.2 硬件设计

10.2.1 实现思路

由于按键矩阵中共有 4x4=16 个按键,如果每个按键都接入一个 GPIO 引脚,势必会造
成引脚的浪费,为了节省引脚,我们同样可以借用动态扫描的思想,具体逻辑如下。

10.2.2 51 单片机引脚内部结构

在上面的演示中,我们应注意的一个问题是:当高电平引脚和低电平引脚短接时,结
果是高电平引脚被拉低,而不是低电平引脚被拉高。这实际上是由 51 单片机引脚的内部结
构决定的,其简化结构如下图所示。

上图的工作原理是:当端口锁存器为 0 时,mos 管导通,此时引脚直接接地,输出低
电平;当端口锁存器为 1 时,mos 管关闭,引脚靠内部的弱上拉电阻(弱的意思是电流很
微弱,可进一步理解为上拉电阻的阻值很大)拉置高电平。
根据上图,可以得出结论,当引脚输出高电平时,很容易被被外部装置拉低(因为上
拉电阻分压多),而当引脚输出低电平时,却很难被拉高(因为引脚接地)。这就是常说的
弱上拉+强下拉模式。
所以在本节矩阵按键的例子中,当我们按下按键短接高低引脚,最终结果是高电平引
脚被拉低。

10.2.3 硬件原理图

10.3 软件设计

(1)Int_DigitalTube.h 和 Int_DigitalTube.c

数码管项目中的 Int_DigitalTube.h 和 Int_DigitalTube.c 复制到当前项目的 Int 目录。

(2)Int_MatrixKey.h

在项目的 Int 目录下创建 Int_MatrixKey.h,写入以下内容。

#ifndef __INT_KEYMATRIX_H__
#define __INT_KEYMATRIX_H__
#include"Com_Util.h"u8 Int_KetMatrix_CheckSW();#endif /* __INT_KEYMATRIX_H__ */

(3)Int_MatrixKey.c

在项目的 Int 目录下创建 Int_MatrixKey.c,写入以下内容。

#include "Int_KeyMatrix.h"
#include<STC89C5xRC.H>u8 Int_KetMatrix_CheckSW()
{u8 i,j;u8 lines[4]={0xFE,0xFD,0xFB,0xF7};u8 columns[4]={0x10,0x20,0x40,0x80};for (i = 0; i < 4; i++){  P2=lines[i];for ( j = 0; j< 4; j++){if((P2 & columns[j])==0){Com_Util_Delay1ms(10);if((P2 & columns[j])==0){while((P2 & columns[j])==0);return j+5+i*4;}}}}return 0;
}  

(4)main.c

#include"Int_KeyMatrix.h"
#include"Int_DigitalTube.h"void main()
{u8 key;Int_DigitalTube_Init();while(1){key=Int_KetMatrix_CheckSW();  //检测按键if(key){Int_DigitalTube_DisplayNum(key);  }Int_DigitalTube_Refresh();}
}

 第 11 章 蜂鸣器

11.1 蜂鸣器简介

蜂鸣器是一种能够发出声音的电子元器件,常用于报警、提示和音频信号输出等场景。
其内部结构如下图所示。
当电流通过线圈时会产生电磁场,电磁场与永磁体相互作用,从而使金属膜产生震动
而发声。为使金属膜持续震动,蜂鸣器需要使用震荡电路进行驱动。有些蜂鸣器元件内部
自带震荡驱动电路,这种蜂鸣器叫做有源蜂鸣器(Active Buzzer,自激式蜂鸣器);而有些
则不带震荡驱动电路,这种蜂鸣器叫做无源蜂鸣器(Passive Buzzer,它激式蜂鸣器)。
更多信息可参考如下内容。

(1)有源蜂鸣器

(2)无源蜂鸣器

11.2 需求描述

为按键矩阵增加按键提示音,要求按键按下后,蜂鸣器响 0.1s。

11.3 硬件设计

11.3.1 硬件原理图

本课程使用的是无源蜂鸣器,所以需要从外部输入一定频率的方波,方波的频率就是
蜂鸣器发声的频率,这里我们使用 500Hz 的方波即可。

11.4 软件设计

(1)Int_DigitalTube.h 和 Int_DigitalTube.c

将数码管项目中的 Int_DigitalTube.h 和 Int_DigitalTube.c 复制到当前项目的 Int 目录。

(2)Int_MatrixKey.h 和 Int_MatrixKey.c

将按键矩阵项目中的 Int_MatrixKey.h 和 Int_MatrixKey.c 复制到当前项目的 Int 目录。

(3)Int_Buzzer.h

在 Int 目录下创建 Int_Buzzer.h,写入以下内容。

#ifndef __INT_BUZZER_H__
#define __INT_BUZZER_H__
#include <STC89C5xRC.H>
#define BUZZ P46
/**
* @brief 蜂鸣器响 0.1s
*
*/
void Int_Buzzer_Buzz();
#endif /* __INT_BUZZER_H__ */

(4)Int_Buzzer.c

在 Int 目录下创建 Int_Buzzer.c,写入以下内容。

#include "Int_Buzzer.h"
#include "Util.h"
void Int_Buzzer_Buzz()
{unsigned char counter = 100;while (counter) {BUZZ = ~BUZZ;Delay1ms(1);--counter;}
}

(5)Main.c

#include "Int_DigitalTube.h"
#include "Int_MatrixKey.h"
#include "Int_Buzzer.h"
int main()
{u8 key_pressed = 0;Int_DigitalTube_Init();Int_DigitalTube_DisplayNum(key_pressed);while (1) {key_pressed = Int_MatrixKey_CheckKey();if (key_pressed) {Int_DigitalTube_DisplayNum(key_pressed);Int_Buzzer_Buzz(); //按键提示音}Int_DigitalTube_Refresh();}
}

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

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

相关文章

vite+vue2+elementui构建之 package.json

webpack版本太低&#xff0c;构建依赖太多&#xff0c;头大。 各种查阅资料&#xff0c;弄了一份直通构建vite构建elementUi核心文件&#xff0c; 构建基于开源若依vue2vue3版本改造&#xff0c;感谢开源&#xff0c;感谢若依。 vitevue2elementui构建之 vite.config.js-CSD…

提升变电站运维效率:安科瑞无线测温系统创新应用

一、引言 变电站作为电力系统的关键枢纽&#xff0c;承担着变换电压、分配电能以及控制电力流向等重要任务。在变电站的运行过程中&#xff0c;电气设备的接点温度监测至关重要。过热问题可能由多种因素引发&#xff0c;如电阻过大、接头质量欠佳、衔接不紧密、物理老化等&…

DMA的三种传输功能

①内存到内存 #include "dma.h" #include "stdio.h"#define BUF_SIZE 16uint32_t src_buf[BUF_SIZE] {0x00000000,0x11111111,0x22222222,0x33333333,0x44444444,0x55555555,0x66666666,0x77777777,0x88888888,0x99999999,0xAAAAAAAA,0xBBBBBBBB,0xCCCCCCC…

【MySQL】MySQL 表的增删改查(CRUD)—— 下篇(内含聚合查询、group by和having子句、联合查询、插入查询结果)

目录 1. 插入查询结果 2 聚合查询 &#xff08;行与行之间运算&#xff09; count 计算查询结果的行数 sum 求和 avg 求平均值 max 最大值 min 最小值 【小结】 3. group by 子句 分组 where 条件 having 条件 4. 联合查询&#xff08;多表查询&#xff09; 内连接…

“思考更长时间”而非“模型更大”是提升模型在复杂软件工程任务中表现的有效途径 | 学术研究系列

作者&#xff1a;明巍/临城/水德 还在为部署动辄数百 GB 显存的庞大模型而烦恼吗&#xff1f;还在担心私有代码库的安全和成本问题吗&#xff1f;通义灵码团队最新研究《Thinking Longer, Not Larger: Enhancing Software Engineering Agents via Scaling Test-Time Compute》…

电脑屏幕录制软件Captura源码编译(Win10,VS2022)

屏幕录像的意义&#xff1a; 教育教学方面 制作教学资源&#xff1a;教师可以通过录制屏幕来制作教学视频&#xff0c;演示软件操作、讲解复杂的知识点等。学生可以随时观看这些视频&#xff0c;便于复习和巩固知识&#xff0c;尤其对于一些抽象的概念或难以在课堂上一次性掌握…

记一次调用大华抓拍SDK并发优化

目录 一、问题分析 二、解决思路 三、贴代码 四、总结 一、问题分析 按惯例上问题&#xff1a; 设备告警采用高电平持续模式&#xff1a;一次开&#xff0c;不主动关就一直处于告警状态。 并发时多个请求下发 setDVRAlarmOutConfig&#xff0c;导致状态混乱。 “开 -&g…

Python图像变清晰与锐化,调整对比度,高斯滤波除躁,卷积锐化,中值滤波钝化,神经网络变清晰

本次使用图片来源于百度 import cv2 import time import numpy as np import pywtfrom PIL import Image, ImageEnhance#-i https://pypi.mirrors.ustc.edu.cn/simpledef super_resolution(input_path, output_path, model_path, scale4):# 初始化超分辨率模型sr cv2.dnn_su…

12个HPC教程汇总!从入门到实战,覆盖分子模拟/材料计算/生物信息分析等多个领域

在科学研究、工程仿真、人工智能和大数据分析等领域&#xff0c;高性能计算 (High Performance Computing, HPC) 正扮演着越来越重要的角色。它通过并行处理、大规模计算资源的整合&#xff0c;极大提升了计算效率&#xff0c;使原本耗时数日的任务能够在数小时内完成。 随着计…

使用Autocannon.js进行HTTP压测

目录 一、为什么选择Autocannon&#xff1f; 二、五分钟快速上手 1. 环境准备 2. 发起首个压测 3. 解读测试报告 三、高阶场景实战 场景1&#xff1a;POST请求压测 场景2&#xff1a;阶梯式压力测试 场景3&#xff1a;编程式集成测试 四、结果深度分析指南 1. 延迟分…

pnpm install报错:此系统上禁止运行脚本

依赖安装 报错信息&#xff1a; pnpm : 无法加载文件 C:\Users\XXX\AppData\Roaming\npm\pnpm.ps1&#xff0c;因为在此系统上禁止运行脚本。有关详细信息&#xff0c;请参阅 https:/go.microsoft.com/fwlink/?LinkID135170 中的 about_Execution_Policies。 所在位置 行:1 …

第9章 多模态大语言模型

​​​​​​第1章 对大型语言模型的介绍第2章 分词和嵌入第3章 解析大型语言模型的内部机制第4章 文本分类第5章 文本聚类与主题建模第6章 提示工程第7章 高级文本生成技术与工具第8章 语义搜索与检索增强生成第10章 构建文本嵌入模型第11章 面向分类任务的表示模型微调第12章…

Python 绘图代码解析:用 Turtle 和 Colorsys 打造绚丽图案

注:本文为作者原创文章,未经许可禁止转载。 Python 绘图代码解析:用 Turtle 和 Colorsys 打造绚丽图案 在 Python 的世界里,有许多有趣的库可以用来创造精美的图形。今天,我们就来详细剖析一段使用turtle库和colorsys库的代码,看看它是如何绘制出独特图案的。 一、库的导…

RTMP 入门指南

1. RTMP 基础概念​​ ​​核心角色​​&#xff1a; ​​推流端&#xff08;Publisher&#xff09;​​&#xff1a;将音视频数据推送到服务器的设备&#xff08;如OBS、手机APP&#xff09;。​​服务器&#xff08;RTMP Server&#xff09;​​&#xff1a;接收推流并分发给…

Java Stream流 常用方法

Map 修改 用于修改集合里的值 public void findData(){ArrayList<String> list new ArrayList<>();list.add("张三");list.add("李四");List<String> collect list.stream().map(s -> s "a").collect(Collectors.toLi…

巧记英语四级单词 Unit5-上【晓艳老师版】

count 数&#xff0c; counter n.计算器&#xff0c;柜台 a.相反的 数数的东西就是计算器&#xff0c;在哪数&#xff0c;在柜台里面数&#xff1b;你和售货员的关系就是相反的(一个买货&#xff0c;一个卖货account n.账户&#xff0c;账号 一再的数accountant n.会计 一再的…

Git多人协作与企业级开发模型

目录 1.多人协作一 2.多人协作二 3.远程分⽀删除后&#xff0c;本地gitbranch-a依然能看到的解决办法 4.企业级开发模型 4.1.Git的重要性 4.2.系统开发环境 4.3.Git 分⽀设计规范 1.多人协作一 ⽬前&#xff0c;我们所完成的⼯作如下&#xff1a; 基本完成Git的所有本…

大众点评 mtgsig1.2 分析 mtgsig

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向过程 部分代码 params[yodaRead…

(三) Trae 调试C++ 基本概念

调试C基本概念 一、调试基础概念1.1 调试信息格式1.2 DWARF格式和PDB格式生成(图解)1.3.典型工具链和调试信息 二、各工具链深度解析1. Clang 与 G 的 DWARF 差异 三 调试工具3.1 调试工具3.2 调试插件(Trae) 一、调试基础概念 1.1 调试信息格式 格式类型适用系统存在形式DWA…

Flink部署与应用——部署方式介绍

引入 我们通过Flink相关论文的介绍&#xff0c;对于Flink已经有了初步理解&#xff0c;这里简单的梳理一下Flink常见的部署方式。 Flink 的部署方式 StandAlone模式 介绍 StandAlone模式是Flink框架自带的分布式部署模式&#xff0c;不依赖其他的资源调度框架&#xff0c…