1.按键模块

        以按键k1为例:两个引脚被接到GND和P1_4引脚,当K1按键被按下时,P1_4引脚会和GND短路到一起,P1_4引脚会呈现低电平。

按键初始化:

//按键初始化
void Key_Init(void)
{P1 |= (0x0f << 4);P3 |= (1 << 5);
}

检测那个按键按下:

int Key_Press(void)
{int ret = 0;if((P1 & (1 << 4)) == 0){ret = 1;}else if ((P1 & (1 << 5)) == 0){ret = 2;}else if ((P1 & (1 << 6)) == 0){ret = 3;}else if ((P1 & (1 << 7)) == 0){ret = 4;}else if ((P3 & (1 << 5)) == 0){ret = 5;}
}

我们可以以此写一个函数:那个按键亮起就让数码管显示那个数字,如k1亮起数码管显示1,如果没有按钮按下则显示0(Diditer_Show函数在上一篇文章有展示)

#include <reg51.h>
#include <key.h>
#include <digiter.h>
#include <delay.h>
int main(void)
{int ret = 0;Key_Init();while(1){ret = Key_Press();Digiter_Show(ret);P0 = 0;}return 0;
}

2.中断

        中断概念:CPU在执行一个任务时,被外界更为紧急的事件打断,转而去执行更为紧急的任务,执行完后再回到刚才的地方继续向下执行,这一过程叫做中断。

        中断源:打断CPU执行当前任务的事件/源头叫做中断源。

        中断源分类外部中断0、外部中断1、定时器0、定时器1、串口。

        中断优先级:CPU再去处理中断任务时候,会去比较多个中断的优先级,优先去处理优先级高的中断

        默认优先级:

         中断嵌套:处理一个中断时,再嵌套另外的中断;51单片机只允许嵌套2层。

        中断处理流程

        (1)中断源发出中断请求

        (2)检查CPU是否响应中断及该中断源是否被屏蔽

        (3)比较中断优先级

        (4)保护现场

        (5)执行中断服务函数(回调函数)

        (6)恢复现场

2.1外部中断

        单片机上的引脚电平变化所引发的中断(INT0(P3-2)、INT1(P3-3))

寄存器相关配置:

1. IE寄存器(中断允许寄存器)

        (1)将IE寄存器中的bit7,EA置1,代表CPU能够响应所有中断

        (2)将IE寄存器中的bit0,EX0置1,代表允许外部中断0产生中断

2. TCON寄存器(定时器寄存器)

(1)将TCON寄存器的bit1,IE0置1,代表向CPU发起中断请求,CPU响应完中断请求后,硬件清“0”

        (2)将TCON寄存器的bit0,IT0置1,代表外部中断0下降沿触发中断

知道相关寄存器内容后,我们来对外部中断0进行配置:

//中断配置
void int0_init(void)
{P3 |= (1 << 2);//将外部中断0对应的引脚置1IE |= (1 << 7);//CPU能够响应所有中断   总开关IE |= (1 << 0);//外部中断0能够发起中断   子开关TCON |= (1 << 0);//外部中断0:P3_2引脚中断触发方式->下降沿触发
}

再编写中断处理函数,即发生中断后所执行的函数内容:

//外部中断0的处理函数,每次发生中断g_i++,无需声明
unsigned int g_i = 0;
void Int0_Handler(void)  interrupt 0
{g_i++;
}

每发生一次中断,g_i都会进行自加,我们将g_i传参进Digiter_Show函数中,使得中断次数在数码管上显示:

#include <reg51.h>
#include <key.h>
#include <digiter.h>
#include <delay.h>
int main(void)
{int ret = 0;Key_Init();int0_init();while(1){Digiter_Show(g_i);	}return 0;
}

        用杜邦线短接P3.2和GND,每次短接,都会产生下降沿触发外部中断0,数码管也会显示中断次数。

2.2定时器中断

定时器:能够产生一个精准的定时,不同外设对时序的要求高(高电平和低电平时间是精准的)

        51单片机内部有两个定时器,分别为timer0、timer1,所使用自增型定时器(计数器 16位),因此其自增范围为0~2^16=65535。

         晶振,晶体振荡器(12MHZ / 11.0592MHZ)

         由于51单片机达不到12MHZ,将12MHZ进行12分频,12MHZ/12 = 1MHZ

         51单片机完成一条指令运算:1/1MHZ = 1us。

因此我们要想定时1ms,需要51单片机完成1000次计时,由于其为自增型,因此我们需要将初始值设为65535-1000=64535。在执行1000次运算后定时器溢出,也就是1ms后中断。


