【51单片机系列】C51中的中断系统扩展实验
本文是关于51单片机中断系统的扩展实验。
文章目录
- 一、 扩展实验一:使用外部中断0控制蜂鸣器,外部中断1控制直流电机
- 二、扩展实验二:修改定时器初值,设定3秒钟的定时时间让LED模块闪烁
- 三、扩展实验三:使用定时器1和数码管设计一个数字时钟
一、 扩展实验一:使用外部中断0控制蜂鸣器,外部中断1控制直流电机
外部中断扩展实验一实现的功能:使用外部中断0控制蜂鸣器发声/不发声,外部中断1控制直流电机转动/停止。
由蜂鸣器的内容可以知道,蜂鸣器分为有源蜂鸣器和无源蜂鸣器;蜂鸣器有两个管脚,要使蜂鸣器发声,需要有电流通过蜂鸣器,即管脚一端接正极,管脚另一端接负极。有源蜂鸣器只需给一定的电压即可发声,无源蜂鸣器需要一定频率的脉冲才可发声。这里设计了两种蜂鸣器,都由外部中断0控制。
直流电机的驱动方式与蜂鸣器类似。
proteus中硬件设计如下,为显示蜂鸣器的发声,这里使用了一个LED显示发声与否。蜂鸣器的一端连接到电源,另一端经过ULN2003芯片连接P1.5口,当P1.5=0时蜂鸣器发声;直流电机的一端连接到电源,另一端经过ULN2003连接到P1.0口,当P1.0=0时电机转动。为体现中断,使用独立按键模块连接到P3.2和P3.3口,当按键按下,蜂鸣器发声或电机转动。

软件设计如下:
/*实现功能:外部中断0控制蜂鸣器发声,外部中断1控制直流电机转动- 与外部中断0和外部中断1有关的有两个寄存器IE和TCON,- IE是中断允许控制寄存器,TCON是中断请求标志寄存器。- IE中包括了- 总中断允许位(EA)- 外部中断0/1允许位(EX0/EX1)- 定时器0/1允许位(ET0/ET1)- 串口中断允许位(ES);- TCON中的低四位是外部中断允许和触发方式控制位,包括了- IT0/IT1是外部中断0/1触发方式控制位,0表示低电平触发,1表示下降沿触发;- IE0/IE1是外部中断0/1请求标志位[2023-12-19] zoya
*/#include "reg52.h"
#include "typedef.h"
#include "Delay.h"sbit BEEP = P1^5;
sbit MOTOR = P1^0;
sbit CTR_INT0 = P3^2;
sbit CTR_INT1 = P3^3;/*************************************************************************
* 函数名: IntInit
* 函数功能: 外部中断0/1初始化,设置中断触发方式为边沿触发
* 输入: void
* 输出: void
**************************************************************************/
void IntInit()
{// 1. 设置中断触发方式IT0=1;IT1=1;// 2. 打开外部中断0/1EX0=1;EX1=1;// 3. 打开总中断EA=1;
}void main()
{MOTOR=0;BEEP=0;IntInit(); while(1);
}/*************************************************************************
* 函数名: Int0
* 函数功能: 外部中断0中断服务函数,
* 控制蜂鸣器发声
* 输入: void
* 输出: void
**************************************************************************/
void Int0() interrupt 0
{delayms(10); // 按键延时消抖if(0 == CTR_INT0){BEEP = ~BEEP;}
}/*************************************************************************
* 函数名: Int1
* 函数功能: 外部中断1中断服务函数,
* 控制直流电机转动
* 输入: void
* 输出: void
**************************************************************************/
void Int1() interrupt 2
{delayms(10); // 按键延时消抖if(0 == CTR_INT1){MOTOR=~MOTOR;}
}
仿真结果:

二、扩展实验二:修改定时器初值,设定3秒钟的定时时间让LED模块闪烁
如何计算定时器初值?
以使用12MHz的晶振频率计算。如果使用的是12MHz晶振,单片机内部的时钟频率为12分频即12/12MHz=1MHz;那么对应的机器周期为1/1MHz=1us。即使用12MHz晶振的机器周期为1us。
如果要定时1ms,需要计数1ms/1us=1000个,定时器使用方式1工作,那么初值为 2 16 − 1000 = 64536 2^{16}-1000 = 64536 216−1000=64536 = 0xFC18。即初值THx=0xfc,TLx=0x18。
如果要定时1s,可以通过初值设置定时1ms,当定时结束重新赋初值,并设定一个全局变量累计定时1ms的次数,当该全局变量累计1000次时表示定时1s。
如果要设定3s时间,可以通过初值设定定时3ms,其它同定时1ms。定时3ms需要计数3ms/1us=3000,定时器使用方式1工作,初值为 2 16 − 3000 2^{16} - 3000 216−3000 = 62536 = 0xF448,即初值THx=0xF4,TLx=0x48。
该实验在前面使用示例的基础上更改计数初值即可实现定时3s实现LED模块的闪烁。proteus中设计LED模块如下,定时器模块在单片机内部。

