51单片机学习笔记8 中断系统及定时器

news2024/11/23 16:49:30

51单片机学习笔记8 中断系统及定时器

  • 一、中断的概念
  • 二、51单片机的中断
    • 1. 51单片机的中断源
    • 2. 中断的优先级
    • 3. 中断结构
    • 4. 外部中断解读
    • 5. 定时器中断
    • 6. 串口中断
  • 三、中断相关寄存器
    • 1. IE 中断允许寄存器
    • 2. TCON 中断请求标志
    • 3. IP 中断优先级
  • 四、中断号
  • 五、代码实现
    • 按键 :
    • LED:
    • 1. 按键事件切换LED亮的状态
      • key_utils.c
      • main.c
  • 六、定时/计数器结构
    • 1. 寄存器介绍
      • TMOD
      • TCON
    • 2. 定时器/计数器工作方式0
      • (1)工作特点
      • (2)门控位说明
      • (3)C/T
    • 3. 工作方式1
    • 4. 工作方式2
    • 5. 工作方式3
  • 七、定时器代码实现
    • 1. 定时器配置步骤
    • 2. 计时器初值计算
    • 3. 示例
      • `timer_utils.c`
      • main.c

在这里插入图片描述

一、中断的概念

中断是一种事件驱动的机制,允许单片机在执行程序的过程中暂时中断当前的任务,转而处理来自外部的优先级更高的事件。
当中断事件发生时,单片机会立即跳转到中断服务程序(ISR),执行相关的处理代码,然后返回到原来的程序继续执行。

二、51单片机的中断

1. 51单片机的中断源

51单片机中的中断源可以是外部硬件引脚的电平变化(外部中断),也可以是单片机内部的定时器/计数器溢出、串口接收等(内部中断)。

不同的51单片机中断源可能有所不同。一般51单片机至少有 5个中断:外部中断0、定时器0中断、外部中断1、定时器1中断、串口中断。

STC89C51RC/RD+ 的系列单片机提供了8个中断请求源,分别是:

  • 外部中断0
  • 定时器0 中断
  • 外部中断1
  • 定时器1 中断
  • 串口中断
  • 定时器2中断
  • 外部中断2
  • 外部中断3

在 中颖的SH79F6442中,提供了27个中断源,其中有5个外部中断、3个定时器中断,另外还有4个PCA中断、4个EUART中断、系统时钟监控中断、1个SPI中断、ADC中断、3路PWM中断、LED中断、TWI中断、CRC中断、LPD中断。

2. 中断的优先级

51单片机中,不同中断源之间存在优先级关系,当多个中断同时发生时,优先级高的中断会先得到响应。
可以通过设置中断优先级和中断允许位来控制不同中断源之间的优先级和允许状态。
下图是来自《STC89Cxx中文参考手册.pdf》 里的中断说明:在这里插入图片描述

3. 中断结构

下图也是摘自《STC89Cxx中文参考手册》,其结构
在这里插入图片描述
上图的解读,整体是以列的方式从左往右看,数据从最左侧是中断源,经过中断允许控制寄存器(开关),到中断优先级控制寄存器,再流向处理程序。

靠上的中断优先级更高。

4. 外部中断解读

  • INT0对应P3.2引脚
  • INT1对应P3.3引脚

中断信号传递流程:

  1. INT0 中断信号通过IT0(TCON控制寄存器第0位)引脚,来选择触发方式(0:低电平触发或 1:下降沿触发);
  2. 触发中断后,将IE0(TCON寄存器第1位,中断标志)置1;
  3. 判断EX0(IE中断允许寄存器第0位)如果是1,就是INT0使能,中断可以继续向后传递;
  4. 如果全局总中断EA(IE中断允许寄存器第7位)打开,中断可以继续传递;
  5. 中断优先级控制寄存器IP判断哪个中断先触发;
  6. 触发CPU的中断服务函数。

从上面的流程可以看出,IE.EX0即使失能状态,也可以通过TCON.IE0读取中断信号。

外部中断INT1对应P3.3引脚,工作流程与INT0类似。

5. 定时器中断

  • T0对应 P3.4引脚
  • T1对应 P3.5 引脚
  1. 有计数信号进入T0;
  2. 计数溢出时,触发 TF0(TCON计数器寄存器,TF0溢出中断标志);
  3. 如果ET0(IE中断第1位,T0的溢出中断允许位),继续传递;
  4. 如果全局总中断EA(IE中断允许寄存器第7位)打开,继续传递;
  5. 中断优先级控制器IP判断优先级;
  6. 触发CPU中断服务函数。

