历史上的今天
返回首页

历史上的今天

今天是:2025年05月18日(星期日)

正在发生

2020年05月18日 | 51单片机的中断和定时器、计数器

2020-05-18 来源:eefocus

中断使得高低速设备可以协调工作(低速设备完成工作后通过中断的方式通知高速设备一次处理一批数据),中断还可以根据不同的优先级实现嵌套执行。

定时器本质上是个 16 位的自增计数器,当发生溢出时,如果开启了溢出中断,单片机会自动向 CPU 报告这个溢出中断,处理相应的中断任务。

寄存器

TCON 定时器控制寄存器

TCON 的低 4 位用作外部中断,高 4 位用作定时控制。地址是 88H。

TCON 定时器控制寄存器各个位的意义如下:

所在位 bit76543210
名称TF1TR1TF0TR0IE1IT1IE0IT0
  • IT0:外部中断0触发方式。1为低电平触发,0为下降沿触发。

  • IE0:外部中断0请求标志位。IE0=1 时表示有中断请求,0则没有。

  • IT1:外部中断1触发方式。1为低电平,0为下降沿信号。

  • IE1:外部中断1请求标志位。IE0=1 时表示有中断请求,0则没有。

  • TR0:定时器/计数器0启动停止控制位。1为启动,0为停止。

  • TF0:定时器/计数器0溢出标志位。1表示发生溢出,如果开启了中断,则会触发中断。

  • TR1:定时器/计数器1启动停止控制位。1为启动,0为停止。

  • TF1:定时器/计数器1溢出标志位。1表示发生溢出,如果开启了中断,则会触发中断。

IE 中断允许控制寄存器

CPU 对中断源的开启或屏蔽的控制,是通过 IE 寄存器来设置的,IE 既可按字节地址寻址(其字节地址为 A8H),又可按位寻址。某个中断对应的位设为 1 则表示允许中断,否则禁止。

IE 寄存器各个位的意义

IE 中断允许控制寄存器各个位的意义如下:

所在位 bit76543210
名称EA-ET2ESET1EX1ET0EX0
  • EX0:外部中断 0 中断允许位

  • ET0:定时器/计数器 0 中断允许位

  • EX1:外部中断 1 中断允许位

  • ET1:定时器/计数器 1 中断允许位

  • ES:串口中断允许位

  • ET2:定时器/计数器 2 中断允许位(进行52系列)

  • EA:中断总开关

定时器工作在中断方式时,当定时器的值计满溢出时,会触发定时器溢出中断。

C 语言示例

只要想使用中断,就必须开启 EA 总中断。例如,如果想使用定时器/计数器0,需要添加下面一段 Keil C51 代码来开启 EA 和 ET0:


EA = 1; // 开启总中断

ET0 = 1; // 开启定时器/计数器0 中断


或者使用字节操作:


IE |= 0x82; // 设置 IE 寄存器为 10000010,即开启总中断和定时器/计数器0中断


汇编语言示例

如果使用汇编语言,开启外部中断 0 的汇编代码,字节操作为:


MOV IE,#81H

;MOV 0A8H,#81H; 这里也可以直接使用 IE 寄存器的地址 A8H


或者使用汇编语言的位操作:


SETB EA

SETB EX0 

TMOD 定时器工作模式寄存器

TMOD 用于控制定时器的工作模式,低4位用于 T0,高4位用于 T1。各个位的意义如下:

所在位 bit76543210
名称GATEC/TM1M0GATEC/TM1M0
  • M0 与 M1:共 4 中组合,对应定时器的 4 中工作模式

    • M1 = 0,M0 = 0:模式0,13 位,最大计数范围 8192。TL 的低 5 位和 TH 的高 8 位组成 13 位计数器,用于兼容 48 系列一般不用。

    • M1 = 0,M0 = 1:模式1,16 位,最大计数范围 65536

    • M1 = 1,M0 = 0:模式2,8 位,最大计数范围 256。高 8 位放预置数,只有低 8 位参与计数。计数溢出后可以自动重新装填预置数,定时精度高。可以用于波特率发生器等精确计时场合。

    • M1 = 1,M0 = 1:模式3,8 位,最大计数范围 256。此时 T0 被拆成 2 个独立的定时/计数器。其中 TL0 可以用作 8 位的定时/计数器,TH0 只能用于定时器。TH0 的控制及溢出标志借用 T1 的。一般仅当 T1 工作在模式 2 时,才会让 T0 工作在模式 3。

  • C/T:设置为 0 则作为定时器使用,设置为 1 则成为计数器

  • GATE:计数脉冲与定时/计数器之间的开关。

    • GATE = 0 时,开关仅由 TR0 控制,TR0 = 1 时计数脉冲可以通过,否则无法通过

    • GATE = 1 时,开关由 TR0 和 INT0 同时控制,仅在 TR0 = 1 且 INT0 高电平时,计数脉冲才可以通过

