1. 51——中断、定时器 / 计数器

本文详细介绍了51单片机的中断系统,包括中断概念、中断作用、中断源及相关寄存器。同时,深入探讨了定时器/计数器的工作原理、结构、模式和配置步骤,并给出了配置示例。此外,还讲解了外部中断INT0/INT1的操作流程和中断服务函数。通过这些内容,读者将能掌握51单片机中断和定时器/计数器的使用方法。
摘要由CSDN通过智能技术生成

中断系统

中断概念

CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生),那么CPU就会暂停当前的工作(A事件),去执行B事件(中断响应和中断服务),然后B事件做完之后,再回到原来的事件(A事件)中继续工作。(中断的返回)。

在这里插入图片描述

中断作用

随着计算机技术的应用,人们发现中断技术不仅解决了快速主机与I/O设备的数据传送问题,而且还有具有如下的优点:

  1. 分时操作:CPU可以分时为多个I/O设备服务,提高了计算机的利用率。
  2. 实时操作:CPU能够及时处理应用系统的随机事件,系统的实时性大大增强。
  3. 可靠性高:CPU具有处理设备故障及掉电等突发性事件能力,从而使系统可靠性更高。

中断源及相关寄存器

中断源及优先级

在这里插入图片描述
在这里插入图片描述

中断允许寄存器 IE

在这里插入图片描述

EA: 总中断允许。 EA=0;CPU屏蔽所有中断的请求 EA=1;开放所有中断。
ES:串行口中断允许位。ES=0; 禁止串行中断。ES=1; 允许串口中断。
ET0、ET1: 定时器/计数器0 和 定时器/计数器 1 中断允许位 =0时 禁止相应的定时器中断。 =1 允许相应的定时器中断。
EX0、EX1: 外部中断0 和 外部中断1 中断允许位。=0时 禁止相应的外部中断。 =1时 允许相应的外部中断。
——:无效位

中断优先级控制寄存器 IP/XICON 和 IPH

在这里插入图片描述

定时器/计数器

概念

51单片机有两组定时器/计数器,因为既可以定时,又可以计数,故称之为定时器/计数器。

定时器/计数器和单片机的CPU是相互独立的。定时器/计数器工作的过程是自动完成的,不需要CPU的参与。

51单片机中的定时器/计数器是根据机器内部的时钟或者是外部的脉冲信号对寄存器中的数据加1。

有了定时器/计数器之后,可以增加单片机的效率,一些简单的重复加1的工作可以交给定时器/计数器处理。CPU转而处理一些复杂的事情。同时可以实现精确定时作用。

工作原理

实质上是加1计数器,随着输入脉冲,计数器自动加1,
溢出的时候会回0,且计数器的溢出使相应的中断标志位 置1。
向CPU发出中断请求。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。
可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值。

定时器结构

定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器THx和TLx组成。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。

在这里插入图片描述

定时器/计数器工作模式寄存器TMOD

在这里插入图片描述

在这里插入图片描述

模式0(13位定时器/计数器)

方式0为13位计数,由TL0的低5位(高3位未用)和TH0的8位组成。TL0的低5位溢出时向TH0进位,TH0溢出时,置位TCON中的TF0标志,向CPU发出中断请求

模式1(16位定时器/计数器)

方式1的计数位数是16位,由TL0作为低8位,TH0作为高8位,组成了16位加1计数器

模式2(8位自动重装模式)

方式2为自动重装初值的8位计数方式。

模式3(两个8位计数器)

方式3只适用于定时/计数器T0,定时器T1处于方式3时相当于TR1=0,停止计数。

定时器/计数器控制寄存器 TCON

在这里插入图片描述
TF0、 TF1: 定时器中断标志(定时器0溢出标志位、定时器1溢出标志位)T0 / T1被允许计数以后,从初值开始加1计数,当最高位产生溢出时,由硬件置“1”TF0 / TF1,向CPU请求中断,一直保持CPU响应该中断时,才由硬件清“0”TF0 / TF1( TF0 / TF1也可由程序查询清“0”)。
TR0 、TR1: 打开相应的定时器(定时器0运行控制位,=1时启动定时器0、定时器1运行控制位,=1时启动定时器1)
由软件清0关闭定时器0/1。当GATE=1,且INIT为高电平时,TR1置1启动定时器1;当GATE=0时,TR1置1启动定时器0/1。
IT0、IT1: 是外部中断的触发方式。 =0时 低电平触发,=1时下降沿触发。
IE0、IE1: 是外部中断的标志位。

定时器初值寄存器 THx 和 TLx

首先先了解一下CPU时序有关知识:
振荡周期: 为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期)
状态周期:2个振荡周期为1个状态周期,用S表示。振荡周期又称S周期或时钟周期。
机器周期:1个机器周期含6个状态周期,12个振荡周期。
指令周期:完成1条指令所占用的全部时间,它以机器周期为单位。

例如:外接晶振为12MHz时,51单片机相关周期的具体值为:
振荡周期=1/12us;
状态周期=1/6us;
机器周期=1us;
指令周期=1~4us;

计数器初值的计算:

机器周期就是CPU完成一个基本操作所需要得时间。
机器周期 = 1 /单片机的时钟频率
51单片机内部时钟频率是外部时钟的12分频,也就是当外部晶振的频率输入到单片机里面
的时候要进行12分频。