6. 串口中断

  • RX 对应 P3.0引脚
  • TX 对应 P3.1 引脚
  1. 当接收到数据或发送完成时,串口硬件会设置RI/TI标志位,表示接收到了数据;
  2. 如果 ES(IE寄存器的第4位,串行口中断允许位)被设置,允许串口中断继续传递;
  3. 如果全局总中断 EA(IE寄存器的第7位,全局中断允许位)被打开,则允许中断继续传递;
  4. 中断优先级控制器IP判断优先级;
  5. 触发中断服务函数;

三、中断相关寄存器

1. IE 中断允许寄存器

IE 地址为 A8H,格式如下:

编号作用
EA7全局中断允许位
6无效位,保留
ET25定时器/计数器2中断允许位
ES4串行口中断允许位
ET13定时器/计数器1中断允许位
EX12外部中断1允许位
ET01定时器/计数器0中断允许位
EX00外部中断0允许位

2. TCON 中断请求标志

编号作用
TF17定时器/计数器1溢出标志位
TR16定时器/计数器1运行控制位
TF05定时器/计数器0溢出标志位
TR04定时器/计数器0运行控制位
IE13外部中断1标志位
IT12外部中断1触发方式选择位
IE01外部中断0标志位
IT00外部中断0触发方式选择位

3. IP 中断优先级

编号作用
7无效位,保留
PT26定时器/计数器2中断优先级位
PS5串行口中断优先级位
PT14定时器/计数器1中断优先级位
PX13外部中断1优先级位
PT02定时器/计数器0中断优先级位
PX01外部中断0优先级位
0无效位,保留

这里对寄存器简单介绍,更详细地说明可以参考本文对应的开源代码里的《STC89Cxx中文参考手册》。

四、中断号

下面是关于中断号的说明:

中断号描述
0外部中断0
1定时器/计数器0 溢出中断
2外部中断1
3定时器/计数器1 溢出中断
4串行口通信中断
5定时器/计数器2 溢出中断
6-7保留

五、代码实现

硬件连接:

按键 :

在这里插入图片描述

LED:

在这里插入图片描述
其中按键3是在P3.2引脚,中断0。

1. 按键事件切换LED亮的状态

key_utils.c

#include "key_utils.h"
#include <reg52.h>
#include "common_utils.h"

sbit KEY3 = P3^2;
sbit LED1 = P2^0;

/**
 * @brief 按键中断初始化
 */
void key3_init(void){
    IT0 = 1; // 下降沿触发
    EX0 = 1; // 开启外部中断0
    EA  = 1;  // 开启总中断            

}
void exti0() interrupt 0{
    delay_10us(500);
    if(KEY3 == 0){
        LED1 = !LED1;
    }
}

main.c

#include <reg52.h>
#include "led_utils.h"
#include "common_utils.h"
#include "key_utils.h"
#include "types.h"

/**
* @brief 主函数
*/
main()
{
	// 关闭所有led
	led_all_off();
	key3_init();
	while(1)
	{
		
	}
}

六、定时/计数器结构

在这里插入图片描述

  • T0:P3.4
  • T1:P3.5 引脚
  • TMOD:定时器的工作模式
  • TCON:低4位控制外部中断,高4位用于定时器控制位

1. 寄存器介绍

TMOD

TMOD用于控制定时器/计数器的工作模式和计数方式,寄存器各位功能:

Bit:    7       6       5       4       3       2       1       0
      ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
      │ GATE │ C/T │ M1  │ M0  │ GATE │ C/T │ M1  │ M0  │
      └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
       T1    T1    T0    T0    T1    T1    T0    T0

TMOD 寄存器各位的功能
分成2组,高4位、低4位,分别控制定时器1、定时器0的工作模式。

  • 位7:GATE1(定时器1门控位):当 GATE1 为 1 时,定时器1的计数/定时工作由外部引脚控制。当 GATE1 为 0 时,定时器1的计数/定时工作受到内部控制。
  • 位6:C/T1(定时器1计数/定时选择位):当 C/T1 为 0 时,定时器1为定时器模式;当 C/T1 为 1 时,定时器1为计数器模式。
  • 位5-4:M11 和 M10(定时器1工作模式位):用于设置定时器1的工作模式,共有四种工作模式,分别为:
    • 00:13位定时器模式
    • 01:16位定时器模式
    • 10:8位自动重装载定时器模式
    • 11:两个8位定时器/计数器分开工作
  • 位3:GATE0(定时器0门控位):与位7相似,用于控制定时器0的门控功能。
  • 位2:C/T0(定时器0计数/定时选择位):与位6相似,用于设置定时器0的工作模式。
  • 位1-0:M01 和 M00(定时器0工作模式位):与位5-4相似,用于设置定时器0的工作模式。

