嵌入式软件--51单片机 DAY 4

一、蜂鸣器

当电流通过线圈时会产生电磁场,电磁场与永磁体相互作用,从而使金属膜产生震动而发声。为使金属膜持续震动,蜂鸣器需要使用震荡电路进行驱动。有些蜂鸣器元件内部自带震荡驱动电路,这种蜂鸣器叫做有源蜂鸣器(Active Buzzer,自激式蜂鸣器);而有些则不带震荡驱动电路,这种蜂鸣器叫做无源蜂鸣器(Passive Buzzer,它激式蜂鸣器)。

1.原理图

2.软件实现

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__ */

 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;}
}

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();}
}

 

二、中断系统

1.概念

中断系统是单片机用于处理外部紧急事件的一种机制。中断系统工作的大致流程如下图所示:当CPU正在处理某项任务时,外部发生了某个紧急事件,此时CPU会暂停当前的工作,转而去处理这个紧急事件,处理完之后,再回到原来被中断的位置,继续处理原来的工作。

中断系统使单片机能够实时响应外部事件,提高了系统的灵活性和响应能力。

中断源

中断源是指能够引发中断的事件。

中断标志位

中断标志位用于标识某个中断是否发生,每个中断源都有一个与之对应的中断标志位。当某个中断发生时,相应的中断标位就会置为1,当CPU检测到标志位时,就会处理相应的中断。当中断处理完毕后,中断标志位需要复位(置0),以便接收下一次中断,有些中断源的标志位,会在CPU处理完中断后,自动复位,而有些则需要开发者手动复位,在使用中断时,需要注意查看手册说明。

中断服务程序

中断服务程序指处理中断的逻辑,当某个中断标志位置1时,CPU会自动执行相应的中断服务程序。

中断优先级

中断优先级是指在多个中断同时发生时,单片机响应中断的先后顺序,并且高优先级的中断可以打断低优先级的中断。

中断源:

STC89C52RC共有8个中断源,8个中断源可分为3类,3个类别分别是外部中断(4个)、定时器中断(3个)、串口中断(1个)。

2.外部中断

外部中断是指由单片机外部的紧急事件触发的中断,通过向单片机的特定引脚发送特定的信号触发。STC89C52RC共提供了4个外部中断引脚,分别是INT0,INT1,INT2,INT3,如下图所示。

51单片机的外部中断支持两种触发方式,分别是低电平触发下降沿触发

3.定时器中断

定时器中断是指由单片机内部的定时器触发的中断。

定时器是大多数单片机都具备的一个功能模块,用于实现定时任务。其用法是,设置一个定时值,然后开始计时,待计时结束后,触发相应的定时器中断,开发者可以在中断服务程序中编写定时任务的逻辑。

STC89C52RC共有三个定时器,分别是Timer0、Timer1、Timer2,每个定时器都有一个相对应的中断。

4.串口中断

串口中断是由单片机串口触发的中断。

串口是单片机用于收发数据的重要接口之一,当单片机通过串口接收到数据或者发送完数据后都会触发相应的中断。

STC89C52RC的串口引脚为TxD和RxD,其中TxD用于发送数据,RxD用于接收数据,如下图所示。


5.中断服务程序

中断服务程序是指用于处理中断的一段代码,当中断发生时,CPU就会暂停当前程序的执行,转而执行对应的中断服务程序,处理完中断后再恢复到原来的程序。

STC89C52RC共有8个中断源,分为4个外部中断、3个定时器中断和1个串口中断,开发者可以为每个中断源声明相应的中断服务程序,中断服务程序的声明语法如下。

6.中断优先级

STC89C52RC共有四个中断优先级,每个中断源都可以单独设置优先级。若多个中断同时发生,优先级高的会被优先处理;若两个中断的优先级相同,则根据其中断号决定处理顺序,中断号越小越优先。

除此之外,高优先级的中断还可以打断低优先级的中断,也就是说当CPU正在处理一个中断时,又发生了另外一个优先级比它还高的中断,此时CPU会暂停原来中断的服务程序,转而去处理这个高优先级的中断,处理完之后,再回到原来低优先级的中断服务程序。这个机制叫做中断嵌套,STC89C52RC支持两级中断嵌套。

三、外部中断

需求:使用外部中断的方式,一键控制LED灯的亮灭。

1.硬件设计

若想通过外部中断的方式检测按钮,必须将按钮接入4个外部中断引脚之一,如下图所示,可以看到SW3可用于触发外部中断0。

2.使用说明

(1)启用中断

默认情况,CPU会屏蔽所有中断请求,也就是说CPU不会响应任何中断请求,要使用中断,必须先进行启用。

每个中断源是否被启用,是由单片机内部的两个寄存器控制的,这两个寄存器分别是IE(Interrupt Enable,中断允许)寄存器和XICON(Auxiliary Interrupt Control,辅助中断控制)寄存器。