比如:你用的是12MHZ的晶振,当你使用12MHZ的外部晶振的时候,
机器周期 = 1 / 1M = 1us。(选择定时器工作方式1 16位)
我们2的16次方等于65536,也就是最大值为65536(溢出)
如果定时1ms
初值就为:1ms / 1us = 1000。也就是要计数1000个数, 初值 = 65535-1000+1 = 645356,65536才会溢出。 所以初值即FC18H(十进制为64536),从64535数到65536,1000个数,1000us=1ms

再比如:用的时候11.0592MHz的晶振。
一个机器周期 = 1 / = 11059200Hz = 0.0904*10^(-6)s = 0.0904us。(选择定时器工作方式1 16位)

12个机器周期用时 = 12 * 0.0904us = 1.085 us

我们2的16次方等于65536,也就是最大值为65536(溢出)
如果定时10ms

10000 us / 1.085 us = 9216.589861751152 次

初值就为:65536 - 9216 = 56,320 = DC00 (HEX)

定时器从 56320 数到 65536 为 10 ms

TH0 = 64536/256 //十六位配置高八位
TL0  = 64536%256; //十六位配置低八位

如果定时50ms
50ms/1us=50000;
初值 = 65535-50000+1=15536;
定时为50ms 初值为15536 即3CB0(十六进制)

用一个软件来计算比较快

在这里插入图片描述

配置 定时器 / 计数器 操作步骤(T0 T1)

  1. 选择工作方式。设置M1、M0 (TMOD寄存器)
  2. 选择控制方式。设置GATE(TMOD寄存器)
  3. 选择定时器还是计数器模式。设置C/T(TMOD寄存器)
  4. 给定时/计数器赋初值。设置THx 和 TLx(定时器初值寄存器)
  5. 开启总中断。设置EA(IE寄存器)
  6. 打开相应定时器中断允许。 设置ET0或ET1(IE寄存器)
  7. 关闭或开启中断标志位(TF0或TF1)
  8. 启动定时器。设置TR1或TR0(TCON寄存器)
  9. 配置中断优先级

配置 定时器 / 计数器 示例

这里就选择定时器0吧 选择方式1(16位)进行定时示例吧

  1. 选择工作方式1(16位)M1=0;M0=1;
  2. 控制方式 :仅有运行控制位TRx来控制定时/计数器的开启。GATE=0;
  3. 选择定时器模式 C/T=0;
TMOD=0x01; //不可位寻址 只能16位全配 0000 0001
  1. 赋初值 这里选择定时为1ms 我的板子晶振是11.0592,推荐用软件mcuelf计算出以下结果
TH0 = 64536/256 //十六位配置高八位
TL0  = 64536%256; //十六位配置低八位

在这里插入图片描述

  1. 打开总中断(总开关)
EA=1;
  1. 打开T0中断开关
ET0=1;
  1. 关闭或开启中断标志位
TF0 = 0; //关闭中断标志位,防止产生中断
  1. 启动定时器0
TR0=1;
  1. 配置中断优先级

定时器函数

void Timer0_Init()
{
		TMOD = 0x01; //模式二 16位定时器 / 计数器
		TF0  = 0; //关闭中断溢出标志,防止产生中断
		TR0  = 1; //开启T0定时器
		TH0  = 64535/256; //配置高8位
		TL0  = 64535%256; //配置低8位
		EA   = 1; //开启总中断
		ET0  = 1; //开启T0中断
		PT0  = 1; //配置优先级
}

中断服务函数

void Timer0_Rountine() interrupt 1
{
		static unsigned int T0Count;
		
		TH0  = 64535/256; //防止定时器从0开始数到65536
		TL0  = 64535%256; //防止定时器从0开始数到65536
		
		T0Count++;
		
		if( T0Count >= 5000 ) //实现通电5s后开始亮灯 1ms*1000=1s 1s*5=5s
		{
				LED = 0; //开灯
				Delay500ms(); //延迟500ms
				LED = 1; //关灯
				Delay500ms(); //延迟500ms
		}
}

效果

在这里插入图片描述

外部中断

INT0 / INT1 操作步骤

  1. 设置 外部中断中断源号及触发方式。设置IT0或IT1(TCON寄存器)
  2. 打开相应的外部中断允许。设置EX0或EX1(IE寄存器)
  3. 打开总中断。设置EA(IE寄存器)

配置外部中断0(INT0)

void init()
{
		EA  = 1; //开启总中断
		EX0 = 1; //开启EX0的外部中断
		IT0 = 1; //下降沿触发	
}

中断服务函数(发生中断你想做什么?)

无返回值 函数名(随意起) interrupt 中断号
void interrupt0ServiceFun() interrupt 0
{
	//编写你要做的事情
}

程序示例

#include "regx52.h"
#include "intrins.h"
#include "Timer0.h"

sbit LED   = P1^0;
sbit SHAKE = P1^1;

void Delay500ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 4;
	j = 129;
	k = 119;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void init()
{
		EA  = 1; //开启总中断
		EX0 = 1; //开启EX0的外部中断
		IT0 = 1; //下降沿触发
		
}

void main()
{
		Timer0_Init();
		
		while(1)
		{
				
		}
}

void init0() interrupt 0
{
		LED = 0; //开灯
		Delay500ms(); //延迟500ms
		LED = 1; //关灯
		Delay500ms(); //延迟500ms
}

  • 7
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值