TCON

TCON 用于控制定时器/计数器的工作状态和中断标志位,各位功能:

Bit:    7       6       5       4       3       2       1       0
      ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
      │  TF1 │ TR1 │  TF0 │ TR0 │ IE1 │ IT1 │ IE0 │ IT0 │
      └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘

TCON 寄存器各位的功能

  • 位7:TF1(定时器1溢出标志位):当定时器1溢出时,TF1 置1,表示定时器1计数达到最大值并溢出。如果不使用中断,也可以通过查询知道是否溢出。
  • 位6:TR1(定时器1运行控制位):当 TR1 置1 时,定时器1开始工作;当 TR1 清0 时,定时器1停止工作。
  • 位5:TF0(定时器0溢出标志位):当定时器0溢出时,TF0 置1,表示定时器0计数达到最大值并溢出。
  • 位4:TR0(定时器0运行控制位):当 TR0 置1 时,定时器0开始工作;当 TR0 清0 时,定时器0停止工作。
  • 位3:IE1(外部中断1标志位):外部中断1的中断标志位,当外部中断1触发时,IE1 置1。
  • 位2:IT1(外部中断1触发方式选择位):外部中断1的触发方式选择位,控制外部中断1的触发方式。
  • 位1:IE0(外部中断0标志位):外部中断0的中断标志位,当外部中断0触发时,IE0 置1。
  • 位0:IT0(外部中断0触发方式选择位):外部中断0的触发方式选择位,控制外部中断0的触发方式。

2. 定时器/计数器工作方式0

(1)工作特点

也称为13位定时器模式,结构图如下:
在这里插入图片描述
其特点是:

  • 定时器/计数器的计数范围为0到8191(2^13-1)。
  • 该模式下,定时器/计数器每计数一次,计数值加1,直到达到最大计数值(8191),然后溢出并重新从0开始计数。

计数由TL0的低5位和TH0的高8位组成,低5位溢出时向TH0进位,TH0 溢出时,TCON.TF0 置位。

(2)门控位说明

  • 门控位GATE是0的时候,经过一个非门、或门、与门,定时器可以由 TR0控制。
  • 当GATE是1的时候,定时器由INT0 引脚控制。

(3)C/T

控制计数还是定时模式,即开关:
在这里插入图片描述

3. 工作方式1

在这里插入图片描述

工作方式1称为16位定时器模式:

  • 定时器/计数器的计数范围为0到65535(2^16-1)。
  • 该模式下,定时器/计数器每计数一次,计数值加1,直到达到最大计数值(65535),然后溢出并重新从0开始计数。

4. 工作方式2

在这里插入图片描述

  • 也称为8位自动重装载定时器模式,定时器/计数器的计数范围为0到255(2^8-1)。
  • 该模式下,定时器/计数器每计数一次,计数值加1,当计数值达到最大值(255)时,自动重新加载初始计数值。
  • 自动重新装载,是将TH0装载到TL0。

5. 工作方式3

工作方式只适应用于T0,也称为两个8位定时器/计数器分开工作模式,其特点:

  • 两个8位定时器/计数器分开工作,分别为定时器0和定时器1,每个定时器/计数器的计数范围为0到255(2^8-1)。
  • 可以独立控制每个定时器/计数器的工作模式、计数方式和中断功能。

七、定时器代码实现

1. 定时器配置步骤

  1. 选择定时器
  2. 选择工作模式
  3. 设置定时器初值
  4. 选择时钟源
  5. 中断使能
  6. TR0或TR1置位,启动定时器
  7. 中断处理

2. 计时器初值计算

使用开源仓库里的51定时器计算工具计算,晶震频率根据开发板实际频率填写。
在这里插入图片描述

3. 示例

本示例每秒LED闪烁一次:

timer_utils.c

#include "timer_utils.h"
#include <reg51.h>
#include "types.h"

sbit LED1 = P2^0;