定时器相关寄存器配置

TCON寄存器:

            (1)bit4置1,TMOD寄存器中的Gate位清0, 代表允许定时器开始计数,

TMOD寄存器:

            (1)定时器0->低四位清0

            (2)将TMOD寄存器中的M0,bit0置1,代表定时器0工作在16位定时器/计数器模式

IE寄存器:

            (1)将IE寄存器中的bit7置1,代表CPU能够响应所有中断

(2)将IE寄存器中的bit1置1,代表允许定时器0产生中断

配置流程:

        1. 先配置TMOD模式选择寄存器,将低四位清0,再将bit0置1代表工作在16位定时器

        2. 向TH0和TL0中装入定时器的初值(1ms -> 64535)

3.  将TCON寄存器中的bit6置1,代表允许定时器开始计数

        4.  将IE寄存器中的bit7和bit1置1,开启中断总开关和定时器0的子开关

        5. 编写定时器0的中断服务函数
我们对定时器进行配置:

// 定时器0初始化函数
void Timer0_Init(void)
{TMOD &= ~(0x0F << 0);    // TMOD寄存器低四位清0TMOD |= (1 << 0);		 // 定时器工作在16位定时器模式TH0 = 64535 >> 8;TL0 = 64535;TCON |= (1 << 4);    // 允许定时器0开始计数IE |= (1 << 7) | (1 << 1);   // 允许CPU响应中断及定时器0产生中断
}

中断服务函数:每过1s对所有LED灯进行一次反转。

void Timer0_handler(void)  interrupt 1
{TH0 = 64535 >> 8;TL0 = 64535;g_i++;if (g_i >= 1000){LED_Nor();g_i = 0;}
}

写入主函数:

#include <reg51.h>
#include "timer.h"
#include "led.h"
int main(void)
{Timer0_Init();while (1){}return 0;
}

3.蜂鸣器模块

                        

蜂鸣器

            震荡源  -> 声音(波)-> 音调不同 -> 波的频率发生变化 -> 高音 高频  低音 低频   音量不同 -> 波的振幅 -> 能量

            有源蜂鸣器:存在震荡源,通电后蜂鸣器会发出持续频率的声音。

            无源蜂鸣器:不存在震荡源,通电后蜂鸣器不会发出声音,需要给蜂鸣器一个震荡。

PWM:脉冲宽度调制,能够让引脚产生一个方波,周期性的让引脚的电平发生翻转。

        PWM周期:一个方波所经历的周期。(从上升沿到上升沿所经历的时间/从下降沿到下降沿所经历的时间)

        PWM占空比:在一个周期内高电平所占的比例。

我们分别调制200,400,600,800,1000hz的蜂鸣器发声频率

以200为例

                PWM蜂鸣器按照频率200HZ,占空比50%工作
频率:200HZ
时间:17公0==0.005s
定时:0.005s/2-0.0025s
定时器初值:
品振:12MHZ*10^6=12,000,000HZ分频:12,000,000HZ/12=1000000HZ
时间:1/1000000HZ=0.000001s
定时器初值:
0.0025/0.000001=2500
65535-2500=63035
TH0=63035 >> 8;TL0=63035;

调制好的频率对应的计数器初始值:

#ifndef TIMER_H__
#define TIMER_H__
extern void Timer0_Init(void);
extern unsigned short g_i1;
#define HZ200  63035
#define HZ400  64285
#define HZ600  64703
#define HZ800  64910
#define HZ1000 65035
#endif

定时器初始化以及中断服务:

#include <reg51.h>
#include "led.h"
unsigned short g_i1 = 0;
// 定时器0中断服务函数
void Timer0_handler(void)  interrupt 1
{TH0 = g_i1 >> 8;TL0 = g_i1;P2 ^= (1 << 1); //蜂鸣器反转信号        
}// 定时器0初始化函数
void Timer0_Init(void)
{TMOD &= ~(0x0F << 0);    // TMOD寄存器低四位清0TMOD |= (1 << 0);		 // 定时器工作在16位定时器模式TH0 = g_i1 >> 8;TL0 = g_i1;TCON |= (1 << 4);    // 允许定时器0开始计数IE |= (1 << 7) | (1 << 1);   // 允许CPU响应中断及定时器0产生中断
}

主函数调用:当按键按下后蜂鸣器会发出对应声音:

#include <reg51.h>
#include "timer.h"
#include "led.h"
#include "key.h"
int main(void)
{int set = 0;Key_Init();Timer0_Init();while (1){set = Key_Press();if (set ==0){TCON = 0;}else if(set == 1){TCON |= (1 << 4);g_i1 = HZ200;}else if(set == 2){TCON |= (1 << 4);g_i1 = HZ400;}else if(set == 3){TCON |= (1 << 4);g_i1 = HZ600;}else if(set == 4){TCON |= (1 << 4);g_i1 = HZ800;}else if(set == 5){TCON |= (1 << 4);g_i1 = HZ1000;}}return 0;
}

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

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

相关文章

【面试向】人工智能机器学习介绍

一、介绍 人工智能&#xff08;AI&#xff09;是通过模拟、延伸和扩展人类智能的技术&#xff0c;使机器能够感知、理解、决策和行动。核心目标是实现“智能自动化”&#xff0c;即让机器在复杂、动态的环境中自主完成任务&#xff0c;甚至超越人类在特定领域的能力。 机器学…

Python趣味入门:打印与计算初体验

1. 尝试使用 print() 打印各种内容print() 是我们在Python中最先接触也是最常用的函数之一。它的核心功能是将内容输出到控制台。让我们用它来玩点花样&#xff1a;在您的IDE中创建一个新的Python文件&#xff08;例如 play_with_print.py&#xff09;&#xff0c;然后尝试以下…

swagger接口文档规范化(苍穹外卖)

swagger接口文档规范化 &#xff08;1&#xff09;说明&#xff1a; 将接口文档分为管理端和用户端 &#xff08;2&#xff09;WebMvcConfiguration修改 位置&#xff1a;sky-server/src/main/java/com/sky/config/WebMvcConfiguration.java 文件完整代码&#xff1a; pa…

Transformer 架构的演进与未来方向(RNN → Self-Attention → Mamba)——李宏毅大模型2025第四讲笔记

一句话总结——“所有架构都为了解决上一代模型的致命缺陷而生&#xff1a;CNN 解决参数爆炸&#xff0c;ResNet 解决梯度消失&#xff0c;Transformer 解决 RNN 无法并行&#xff0c;而 Mamba 则试图一次解决 Transformer 的 O(N) 与 RNN 的记忆瓶颈。”1 每种架构的存在理由•…

Vllm-0.10.1:通过vllm bench serve测试TTFT、TPOT、ITL、E2EL四个指标

一、KVM 虚拟机环境GPU:4张英伟达A6000(48G)内存&#xff1a;128G海光Cpu:128核大模型&#xff1a;DeepSeek-R1-Distill-Qwen-32B推理框架Vllm:0.10.1二、四个性能指标介绍2.1、TTFT:Time to First token首次生成token时间&#xff08;ms&#xff09;,TTFT 越短&#xff0c;用户…

逻辑回归基础

昨天一直在复盘梯度下降&#xff0c;都没咋预习逻辑回归&#xff0c;好在不是很难&#xff0c;来捋捋逻辑回归简介逻辑回归是解决分类问题数学基础-sigmoid函数还要回顾一下概率论极大似然估计再来看一下对数逻辑回归原理逻辑回归的损失函数例子&#xff1a;分类问题评估混淆矩…

STM32----W25QXX

W25QXX款图W25QXX存储解读块--->扇-->页块分成128块一块64kb一块分成16扇一扇4kb一个扇区分成16页&#xff0c;页的大小是256个字节 当数据传入W25QXX最小的擦除单元是扇区当已经输入了一页的数据&#xff0c;这时RAM的数据会转存进FLASH&#xff0c;这时会置一个标志位&…

【Kafka】Kafka使用场景用例Kafka用例图

【Kafka】Kafka使用场景用例&Kafka用例图一、Kafka用例总图二、Kafka用例图示三、Kafka场景案例图一、Kafka用例总图 二、Kafka用例图示 三、Kafka场景案例图 注&#xff1a;以上图片来源于网络&#xff0c;如有不妥请私信删除&#xff01;

Altium Designer(AD24)集成开发环境简介

🏡《专栏目录》 目录 1,概述 2,界面介绍 2,搜索功能简介 1,概述 Altium Designer 24的原理图,PCB等设计工作都是在集成开发环境中进行的,本文简单介绍集成开发环境界面。 2,界面介绍 如下图所示,Altium Designer 24的集成开发环境,包括: 标题栏:目前设计中文件的…

[论文阅读] 软件工程 | 告别“线程安全玄学”:基于JMM的Java类静态分析,CodeQL3分钟扫遍GitHub千仓错误