IP 中断优先级控制寄存器

所在位 bit76543210
名称--PT2PSPT1PX1PT0PX0

SCON 串行口控制寄存器

所在位 bit76543210
名称SM0SM1SM2RENTB8RB8TIRI
  • SM0 和 SM1:串行口方式选择

SM0SM1方式说明波特率
0008位数据发送fosc/12
01110位数据发送,包括起始位,停止位可变
10211位数据发送,包括起始位,停止位 ,校验位fosc/64
113同方式2
  • SM2:多机通信使能位。在方式2或方式3中,若SM2=1,则只有当接收到的第9位数据(RB8)为1时,才能将接收到的数据送入SBUF,并使接收中断标志RI置位向CPU申请中断,否则数据丢失;若SM2=0,则不论接收到的第9位数据为1还是为0,都将会把前8位数据装入SBUF中,并使接收中断标志RI置位向CPU申请中断。在方式1,如SM2=1,则只有收到有效的停止位时才会使RI置位。在方式0时,SM2必须为0。

  • REN:串口数据接收允许位,1允许,0禁止

  • TB8:在方式2和方式3中,这位发送的是第9位。在多机通信中,常以该位的状态来表示主机发送的是地址还是数据。通常规定:TB8为“0”表示主机发送的是数据,为“1”表示发送的是地址。

  • RB8:在方式2和方式3中,这位发送的是第9位。它和SM2、TB8一起用于通信控制。

  • TI:发送中断标志位 ,用完时要用软件清0

  • RI:接受中断标志位,用完时要用软件清0

中断

中断源

51单片机有5个中断源,5个中断源分别是:

  • 外部中断0,从 P3.2 端口复用

  • 外部中断1,从 P3.3 端口复用

  • 定时/计数器0溢出中断

  • 定时/计数器1溢出中断

  • 串口发送或接收中断

中断可以根据优先级实现嵌套,51 系列可以实现 2 级嵌套(对应优先级寄存器 IP),52 系列可以实现 4 级嵌套(对应优先级寄存器 IP 和 IPH)。

中断对应信息

中断名称中断标志位中断号默认优先级中断入口地址
外部中断0IE000003H
定时/计数器0溢出中断TF02000BH
外部中断1IE110013H
定时/计数器1溢出中断TF13001BH
串口发送或接收中断RI/TI40023H

中断处理流程

  1. 停止主程序运行

  2. 保护断点,把程序计数器 PC 的值压入堆栈

  3. 寻找中断入口,每个中断都有不同的程序入口

  4. 执行中断处理程序

  5. 中断返回,继续执行主程序

中断的使用

任何中断的使用都要满足 3 个条件:

  • 开启总开关:EA EX = 1

  • 开启指定中断的开关,例如要使用外部中断0,则必须设置:EX0=1

  • 发生中断事件

中断系统有一个总的开关 EA(IE 寄存器中),如果想使用中断,必须打开总开关。

每个中断都有一个单独的开关,这些单独的开关跟总开关 EA 一样,都在 IE 寄存器中。

定时器中断使用

初始值的计算

假设我要每计数 24 次触发一次溢出中断,定时器工作在模式 1,则计数初始值为 65536 - 24 = 65512。

Keil C51 代码

外部中断示例代码

下面代码使用了外部中断0,上电后 P1 端口 0 号引脚的 LED 会一直闪烁,首次触发外部中断时,P1 端口所有 LED 点亮,再次触发外部中断时,0号引脚的 LED 再次开始闪烁,以此循环:


#include

 

int flag = 1;

void delay() {

unsigned int a = 50000;

while(a--);

}

 

void main() {

EA = 1;// 开启中断总开关

IT0 = 1;// 设置外部中断0触发方式,下降沿触发

EX0 = 1;// 开启外部中断0

while(1) {

while(flag & 0x01 == 1) {

P1 = 0xfe;

delay();

P1 = 0xff;

delay();

}

P1 = 0x00;

}

}

 

void externelInterrupt() interrupt 0 {

flag++;

}


电路图:
在这里插入图片描述

串口示例代码

/*9600@11.0592M*/

#include

void InitUART(void) {

TMOD = 0x20;

SCON = 0x50;

TH1 = 0xFD;

TL1 = TH1;

PCON = 0x00;

EA = 1;

ES = 1;

TR1 = 1;

}

void SendOneByte(unsigned char c) {

SBUF = c;

while(!TI);

TI = 0;

}

void main(void) {

InitUART();

}

void UARTInterrupt(void) interrupt 4 {

if(RI) {

RI = 0;

} else

TI = 0;

}


推荐阅读

史海拾趣

Equator Technologies公司的发展小趣事