/**
* @brief 定时器 0 初始化函数
*/
void timer1_init(void){
    // 选择为定时器 0 模式,工作方式 1
    TMOD |= 0X01;
    // 给定时器赋初值,定时 1ms
    TH0 = 0XFC;
    TL0 = 0X66;
    // 打开定时器 0 中断允许
    ET0 = 1;
    // 打开总中断
    EA = 1;
    // 打开定时器
    TR0 = 1;
}
// 定义静态变量 i
static u16 i;

/**
* @brief 定时器 0 中断函数
*/
void timer1() interrupt 1 
{
	// 定时器重新赋初值,定时 1ms
    TH0 = 0XFC;     
    TL0 = 0X66; 
    i++;
    if(i == 1000)
    {
        i =0 ;
        LED1 = !LED1;
    }
}


main.c

#include <reg52.h>
#include "led_utils.h"
#include "common_utils.h"
#include "types.h"
#include "timer_utils.h"

/**
* @brief 主函数
*/
main()
{
	// 关闭所有led
	led_all_off();
	time0_init();
	while(1)
	{
		
	}
}

本文开源地址:
https://gitee.com/xundh/learn51

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

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

相关文章

如何实现跨标签页通讯

什么是跨标签页通讯 同一浏览器&#xff0c;可以打开多个标签页&#xff0c;跨标签页通讯就是&#xff0c;一个标签页能够发消息给另一标签页。 有哪些实现方案 localStorage &#xff08;window.onstorage事件监听&#xff09;BroadcastChannel&#xff08;广播&#xff09…

Redis如何设置键的生存时间或过期时间

键的生存时间或过期时间 概述。 通过EXPIRE命令或者PEXIPIRE命令&#xff0c;客户端可以以秒或者毫秒精度为数据库中的某个键设置生存时间(Time To Live,TTL)&#xff0c;在经过指定的秒数或者毫秒数之后&#xff0c;服务器就会自动删除生存时间为0的键: 127.0.0.1:6379>…

Python零基础---爬虫技术相关

python 爬虫技术&#xff0c;关于数据相关的拆解&#xff1a; 1.对页面结构的拆解 2.数据包的分析&#xff08;是否加密了参数&#xff09;&#xff08;Md5 aes&#xff09;难易程度&#xff0c;价格 3.对接客户(433,334) # 数据库 CSV 4.结单&#xff08;发一部分数据&a…

酷开系统满足你的需求,加入酷开会员开启娱乐之旅

酷开科技深知家庭娱乐在我们生活中的重要性&#xff0c;因此&#xff0c;酷开科技不断努力为我们带来更好的内容和服务&#xff0c;在这里&#xff0c;我们能够享受到家庭娱乐的乐趣和便利&#xff0c;感受到酷开科技带来的温暖。电影迷、游戏迷还是音乐爱好者&#xff0c;酷开…

1236 - 二分查找

代码 #include<bits/stdc.h> using namespace std; int a[1100000]; int main() {int n,x,l,r,p,mid,i;cin>>n;for(i1;i<n;i)cin>>a[i];cin>>x;l1;rn;p-1;while(l<r){mid(rl)/2;if(a[mid]x){pmid;break;}else if(x<a[mid]) rmid-1;else if(x…

k8s为什么删除了pod但是还是没删除掉的问题,deployment在影响

deployment 影响pod删除 一、问题所在二、解决问题 一、问题所在 执行&#xff1a;kubectl get pods --all-namespaces&#xff0c;获取dashboard相关的pod kubectl get pods --all-namespaces | grep dashboardkubectl delete pod dashboard-metrics-scraper-546d6779cb-4x6…

备战秋招(coding篇)