从上图可以看出,STC89C52系列的中断系统具有两级控制,首先是EA总控制位,其次是每个中断源各自的控制位。因此若需要启用某个中断,需要先将总控制位EA置位1,再将该中断自身的控制位置为1。//EA=1

(2)配置外部中断触发方式

STC89C52系列的外部中断支持两种触发方式,分别是低电平触发和下降沿触发,4个外部中断各需要1个控制位用于设置触发方式,这4个控制位分布于如下两个寄存器中,分别是XICON(Auxiliary Interrupt Control,辅助中断控制)寄存器中、TCON(Timer 0 and 1 Control寄存器,如下图所示。

4个控制位的具体作用可参考下图(STC89C52系列中断系统结构图)。

(3)配置中断优先级

STC89C52系列的中断系统支持四个优先级,所以每个中断源的优先级都需要通过2个控制位进行配置,8个中断源共需要16个控制位,这16个控制位分布在如下3个寄存器中,分别是IPH(Interrupt Priority High,中断优先级高位)寄存器,IP(Interrupt Priority Low,中断优先级低位)寄存器,XICON(Auxiliary Interrupt Control,辅助中断控制)寄存器。

(4)定义中断服务程序

外部中断0到外部中断3的中断号分别是:0、2、6、7,以外部中断0为例,其中断服务程序应定义为

void INT0_Handler() interrupt 0{}

3.软件设计

实现思路:

(1)启用外部中断0

//打开中断总开关
EA=1;
//打开外部中断0开关
EX0=1;

(2)配置外部中断0的触发方式

下降沿触发

IT0=1;

(3)只有一个中断,优先级不考虑

(4)中断服务程序

void INT0_Func() interrupt 0
{LED0=~LED0;
}

完整代码:

#include <STC89C5xRC.H> //包含STC89C52的头文件#define LED0   P00void Init_INT0()
{// 打开中断总开关EA = 1;// 打开外部中断0开关EX0 = 1;// 配置外部中断为下降沿触发IT0 = 1;
}void main()
{Init_INT0();while (1);
}/*** @brief 中断函数中打开LED0,代表当触发中断时,LED0会打开。*        根据我们之前的设置,当按下SW3时,P32为低电平,此时LED0打开。**        interrupt 0表示0号中断触发时执行该函数的逻辑*        如果用C语言编程,中断查询次序就是中断号*/
void INT0_Func() interrupt 0
{// 中断中打开LED0LED0 = ~LED0;
}

四、定时器中断--闪烁LED灯

1.需求:

使用定时器中断的方式实现LED闪烁,具体要求是使用定时器0令LED1每1秒钟闪烁一次。

定时器的基本工作原理,是使用一个n位的脉冲计数器,对时钟信号的脉冲进行计数,每个脉冲加1,当脉冲计数器达到最大值(2n)时,也就是溢出时,触发定时器中断。

2.启用定时器中断

//中断总开关
EA=1;
//定时器0中断开关
ET0=1;

选择定时器工作模式

M1

M0

工作模式

0

0

工作模式0(13位)

0

1

工作模式1(16位)

1

0

工作模式2(8位自动重装载)

1

1

工作模式3(双8位)

计算脉冲初始值

假如现在需要定时1ms,那么1ms需要的脉冲个数应为0.001/(12/11059200),因此定时器的初始值应为65536-0.001/(12/11059200),大约等于64614。

计算完毕后,需要将该值赋予TL0(低8位)和TH0(高8位),如下。

TL0 = 64614;

TH0 = 64614 >> 8;

启动定时器

在做完上述配置后,还需最后一步——启动定时器,启动之后定时器才会开始工作。定时器的启动可由单片机内部的寄存器控制,也可由单片机的外部引脚控制。具体控制逻辑如下图所示。

当GATE=0时,外部引脚(INT0,P3.2)无效,此时只能由内部寄存器TR0控制,当TR0=1时,脉冲计数器开始计数,TR0=0时,停止计数。

当GATE=1时,外部引脚(INT0,P3.2)生效,此时只有当内部寄存器TR0和外部引脚INT0都为1时,脉冲计数器才开始计数,否则停止计数。

3.定义中断服务程序

void Timer0_Hander() interrupt 1

{

    //编写定时任务逻辑

}

4.软件设计

(1)启用定时器中断

EA=1;
ET0=1;

(2)选择定时器0的工作模式

GATE=0 C/T=0 M1=0 M0=1

C/T是TMOD寄存器中定时器0的控制位,选择定时器C/T应为0.

故,TMOD寄存器低四位是0001,高四位保持原值。

TMOD&=0xF0;//高四位不变,低四位归零。

TMOD|=0x01;//高四位不变,最低位变1.

(3)启动定时器

GATE已经设置为0,只要TR0=1,即可启动。

(4)定义中断服务程序

void Timer0_Hander() interrupt 1
{
static unsigned int count = 0;//重新状态脉冲计数器TL0 = 64614;TH0 = 64614 >> 8;//统计中断次数if (count++ >= 500) {LED1  = ~LED1;count = 0;}
}

5.完整代码

Dri_Timer0.c

#include "Dri_Timer0.h"
#include <STC89C5xRC.H>
void Dri_Timer0_Init()
{EA=1;//总开关ET0=1;//定时器0开关//定时器0工作方式TMOD&=0xF0;TMOD|=0x01;//脉冲计数器初始值TL0=64614;TH0=64614>>8;//启动定时器TR0=1;}

Dri_Timer0.h

#ifndef __DRI_TIMER0_H__
#define __DRI_TIMER0_H__void Dri_Timer0_Init();//定时器0开关,启动函数#endif /* __DRI_TIMER0_H__ */

main.c

#include <STC89C5xRC.H>
#include "Dri_Timer0.h"
#include "Com_Util.h"
#define LED1 P00
void main()
{Dri_Timer0_Init();while(1);
}
//定时中断服务程序
void Timer0_Hander() interrupt 0
{LED1=~LED1;Com_Util_Delay1ms(500);
}

6.定时器封装

为使定时器使用起来更加方便和通用,我们可以将定时器代码进一步封装。

(1)思路

初始化定时器-->中断服务程序,轮询调用函数.

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

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

相关文章

计算机网络 TCP/IP协议篇

今天学习了TCP/IP协议的相关知识&#xff0c;学习笔记如下&#xff1a; 在学习之前&#xff0c;我们先抛出几个问题&#xff0c;什么是TCP/IP协议簇&#xff1f;TCP/IP协议簇是怎么工作的&#xff1f; TCP/IP模型 协议分层 每层通过协议完成各自特定的功能上层依赖下层提供…

24/9/6算法笔记 kaggle 房屋价格

预测模型主要分为两大类&#xff1a; 回归模型&#xff1a;当你的目标变量是连续的数值时&#xff0c;你会使用回归模型进行预测。回归模型试图找到输入特征和连续输出之间的关联。一些常见的回归模型包括&#xff1a; 线性回归&#xff08;Linear Regression&#xff09;岭回归…

学不会虚拟列表?10分钟带你实现高度固定的Vue虚拟列表方案及原理

前言 本文主要介绍长列表的一种优化方案&#xff1a;虚拟列表。本文主要是对传统的虚拟列表方案进行更加详尽的刨析&#xff0c;以便我们能够更加深入理解虚拟列表的原理。 虚拟列表目录 1、为什么需要使用虚拟列表2、什么是虚拟列表与懒加载的区别(重要) 3、实现思路4、通过节…

SAP PO附件上传报错 输入时错

SAP PO附件上传报错 场景&#xff1a; 在SAP采购订单上传附件时&#xff0c;出现了SO424报错 Error occurred during import(输入时错)&#xff0c;报错界面如下图所示&#xff1a; 分析&#xff1a; 输入事务代码SLG1&#xff0c;在User处输入自己的用户名并运行报表。本案例…

统计学习方法与实战——统计学习方法之感知机

感知机 感知机三要素分析模型策略损失函数选择 算法原始形式对偶形式 相关问题 例子iris数据集分类实战数据集查看 显示结果sklearn 实战感知机 习题解答习题2.1解题步骤反证法 习题2.2习题2.3凸壳线性可分线性可分证明凸壳不相交证明充分性&#xff1a;凸壳不相交\Rightarrow⇒…

Jenkins 通过 Version Number Plugin 自动生成和管理构建的版本号

步骤 1&#xff1a;安装 Version Number Plugin 登录 Jenkins 的管理界面。进入 “Manage Jenkins” -> “Manage Plugins”。在 “Available” 选项卡中搜索 “Version Number Plugin”。选中并安装插件&#xff0c;完成后可能需要重启 Jenkins。 步骤 2&#xff1a;配置…

ultralytics实现DeepSort目标追踪算法之特征提取网络

文章目录 DeepSort基本流程DeepSort特征提取网络Market-1501数据集目录结构命名规则 数据集划分 网络模型训练过程参数设置数据集加载特征提取网络定义预训练模型加载损失函数与优化器定义mian函数调用训练过程验证过程平均指标与结果 DeepSort基本流程 DeepSort&#xff08;D…

数据结构栈和队列

系统栈 程序运行中使用的栈&#xff0c;由操作系统维护 栈区&#xff1a;1&#xff0c;保存局部变量 2&#xff0c;函数的形参的返回值 3&#xff0c;函数的调用关系 函数中调用函数时会把调用函数的下一条指定的首地址保存在栈区。 &#xff08;保护现…

Steam游戏截图方法

Steam游戏截图方法 截图快捷键 Steam游戏自带截图功能&#xff0c;在游戏中无需复杂的快捷键&#xff0c;仅需按下F12快捷键便可立即截图&#xff0c;官方说明如下。下文介绍使用方法。 查看截图 退出游戏后&#xff0c;在Steam界面点击查看 - 截图&#xff0c;即可查看截…

JAVA—反射

学习Java中关于反射的知识&#xff0c;以理解框架 目录 1.认识反射 2.获取类 3.获取构造器 4.获取成员变量​编辑 5.获取成员方法 6.作用 应用场景 1.认识反射 反射 加载类 并允许以编程的方式解刨类中的各种成分&#xff08;成员变量 方法 构造器&#xff09; 学习反射…

【Hadoop|HDFS篇】HDFS的读写流程

1. HDFS的写流程 1.1 剖析文件的写入 副本存储节点的选择问题&#xff1a; 第一个副本在Client所在的节点上&#xff0c;如果客户端在集群外&#xff0c;随机选一个。第二个副本在另一个机架的随机一个节点上。第三个副本在第二个副本所在的机架的随机节点上。 2. HDFS的写流…

机器学习和物联网驱动技术在加工过程中监测工具磨损:一项全面的综述

这篇论文的标题是《Machine-Learning and Internet-of-Things-Driven Techniques for Monitoring Tool Wear in Machining Process: A Comprehensive Review》&#xff0c;由 Sudhan Kasiviswanathan、Sakthivel Gnanasekaran、Mohanraj Thangamuthu 和 Jegadeeshwaran Rakkiya…

超越传统:Reflection 70B如何革新AI语言处理

Reflection 70B&#xff1a;AI语言模型的新里程碑&#x1f680; AI领域迎来了革命性的变革&#xff0c;HyperWrite公司推出的开源AI大模型Reflection 70B&#xff0c;以其卓越的性能在多个基准测试中超越了GPT-4o和Llama 3.1。这款基于Meta的Llama 3.1 70B Instruct构建的模型…

为何iPhone 16系列的发布对苹果至关重要?

即将发布的iPhone 16系列对苹果来说将是至关重要的时刻&#xff0c;特别是在快速发展的AI智能手机市场背景下。随着Android制造商在集成先进AI功能方面领先一步&#xff0c;苹果正处于一个关键的转折点——赶上竞争对手不仅仅是选择&#xff0c;而是必须完成的任务。 AI竞赛&am…

上交2024最新-《动手学大模型》实战教程及ppt分享!

本课介绍 今天分享一个上海交大的免费的大模型课程&#xff0c;有相关教程文档和Slides&#xff0c;目前是2.2K星标&#xff0c;还是挺火的&#xff01; 《动手学大模型》系列编程实践教程&#xff0c;由上海交通大学2024年春季《人工智能安全技术》课程&#xff08;NIS3353&…

传统CV算法——基于harris检测算法实现角点检测

角点 角点是图像中的一个特征点&#xff0c;指的是两条边缘交叉的点&#xff0c;这样的点在图像中通常表示一个显著的几角。在计算机视觉和图像处理中&#xff0c;角点是重要的特征&#xff0c;因为它们通常是图像中信息丰富的区域&#xff0c;可以用于图像分析、对象识别、3D…

如何在极狐GitLab中添加 SSH Key?

本文分享如何生成 SSH Key 并添加到极狐GitLab 中&#xff0c;然后用 SSH Key 进行代码拉取。 极狐GitLab 是 GitLab 在中国的发行版&#xff0c;可以私有化部署&#xff0c;对中文的支持非常友好&#xff0c;是专为中国程序员和企业推出的企业级一体化 DevOps 平台&#xff0…

43. 1 ~ n 整数中 1 出现的次数【难】

comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9843.%201%EF%BD%9En%E6%95%B4%E6%95%B0%E4%B8%AD1%E5%87%BA%E7%8E%B0%E7%9A%84%E6%AC%A1%E6%95%B0/README.md 面试题 43. 1 &#xff5e; n 整数中 1 …

C#游戏服务器开发框架设计与架构详解

我一直在思考一个问题&#xff0c;什么样的服务端框架最好用&#xff0c;最适合? 经过这些年的项目经验&#xff0c;其实最好用&#xff0c;最适合的游戏服务端框架就是自己结合公司项目需求,团队特点与技术能力,自己整合的游戏框架是最好用的。 很多新手会担心自己整合的框架…

JS生成二维码QRCode代码

JavaScript是一种广泛使用的前端编程语言&#xff0c;它不仅用于网页交互&#xff0c;还可以实现许多实用功能&#xff0c;如生成二维码。本篇文章将深入探讨如何使用JavaScript生成二维码&#xff0c;以及如何确保这种生成的二维码在各种浏览器和手机端都能正常工作&#xff0…