在XX年代中期,Equator迎来了一个重要的转折点——被Pixelworks公司收购。Pixelworks是一家在显示图像处理领域具有领先地位的公司,其产品线广泛,包括用于各种显示设备的图像处理芯片和软件。与Pixelworks的合并使Equator获得了更广阔的市场和资源支持,加速了其技术和产品的发展。合并后,Equator继续专注于视频处理技术的研发,并与Pixelworks共同推出了多款创新产品。

Helium公司的发展小趣事

2017年,随着区块链技术的兴起,Helium团队看到了新的机遇。他们意识到区块链的透明性和自确认性可以为物联网网络的建设带来革命性变化。于是,Helium决定将网络建设“去中心化”,并借助区块链技术重新定义激励机制。这一决策标志着Helium从单纯的物联网项目转变为融合区块链技术的创新企业。通过去中心化的方式,Helium降低了网络建设和维护的成本,加速了网络覆盖的速度,为物联网设备提供了更加便捷和经济的连接方案。

Fluke公司的发展小趣事

随着Helium商业模式的成功实施,其热点数量迅速增长。据数据显示,Helium的热点数量从最初的少数几个发展到数十万乃至数百万个,覆盖了全球169个国家和地区。这一成就不仅彰显了Helium在物联网领域的领先地位,也为其带来了巨大的市场影响力和商业价值。通过广泛的网络覆盖,Helium为物联网设备提供了稳定、可靠的连接服务,促进了物联网技术的普及和应用。

DIOTECH公司的发展小趣事

为了进一步提升市场份额和品牌影响力,DIOTECH公司开始加大市场拓展力度。通过参加国际电子展会、举办新品发布会等活动,公司成功吸引了全球范围内的客户和合作伙伴的关注。同时,公司还加强了品牌建设,通过一系列营销活动提升了品牌知名度和美誉度。这些努力使得DIOTECH逐渐成为了电子行业内的知名品牌。

Emerging Display Technolgies公司的发展小趣事

随着虚拟现实(VR)、增强现实(AR)等技术的快速发展,微型显示技术的需求日益增加。一家新兴显示技术公司,凭借其在微纳加工和光学设计方面的技术优势,成功研发出了高性能的微型显示屏。这种显示屏具有体积小、分辨率高、功耗低等特点,为VR/AR设备提供了更加逼真的视觉体验。

CTS公司的发展小趣事

在业务发展过程中,CTS公司还通过一系列收购来扩展其业务范围和增强竞争力。例如,CTS完成了对Alpha Ceramics的收购,这是一家为军事和航空航天市场提供传感器和换能器制造商的压电陶瓷材料供应商。这一收购使CTS能够进一步增强其在特定领域的专业能力,并为客户提供更全面的解决方案。

问答坊 | AI 解惑

菜鸟求程序下载软件

各位大虾, 用KEIL能不能下载程序?  不能的话给我介绍一个。。感激涕零。。…

查看全部问答>

逆变器综合设计大全

本帖最后由 paulhyde 于 2014-9-15 09:19 编辑 涵盖  …

查看全部问答>

求救,关于WINCE下的触摸屏驱动

     最近在调试触摸屏驱动,但遇到了一个奇怪的问题,问题描述如下:      开机后,可以实现触摸功能,也可以实现校准功能。但是,除最顶栏处的菜单栏和最低处的任务栏,其他地方均可以正常点击,这两处 ...…

查看全部问答>

arm7和PIC 单片机 应从哪块 具有代表性的单片机学起?

arm7和PIC 单片机 应从哪块 具有代表性的单片机学起?顺便请推荐这两款单片机学习的好书籍,谢谢!!…

查看全部问答>

bthcsr.dll库的调用问题

请问一下,bthcsr.dll库通常是在系统启动的哪个阶段调用啊?它是不是在serial驱动加载前就加载了呢?谢谢。…

查看全部问答>

求高手点拨:ARMulator 中如何使用定时器?

求高手点拨:ARMulator 中如何使用定时器?   我按照《ADS_DEBUGTARGETGUIDE_D.PDF》写了 Timer1 的初始化函数,但是不知道怎样关联中断处理函数了。请高手点拨,呵呵: #define CLK          & ...…

查看全部问答>

期待Cortex-M3核出带LCD控制器的型号

                                 如题,像ARM7一样,Cortex-M3核何时才能见到带LCD控制器的MCU型号呢。…

查看全部问答>

路由的转发怎么不行啊

我用AF_DataRequest函数发送数据,用IEEE地址进行单播,协调器给他下一层的节点可以发送数据,但是在下一层的节点就收不到数据了。radius是AF_DEFAULT_RADIUS,options一开始用0,后来改为AF_DISCV_ROUTE、AF_DISCV_ROUTE | AF_SKIP_ROUTING,都不 ...…

查看全部问答>