其中coding题目来源于师兄面试经验 1、链表的结构体反转链表 本质上就是一个构造函数 struct ListNode{int val_;ListNode* next_;ListNode() : val_(0), next_(NULL) {}ListNode(int x) : val_(x), next_(NULL) {}ListNode(int x, ListNode* next) : val_(x), next_(next) …

【Spring Cloud】微服务通信概述

SueWakeup 个人主页&#xff1a;SueWakeup 系列专栏&#xff1a;学习技术栈 个性签名&#xff1a;人生乏味啊&#xff0c;我欲令之光怪陆离 本文封面由 凯楠&#x1f4f7; 友情赞助播出 目录 前言 1. Dubbo&#xff08;Spring Cloud Alibaba&#xff09;和 Spring Cloud 的适…

使用ollama + webui 运行任意大模型

安装ollama https://hub.docker.com/r/ollama/ollama docker run -d -v ~/Documents/work/softs/docker/ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama验证安装 # 进入容器docker exec -it ollama bash # 运行大模型 ollama run llama2 # 发送请求&…

【python + Django】Django模板语法 + 请求和响应

前言&#xff1a; 现在现在&#xff0c;我们要开始将变量的值展现在页面上面啦&#xff01; 要是只会显示静态页面&#xff0c;我们的页面也太难看和死板了&#xff0c; 并且数据库的数据也没法展现在页面上。 但是呢&#xff0c;模板语法学习之后就可以啦&#xff01;&…

笔记本8代i5和台式机12代i5的性能比较

一、 台式机12代i5 二、笔记本8代i5 在多核性能上差不多是2.4倍&#xff0c;所以跑大一点的Matlab或者别的程序&#xff0c;用台式机&#xff0c;后边实验室能用上超多核服务器另说。

【Flutter】文件选择器(file_picker)的用法

Flutter 没有提供内置的文件选择器&#xff0c;但社区内有人贡献了一个比较完整的解决方案——file_picker。 file_picker 的 API 简洁易用&#xff0c;支持全平台&#xff08;Android / iOS / Mac / Linux / Windows&#xff09;&#xff0c;是我开发桌面应用时的首选。 这边…

IDEA中快速配置Git

Git介绍&#xff1a; Git下载 idea中配置Git

蓝桥杯单片机快速开发笔记——串口通信

一、原理分析 二、思维导图 三、示例框架 #include <STC15F2K60S2.H> #include "HC573.h"void UartInit(void) //9600bps12.000MHz {SCON 0x50; //8位数据,可变波特率AUXR | 0x01; //串口1选择定时器2为波特率发生器AUXR & 0xFB; //定时器时钟12T模式…

流畅的 Python 第二版(GPT 重译)(六)

第三部分&#xff1a;类和协议 第十一章&#xff1a;一个 Python 风格的对象 使库或框架成为 Pythonic 是为了让 Python 程序员尽可能轻松和自然地学会如何执行任务。 Python 和 JavaScript 框架的创造者 Martijn Faassen。 由于 Python 数据模型&#xff0c;您定义的类型可以…

【Linux】进程通信

目录 一、管道通信 二、共享内存 三、消息队列 一、管道通信 管道是由操作系统维护的一个文件&#xff0c;管道通信的本质就是将管道文件作为临界资源&#xff0c;实现不同进程之间的数据读写&#xff0c;但是管道只允许父子进程或者兄弟进程之间的通信。 管道文件本身是全…

数据结构从入门到精通——堆排序

堆排序 前言一、堆排序的基本思想二、堆排序的特性总结三、堆排序的动图展示四、堆排序的代码实现向上建堆test.c 前言 堆排序是一种利用堆数据结构实现的排序算法。首先&#xff0c;它将待排序的数组构建成一个大顶堆或小顶堆。然后&#xff0c;通过不断将堆顶元素&#xff0…

MC10T1S-10BASE-T1S车载以太网转换器

10BASE-T1S车载以太网转换器 为10BASE-T1S车载以太网转换器&#xff0c;支持Multidrop bus line和Point-to-Point。采用的DB9接口类型&#xff0c;支持PLCA。10BASE-T1S是IEEE 802.3cg标准制定的IEEE汽车以太网的最新标准之一&#xff0c;采用UTP这样的一对无屏蔽的双芯电缆进行…

Uibot (RPA设计软件)财务会计Web应用自动化(批量开票机器人)

Uibot (RPA设计软件&#xff09;Mage AI智能识别&#xff08;发票识别&#xff09;———机器人的小项目友友们可以参考小北的课前材料五博客~ (本博客中会有部分课程ppt截屏,如有侵权请及请及时与小北我取得联系~&#xff09; 紧接着小北的前两篇博客&#xff0c;友友们我们…

webpack5零基础入门-13生产模式

1.生产模式介绍 生产模式是开发完成代码后&#xff0c;我们需要得到代码将来部署上线。 这个模式下我们主要对代码进行优化&#xff0c;让其运行性能更好。 优化主要从两个角度出发: 优化代码运行性能优化代码打包速度 2.生产模式准备 我们分别准备两个配置文件来放不同的…