告别“线程安全玄学”&#xff1a;基于JMM的Java类静态分析&#xff0c;CodeQL3分钟扫遍GitHub千仓错误 论文信息类别详情论文原标题Scalable Thread-Safety Analysis of Java Classes with CodeQL主要作者及机构1. Bjrnar Haugstad Jatten&#xff08;哥本哈根IT大学&#xff…

jQuery.ajax() 方法核心参数详解

大家好&#xff0c;欢迎来到程序视点&#xff01;我是你们的老朋友.小二&#xff01;jQuery.ajax() 方法核心参数详解基础参数url类型&#xff1a;String功能&#xff1a;请求地址&#xff0c;默认当前页地址。type类型&#xff1a;String&#xff08;get/post为主&#xff0c;…

LCR 175. 计算二叉树的深度【简单】

LCR 175. 计算二叉树的深度【简单】 题目描述 某公司架构以二叉树形式记录&#xff0c;请返回该公司的层级数。 示例 1&#xff1a;输入&#xff1a;root [1, 2, 2, 3, null, null, 5, 4, null, null, 4] 输出: 4 解释: 上面示例中的二叉树的最大深度是 4&#xff0c;沿着路…

AI驱动健康升级:新零售企业从“卖产品”到“卖健康”的转型路径

随着健康意识的不断提升&#xff0c;健康管理增值服务正逐渐成为零售企业的核心竞争力。消费者对“产品服务”的需求激增&#xff0c;企业亟需构建覆盖健康评估、干预到跟踪的营养健康管理体系&#xff0c;通过数据化手段提升用户粘性。在此背景下&#xff0c;AI技术正推动健康…

2025年最新三维WebGIS开发学习路线图深度解析

地信小白为何学习webgis&#xff1f;我们在后台经常收到同学们关于地信测绘等专业的吐槽&#xff0c;总结后主要分为以下几类&#xff1a;第一种吐槽学校理论与实践脱节的&#xff0c;学校课程偏重理论&#xff0c;缺乏企业级真实项目经验&#xff0c;导致同学们简历空洞、单一…

15-Java-面向对象-标准JavaBean类

文章目录标准JavaBean类标准JavaBean类 类名需要见名知意成员变量使用private修饰提供至少两个构造方法 无参构造方法带全部参数的构造方法 成员方法 提供每一个成员变量对应的setXxx&#xff08;&#xff09;/getXxx&#xff08;&#xff09;如果还有其他行为&#xff0c;也需…

AI大模型应用研发工程师面试知识准备目录

一、大模型核心基础理论 大模型核心架构&#xff1a;Transformer&#xff08;Encoder/Decoder结构、自注意力机制、多头注意力&#xff09;、GPT系列&#xff08;Decoder-only&#xff09;、BERT系列&#xff08;Encoder-only&#xff09;的差异与适用场景关键技术原理&#xf…

基于单片机汽车防撞系统设计

传送门 &#x1f449;&#x1f449;&#x1f449;&#x1f449;单片机作品题目速选一览表&#x1f680; &#x1f449;&#x1f449;&#x1f449;&#x1f449;单片机作品题目功能速览&#x1f680; &#x1f525;更多文章戳&#x1f449;小新单片机-CSDN博客&#x1f68…

《Java线程池面试全解析:从原理到实践的高频问题汇总》

线程池作为Java并发编程的核心组件&#xff0c;是面试中的必考知识点。无论是初级开发岗还是资深架构岗&#xff0c;对线程池的理解深度往往能反映候选人的并发编程能力。本文汇总了线程池相关的高频面试题&#xff0c;并提供清晰、深入的解答&#xff0c;助你轻松应对各类面试…

波特率vs比特率

一、核心定义1. 波特率&#xff08;Baud Rate&#xff09;定义&#xff1a;单位时间内传输的 “信号符号&#xff08;Symbol&#xff09;” 数量&#xff0c;单位为 “波特&#xff08;Baud&#xff09;”。这里的 “符号” 是通信中的基本信号单元&#xff0c;指信号在物理层的…

AI 生成式艺术重塑动漫角色创作:从技术逻辑到多元可能性(一)

当《蜘蛛侠&#xff1a;纵横宇宙》中风格迥异的角色群像惊艳银幕&#xff0c;当《鬼灭之刃》的 “柱” 系列角色凭借鲜明人设圈粉无数&#xff0c;动漫角色早已超越 “故事载体” 的属性&#xff0c;成为承载世界观、传递情感的核心符号。传统动漫角色创作往往依赖团队数月甚至…