软件设计如下:
/*实现功能:定时器0定时3s实现LED模块亮灭- 与定时/计数器工作有关的寄存器有IE、TCON、TMOD、THx、TLx- IE是中断允许控制寄存器,TCON是中断请求标志寄存器,TMOD是定时/计数器工作方式寄存器- THx和TLx是计数初值赋值寄存器。- IE中包括了- 总中断允许位(EA)- 外部中断0/1允许位(EX0/EX1)- 定时器0/1允许位(ET0/ET1)- 串口中断允许位(ES);- TCON中的高四位用于控制定时/计数器的启动和中断申请,包括TR0/1、TF0/1- TR0/TR1是T0/T1运行控制位,TR0=1时开始工作,TR0=0时停止工作,TR1与TR0类似;- TF0/TF1是T0/T1溢出中断请求标志位,溢出时由硬件自动置位,CPU响应中断后由硬件自动清0可随时查询该位状态,也可软件置1或清0.- TMOD高四位控制T1,低四位控制T0,高四位和低四位分别为有GATE、C/T、M1M0- GATE是门控位,- GATE=0表示不受外部中断信号影响,仅TR0/TR1控制定时/计数器工作,- GATE=1表示受外部中断信号影响,即TR0/TR1+INT0控制定时/计数器工作- C/T是定时/计数器模式选择位,C/T=0为定时模式,C/T=1为计数模式;- M1M0是工作方式设置位,有四种方式:00 01 10 11[2023-12-20] zoya
*/#include "reg52.h"
#include "typedef.h"
#include "Delay.h"#define GPIO_LED P2
/*************************************************************************
* 函数名: Timer0Init
* 函数功能: 定时器0初始化,工作方式1定时3ms,仅TR0启动或停止计数
* 输入: void
* 输出: void
**************************************************************************/
void Timer0Init()
{// 1. 设置工作方式1,仅TR0控制TMOD |= 0x01;// 2. 设置定时3ms的初值,0xf448TH0 = 0xf4;TL0 = 0x48;// 3. 打开中断允许位EA = 1;ET0 = 1;// 4. 置位TR0,开始计数TR0 = 1;
}void main()
{Timer0Init(); while(1);
}/*************************************************************************
* 函数名: Timer0
* 函数功能: 定时器0中断服务函数,定时3s控制LED模块亮灭
* 输入: void
* 输出: void
**************************************************************************/
void Timer0() interrupt 1
{static u16 i;// 重新赋初值TH0 = 0xf4;TL0 = 0x48;i++;if(1000 == i){i=0;GPIO_LED = ~GPIO_LED;}
}
仿真结果:

三、扩展实验三:使用定时器1和数码管设计一个数字时钟
定时器的设置参考扩展实验二。
数字时钟采用24小时制,显示使用“00-00-00”格式。
这里数码管使用一个八位一体的共阴极数码管,使用芯片74HC138控制数码管的位选,使用芯片74HC245控制数码管的段选;P0口控制74HC245的输入,P2.2 ~ P2.4控制74HC138的输入。proteus设计如下:

软件设计如下:
/*实现功能:定时器1和数码管设计一个数字时钟- 与定时/计数器工作有关的寄存器有IE、TCON、TMOD、THx、TLx- IE是中断允许控制寄存器,TCON是中断请求标志寄存器,TMOD是定时/计数器工作方式寄存器- THx和TLx是计数初值赋值寄存器。- IE中包括了- 总中断允许位(EA)- 外部中断0/1允许位(EX0/EX1)- 定时器0/1允许位(ET0/ET1)- 串口中断允许位(ES);- TCON中的高四位用于控制定时/计数器的启动和中断申请,包括TR0/1、TF0/1- TR0/TR1是T0/T1运行控制位,TR0=1时开始工作,TR0=0时停止工作,TR1与TR0类似;- TF0/TF1是T0/T1溢出中断请求标志位,溢出时由硬件自动置位,CPU响应中断后由硬件自动清0可随时查询该位状态,也可软件置1或清0.- TMOD高四位控制T1,低四位控制T0,高四位和低四位分别为有GATE、C/T、M1M0- GATE是门控位,- GATE=0表示不受外部中断信号影响,仅TR0/TR1控制定时/计数器工作,- GATE=1表示受外部中断信号影响,即TR0/TR1+INT0控制定时/计数器工作- C/T是定时/计数器模式选择位,C/T=0为定时模式,C/T=1为计数模式;- M1M0是工作方式设置位,有四种方式:00 01 10 11使用一个八位一体的共阴极数码管显示时间,74HC138芯片控制数码管的位选,74HC245控制数码管的段选。[2023-12-20] zoya
*/#include "reg52.h"
#include "typedef.h"
#include "Delay.h"#define GPIO_DISPLAY P0
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;// 共阴极数码管的码表,0-9以及:
u8 code smg[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x67, 0x40};static u16 h, m, s;/*************************************************************************
* 函数名: Timer0Init
* 函数功能: 定时器0初始化,工作方式1定时3ms,仅TR0启动或停止计数
* 输入: void
* 输出: void
**************************************************************************/
void Timer1Init()
{// 1. 设置工作方式1,仅TR0控制TMOD |= 0x10;// 2. 设置定时1ms的初值,0xFC18TH1 = 0xFC;TL1 = 0x18;// 3. 打开中断允许位EA = 1;ET1 = 1;// 4. 置位TR1,开始计数TR1 = 1;
}void DigDisplay()
{LSA=0; LSB=0; LSC=0; GPIO_DISPLAY = smg[h/10];delayms(1);LSA=1; LSB=0; LSC=0; GPIO_DISPLAY = smg[h%10];delayms(1);LSA=0; LSB=1; LSC=0; GPIO_DISPLAY = smg[10];delayms(1);LSA=1; LSB=1; LSC=0; GPIO_DISPLAY = smg[m/10];delayms(1);LSA=0; LSB=0; LSC=1; GPIO_DISPLAY = smg[m%10];delayms(1);LSA=1; LSB=0; LSC=1; GPIO_DISPLAY = smg[10];delayms(1);LSA=0; LSB=1; LSC=1; GPIO_DISPLAY = smg[s/10];delayms(1);LSA=1; LSB=1; LSC=1; GPIO_DISPLAY = smg[s%10];delayms(1);
}void main()
{GPIO_DISPLAY = 0x00;Timer1Init(); while(1){DigDisplay();}
}/*************************************************************************
* 函数名: Timer1
* 函数功能: 定时器1中断服务函数,控制数码管显示
* 输入: void
* 输出: void
**************************************************************************/
void Timer1() interrupt 3
{static u16 j;// 重新赋初值TH1 = 0xFC;TL1 = 0x18;j++;if(1000 == j){j=0;s++;if(60 == s){s=0; m++;if(60 == m){m=0; h++;if(24 == h){h=0;}}}}
}
仿真结果:

相关文章:
【51单片机系列】C51中的中断系统扩展实验
本文是关于51单片机中断系统的扩展实验。 文章目录 一、 扩展实验一:使用外部中断0控制蜂鸣器,外部中断1控制直流电机二、扩展实验二:修改定时器初值,设定3秒钟的定时时间让LED模块闪烁三、扩展实验三:使用定时器1和数…...
Poi实现复杂Excel导出,理解POI操作Excel思路!!!
前言 对于简单excel报表导出,有很多简单的工具如easypoi,而且现在网上已经有很多工具类整合easypoi使用起来非常方便。但是简单的弊端往往无法适配一些负责场景,而我们实际生产中面临的都是客户自定以的一个负责报表导出,这是利用…...
关于 jsconfig.json 文件在导入文件路径提示方面
前文:以前我弄不清 jsconfig.json 文件的作用是什么,只觉得 tsconfig.json 文件是用来 ts 编译的配置项,js 又不用编译为什么会需要 jsconfig.json 文件。搬了这么久的砖,也算是有所心得,今日记下以备不时之需。 jsco…...
验证码:防范官网恶意爬虫攻击,保障用户隐私安全
网站需要采取措施防止非法注册和登录,验证码是有效的防护措施之一。攻击者通常会使用自动化工具批量注册网站账号,以进行垃圾邮件发送、刷量等恶意活动。验证码可以有效阻止这些自动化工具,有效防止恶意程序或人员批量注册和登录网站。恶意程…...
python学习笔记--异常捕获
异常场景 numinput("input you number:") n9000 try:resultn/int(num)print({} 除以num 结果为{}.format(n,result)) except ZeroDivisionError as err:print("0不可以作为除数,出现报错{}".format(err)) except ValueError as err:print(&quo…...
ChatGPT如何计算token数?
GPT 不是适用于某一门语言的大型语言模型,它适用于几乎所有流行的自然语言。所以 GPT 的 token 需要 兼容 几乎人类的所有自然语言,那意味着 GPT 有一个非常全的 token 词汇表,它能表达出所有人类的自然语言。如何实现这个目的呢?…...
页面菜单,通过get请求一个url后,跳转另外一个页面,+丢失问题
业务场景描述: 在A系统,菜单点击跳B系统这个操作。 A系统菜单是get请求到B系统的一个缓冲页面,然后这个缓冲页面获取到url中的accessToken后,在这个页面中通过post请求后端接口。 问题描述: 当accessToken中包含了…...
高并发场景下的延时双删
基本介绍 "延时双删"是一种在并发编程中使用的技术,用于处理缓存和数据库之间的数据一致性问题。在高并发的场景下,这种方法特别有用。下面是对延时双删的详细介绍: 基本概念: 缓存与数据库的不一致:在并发…...
log4js-node在nodejs项目中的使用示例
在Node.js项目中使用log4js-node模块可以帮助你记录日志。以下是一个简单的示例,演示了如何在Node.js项目中使用log4js-node模块: 首先,你需要安装log4js-node模块。在终端中执行以下命令: npm install log4js 接下来ÿ…...
Java_集合进阶(Collection和List系列)
一、集合概述和分类 1.1 集合的分类 已经学习过了ArrayList集合,但是除了ArrayList集合,Java还提供了很多种其他的集合,如下图所示: 我想你的第一感觉是这些集合好多呀!但是,我们学习时会对这些集合进行…...
QT GUI代码大全(MainWindow, QFile, QPainter, QGraphicsItem/Scene/View)
文章目录 窗口设置QMainWindow类 按钮和菜单QMenuBar类QMenu类QAction类 文件交互QFileDialog类QFileInfo类QFile类QTextStream 绘图QPixmap类QPainter类QBrush类QPen类QPainterPath类 游戏场景QGraphicsItem类QGraphicsScene类QGraphicsView类 窗口设置 QMainWindow类 QMainW…...
C# Onnx Yolov8 Detect 物体检测 多张图片同时推理
目录 效果 模型信息 项目 代码 下载 C# Onnx Yolov8 Detect 物体检测 多张图片同时推理 效果 模型信息 Model Properties ------------------------- date:2023-12-18T11:47:29.332397 description:Ultralytics YOLOv8n-detect model trained on …...
学习使用js保留两位小数同时去掉小数末尾多余的00
学习使用js保留两位小数同时去掉小数末尾多余的00 前言去除00方法 前言 let number 50000000;let new_number number / 10000;console.log(formatter-new_number, new_number);return new_number.toFixed(2) 万;会发现整数使用toFixed(2),之后会有多余的.00 去…...
linux驱动的学习 驱动开发初识
1 设备的概念 在学习驱动和其开发之前,首先要知道所谓驱动,其对象就是设备。 1.1 主设备号&次设备号: 在Linux中,各种设备都以文件的形式存在/dev目录下,称为设备文件。最上层的应用程序可以打开,关…...
Node.js中npm中ws的WebSocket协议的实现
在Node.js中,ws是一个非常有用的模块,它提供了WebSocket协议的实现。WebSocket协议是一种在Web浏览器和服务器之间进行双向通信的协议,它可以使得Web应用程序更加交互式和实时。在本文中,我们将详细介绍npm中ws的内容。 ws是什么…...
PHP HTTPoxy CGI 应用程序漏洞 CVE-2016-5385
HTTPoxy CGI 应用程序漏洞 CVE-2016-5385 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议 漏洞名称 漏洞描述 在Oracle Communications BRM 10.x/12.x(云软件)中发现漏洞。它已经被宣布为关键。此漏洞影响组件用户数据库的未…...
qt-C++笔记之使用QLabel和QPushButton实现一个bool状态的指示灯
qt-C笔记之使用QLabel和QPushButton实现一个bool状态的指示灯 code review! 文章目录 qt-C笔记之使用QLabel和QPushButton实现一个bool状态的指示灯1.QPushButton实现2.QLabel实现2.QLabel实现-对错符号 1.QPushButton实现 运行 代码 #include <QtWidgets>class Ind…...
自动驾驶技术入门平台分享:百度Apollo开放平台9.0全方位升级
目录 平台全方位的升级 全新的架构 工具服务 应用软件(场景应用) 软件核心 硬件设备 更强的算法能力 9.0版本算法升级总结 更易用的工程框架 Apollo开放平台9.0版本的技术升级为开发者提供了许多显著的好处,特别是对于深度开发需求…...
Elementor Pro v3.18.1和(完整模板套件)介绍说明
WordPress 插件:免费下载 Elementor Pro v3.18.1 免费最新版本 [所有功能已激活] Elementor Pro 是一个功能强大的 WordPress 插件,使用户无需编码即可构建和设计网站。它是 Elementor 页面构建器的付费版本,提供额外的功能和小部件来创建更复杂的设计。在这篇博文中,我们将探讨…...
Windows如何安装使用TortoiseSVN客户端并实现公网访问本地SVN Server
文章目录 前言1. TortoiseSVN 客户端下载安装2. 创建检出文件夹3. 创建与提交文件4. 公网访问测试 前言 TortoiseSVN是一个开源的版本控制系统,它与Apache Subversion(SVN)集成在一起,提供了一个用户友好的界面,方便用…...
League-Toolkit:3个核心功能解决英雄联盟玩家的日常痛点
League-Toolkit:3个核心功能解决英雄联盟玩家的日常痛点 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 还在为英雄联…...
手把手教你用STM32CubeMX配置LCD1602显示:HAL库驱动移植+Proteus 8.12仿真
STM32CubeMX与Proteus联合开发:LCD1602显示实战指南 在嵌入式开发领域,STM32CubeMX和Proteus的组合为开发者提供了从硬件配置到软件仿真的完整解决方案。本文将深入探讨如何利用这两个工具链实现LCD1602液晶显示屏的驱动与显示功能,特别针对从…...
LuatOS扩展库API——【airlbs 】airlbs 定位服务
LuatOS 是物联网终端开发的常用工具,为轻量级嵌入式 Lua 脚本运行框架兼实时系统,基于 Lua 5.3 深度优化,适配 4G-Cat.1、MCU 等物联网终端硬件。其以 Lua 脚本开发,采用协程多任务架构,配套完善开发资源,含…...
Java 新纪元 — JDK 25 + Spring Boot 4 全栈实战(十七):Boot 3 → Boot 4 迁移避坑指南——那些文档不会告诉你的迁移血泪史
系列导航 | ← 上一篇:D16 Spring Boot 4 + AI推理后端集成 | 下一篇:D18 云原生部署:Docker + K8s + GraalVM → 适用读者:正在从 Spring Boot 3.x 升级到 4.x 的开发者,或在评估升级可行性的架构师。 前置知识:熟悉 Spring Boot 3.x 开发,了解 JDK 21+ 基本特性。 本文…...
GEE实战:基于ERA5-Land小时数据批量计算与导出区域月极值气温
1. ERA5-Land数据与GEE平台基础 ERA5-Land是欧洲中期天气预报中心(ECMWF)推出的高分辨率地表再分析数据集,它提供了从1950年至今的逐小时全球气候数据。与ERA5相比,ERA5-Land的空间分辨率更高,达到0.10.1(约…...
NaViL-9B开源模型生态:HuggingFace模型卡+GitHub训练代码指引
NaViL-9B开源模型生态:HuggingFace模型卡GitHub训练代码指引 1. 平台简介 NaViL-9B是上海人工智能实验室发布的一款原生多模态大语言模型,支持纯文本问答和图片理解双重能力。作为开源社区的重要贡献,该模型已在HuggingFace平台发布模型卡&…...
ViGEmBus虚拟控制器驱动完全指南:从技术原理到场景落地的突破方案
ViGEmBus虚拟控制器驱动完全指南:从技术原理到场景落地的突破方案 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 价值定位:重新定义…...
火星探测器通信系统设计与关键技术解析
1. 火星探测器通信系统设计解析1.1 火星探测任务概述2021年5月15日,中国首次火星探测任务"天问一号"成功着陆火星北半球的乌托邦平原,标志着中国成为继前苏联和美国之后第三个成功实现火星软着陆的国家。此次任务中,"祝融号&q…...
Debian/Ubuntu 上 KVM 虚拟化环境搭建全攻略:从源码到实战
Debian/Ubuntu 上 KVM 虚拟化环境搭建全攻略:从源码到实战 在当今云计算和容器化技术蓬勃发展的时代,虚拟化技术依然是基础设施领域不可或缺的基石。KVM(Kernel-based Virtual Machine)作为Linux内核原生支持的虚拟化解决方案&…...
Qwen3-0.6B-FP8部署与Git工作流结合:AI代码审查助手
Qwen3-0.6B-FP8部署与Git工作流结合:AI代码审查助手 你有没有遇到过这种情况?团队里新来的小伙伴提交了一段代码,语法上挑不出大毛病,但总觉得逻辑有点绕,或者命名风格不太统一。你作为资深开发,想提点建议…...
