51单片机入门-2-中断与定时

51单片机入门-2-中断与定时



前言

自学笔记,没有历史知识铺垫(省略百度部分)了解51单片机的中断与定时


一、中断基础

1.中断同级优先级

在这里插入图片描述

2.中断条件

  1. 中断源: 有段请求(如INT0#/INT1#/T0/T1/代码请求等)
  2. 中断源中断允许位: 1 (相当于子开关,如EX0/EX1/ET0/ET1/ES/EADC/ELVD等)
  3. CPU开启中断 EA位:1 (相当于总开关)

3.中断程序执行原理图

在这里插入图片描述

低优先级中断可以被高优先级打断
高优先级中断不能被低优先级中断打断

4.定时器计数与时间换算公式

t=(1/晶振频率)x(一个机器周期晶振震荡周期)x(定时器数值)
其中一个机器周期晶振震荡周期为12
定时器数值意思为定时器需要运行的数值,注意定时器16位最大记录65536

晶振频率选用12MHz
则每次计数时间约为(1/12000000)*12*1=0.000001秒即1微秒,
要使计数时间为1ms,则定时器数值位0.001/(1/12000000)*12=1000,则计数初始值为65535-1000
要使计数时间为10ms,则定时器数值位0.01/(1/12000000)*12=10000,则计数初始值为65535-10000
要使计数时间为50ms,则定时器数值位0.05/(1/12000000)*12=50000,则计数初始值为65535-50000
当晶振频率选用11.0592MHz
则每次计数时间约为(1/11059200)*12*1=0.000001085秒即1.085微秒,
要使计数时间为1ms,则定时器数值位0.001/(1/11059200)*12=922,则计数初始值为65535-922
要使计数时间为10ms,则定时器数值位0.01/(1/11059200)*12=9216,则计数初始值为65535-9216
要使计数时间为50ms,则定时器数值位0.05/(1/11059200)*12=46080,则计数初始值为65535-46080

二、中断相关寄存器

针对于TMOD/IE等名词,并不是针对单片机的引脚,而是单片机中特殊寄存器的命名规则
官方文档93页

1.中断相关寄存器列表

  1. IE 中断允许寄存器(可寻址)
  2. IE2 中断允许寄存器2(不可寻址)
  3. IP 中断优先级控制寄存器(可寻址)
  4. TCON 定时器控制寄存器(可寻址)
  5. TMOD 工作方式控制寄存器 (不可寻址)
  6. T2MOD 工作方式控制寄存器 (不可寻址)
  7. SCON 串行口控制寄存器(可寻址)
  8. PSW 程序状态字(可寻址)
  9. PCON 电源控制器及波特率选择寄存器(可寻址)
  10. ADC_CONTR AD转换控制寄存器(可寻址)

2. 中断功能的开关 – IE 中断允许寄存器

该寄存器主要作用是控制单片机的中断是否允许启用

在这里插入图片描述

如下每一位都表示中断允许控制位
EA 该位用于控制整个单片机的中断功能是否开启,总开关概念

  1. 设置为0表示禁止单片机开启所有中断功能
  2. 设置为1 表示允许单片机开启任意中断功能

EX0 该位用于控制单片机INT0引脚是否转为外部中断0功能(不开启时该引脚默认为普通IO功能)

  1. 设置为0 不开启该引脚的外部中断功能,使用默认的IO功能
  2. 设置为1 开启该引脚的外部中断功能(IO功能相应的会被关闭)

EX1 该位用于控制单片机INT1引脚是否转为外部中断1功能(不开启时该引脚默认为普通IO功能)

  1. 设置为0 不开启该引脚的外部中断功能,使用默认的IO功能
  2. 设置为1 开启该引脚的外部中断功能(IO功能相应的会被关闭)

ET0 该位用于控制单片机开启定时器/计数器0的中断功能
问题:开启时影响会单片机哪些引脚的功能发生转换?

  1. 设置为0 不开启定时器/计数器0的中断功能
  2. 设置为1 开启定时器/计数器0的中断功能

ET1 该位用于控制单片机开启定时器/计数器1的中断功能

  1. 设置为0 不开启定时器/计数器1的中断功能
  2. 设置为1 开启定时器/计数器1的中断功能

ES 串行中断允许控制位 该位控制串行中断的开关(待了解)

  1. 设置为0 关闭串行中断功能
  2. 设置为1 开启串行中断功能

EADC AD转换中断允许控制位(待了解)

ELVD 低压检测中断允许控制位(待了解)

3. 中断/定时器/计数器的通用控制 – TCON 中断/定时器/计数器通用控制寄存器

该寄存器用于定时器/计数器的控制

缺图

TF0 计数器0 溢出标识位
TF1 计数器1 溢出标识位
TR0 定时器/计数器0 运行控制位

  1. 设置为0 停止定时器/计数器工作
  2. 设置为1 启动定时器/计数器工作

TR1 定时器/计数器1 运行控制位

  1. 设置为0 停止定时器/计数器工作
  2. 设置为1 启动定时器/计数器工作

IE0 外部中断请求0 标识位 (当CPU采集到INT0 出现请求中断时,自动置为1,中断服务结束后自动置为0)
IE1 外部中断请求1 标识位 (当CPU采集到INT0 出现请求中断时,自动置为1,中断服务结束后自动置为0)
IT0 外部中断请求0 控制位

  1. 设置为0 表示低电平方式触发 外部中断0
  2. 设置为1 表示下降沿方式触发 外部中断0

IT1 外部中断请求1 控制位

  1. 设置为0 表示低电平方式触发 外部中断1
  2. 设置为1 表示下降沿方式触发 外部中断1

4. 定时/计数器工作方式的配置 – TMOD工作方式控制寄存器

该寄存器用于定时器/计数器工作方式的配置

缺图

高4位 控制定时器/计数器1
GATE 定时器/计数器1 的 门控位

  1. 设置为0 表示用TR1即可控制 定时器/计数器1 的开启与禁止
  2. 设置为1 表示需要用TR1和INT1# 一起才能控制 定时器/计数器1 的开启与禁止

C/T 定时器/计数器1 具体功能为计数还是定时

  1. 设置为0 表示定时功能 使用TH和TL可以设置初始数值,8位定时器读取TH和TL最大为65535时触发中断
  2. 设置为1 表示计数功能 由外部引脚 T1做计数脉冲

M1 M0 控制定时器/计数器工作模式

低4位 控制定时器/计数器0
GATE定时器/计数器0 的 门控位

  1. 设置为0 表示用TR0即可控制 定时器/计数器0 的开启与禁止
  2. 设置为1 表示需要用TR0和INT0# 一起才能控制 定时器/计数器0 的开启与禁止

C/T定时器/计数器0 具体功能为计数还是定时

  1. 设置为0 表示定时功能 使用TH和TL可以设置初始数值,8位定时器读取TH和TL最大为65535时触发中断
  2. 设置为1 表示计数功能 由外部引脚 T0做计数脉冲

M1 M0 控制定时器/计数器工作模式

M1位M0位对应工作模式描述
00013位计时计数器 (8192)
01116位计时计数器 (65536)
1028位计时计数器,可自动重新载入计数值 (256)
113当成两组独立的8位计时器(256,T0和T1不能同时用)

5.TH0/TL0 (TH1/TL1) 定时器高/低8位寄存器

定时器计数的寄存器,可以设置初始值,用于设定定时器的定时间隔

6.IP 定时/计数器同级优先级的配置 – 中断优先级寄存器

该寄存器的作用是设置中断同级优先级顺序时使用

在这里插入图片描述

PT0 定时中断0优先级设置位

  1. 设置位1 表示设置位同级高优先级
  2. 设置位0 表示设置位同级低优先级

PT1 定时中断1优先级设置位

  1. 设置位1 表示设置位同级高优先级
  2. 设置位0 表示设置位同级低优先级

PX0 外部中断0优先级设置位

  1. 设置位1 表示设置位同级高优先级
  2. 设置位0 表示设置位同级低优先级

PX1 外部中断1优先级设置位

  1. 设置位1 表示设置位同级高优先级
  2. 设置位0 表示设置位同级低优先级

PS 串口中断优先级设定位

  1. 设置位1 表示设置位同级高优先级
  2. 设置位0 表示设置位同级低优先级

PPCA PCA中断优先级设置位

  1. 设置位1 表示设置位同级高优先级
  2. 设置位0 表示设置位同级低优先级

PLVD 低压中断优先级设置位

  1. 设置位1 表示设置位同级高优先级
  2. 设置位0 表示设置位同级低优先级

PADC ADC中断优先级设置位

  1. 设置位1 表示设置位同级高优先级
  2. 设置位0 表示设置位同级低优先级

7.串口的工作方式和控制功能 – SCON 串口控制寄存器

控制和设置串口工作方式的寄存器

SM0/FE 串行口工作方式选择位,FE功能时为帧错误检测

  1. 当PCON寄存器中的SMOD0为1时,该位用于帧错误检测。当检测到一个 无效停止位时,通过UART接收器设置该位。它必须由软件清0。
  2. 当PCON寄存器中的SMOD0位为0时,该位和SM1一起指定串行通信的工作方式。

SM1 串行口工作方式选择位
SM2 多机通信控制位

  1. 工作方式0时:非多机通讯方式,SM2位需要设置为0,无特殊作用
  2. 工作方式1时:非多机通讯方式,SM2位需要设置为0,表示只有接收到**有效的停止位(第九位RB8)**才激活RI
  3. 工作方式2或3时:多机通信控制位,(REN需要置为1)
    A)SM2位设置为1时,则接收器处于地址帧筛选状态,此时可以利用接收到的第9位RB8来筛选地址帧
    RB8位读取为0时,则表示接收的数据不是地址帧,应该舍弃,并且保持RI=0状态
    RB8位读取为1时,则表示接收的数据是地址帧,数据存入SBUF,并且RI=1状态,触发串口中断,可以在中断中再进行地址号的比较
    B)SM2位设置为0时,则接收器处于地址帧筛选被禁止状态,此时接收到的第九位RB8通常为校验标志位
    RB8无论是0还是1,数据都会存入SBUF中,并且RI=1状态

REN 允许/禁止串行口接收的控制位

  1. 设置为0 禁止接收
  2. 设置为1 允许接收

TB8 发送的第九位数据,与SM2结合使用

  1. 工作方式0时: 无用
  2. 工作方式1时: 无用
  3. 工作方式2或3时: 按需要置位或清0(奇偶校验的标志位或地址帧/数据帧的标志位)

RB8 接收到的第九位数据,与SM2相关

  1. 工作方式0时: 无用
  2. 工作方式1时: 此位数据为接收到的停止位
  3. 工作方式2或3时: SM2设置为0,则此位数据为奇偶校验的标志位;SM2设置为1时,地址帧/数据帧的标志位

TI 发送中断请求标志位

  1. 工作方式0时: 串行发送第八位结束时,由内部硬件自动置位,并向主机发起中断请求,响应中断服务接收后,TI必须由软件设置为0
  2. 其他工作方式时: 停止位开始发送时,由内部硬件自动置位,并向主机发起中断请求,响应中断服务接收后,TI必须由软件设置为0

RI接受中断请求标志位

  1. 工作方式0时: 接收第八位数据结束时,由内部硬件自动置位,并向主机发起中断请求,响应中断服务接收后,RI必须由软件设置为0
  2. 其他工作方式时: 接收停止位中间时,由内部硬件自动置位,并向主机发起中断请求,响应中断服务接收后,RI必须由软件设置为0
SM0SM1工作方式功能说明波特率
00方式0同步移位串行方式:移位寄存器当UART_M0x6 = 0时,波特率是SYSclk/12,当UART_M0x6 = 1时,波特率是SYSclk / 2
01方式18位UART,波特率可变( 2SMOD/32 )×(定时器1的溢出率或BRT独立波特率发生器的溢出率)
10方式29位UART( 2SMOD/ 64) x SYSclk系统工作时钟频率
11方式39位UART,波特率可变(2SMOD/32 )x(定时器1的溢出率或BRT独立波特率发生器的溢出率)

注意:

  1. SMOD PCON中的波特率选择位
    设置为0:波特率加倍
    设置为1:波特率正常

  2. 溢出率为每秒溢出多少次 T1溢出率 = fosc / {12 * [256-(TH1)]}

  3. fosc为晶振频率 如11.0592MHZ的晶振频率为11059200

  4. RITI向主机发送中断请求时,他们之间的关系是或逻辑,单片机无法自动识别,使用时,需要业务操作进行区分

8.电源的控制 --PCON 电源控制寄存器

控制电源和部分串口功能的寄存器

SMOD 波特率选择位,复位时默认清零(与电源无关,与串口有关)

  1. SMOD=0时,串口方式为1/2/3,则波特率加倍
  2. SMOD=1时,串口方式为1/2/3,则波特率正常

SMOD0 帧错误检测有效控制位(与电源无关,与串口有关)

  1. SMOD0=0时,SM0/FE的功能是SM0,与SM1进行串口功能的工作方式选择
  2. SMOD0=1时,SM0/FE的功能是FE,进行帧错误检测

LVDF 低压检测标志位(也是低压检测中断请求标志位)

  1. 正常/空闲工作时:
    — 当工作电压Vcc低于低压检测门槛电压时,该位置1。该位要由软件清0 当低压检测电路发现工作电压Vcc偏低时,不要进行EEPROM/IAP操作。
  2. 在进入掉电工作状态前:
    — 如果低压检测电路未被允许可产生中断,则在进入掉电模式后,该低压检测电路不工作以降低功耗。
    — 如果被允许可产生低压检测中断,则在进入掉电模式后,该低压检测电路继续工作,在内部工作电压Vcc低于低压检测门槛电压 后,产生低压检测中断,可将MCU从掉电状态唤醒。

POF 上电复位标志位
GF1(GF0) 两个通用工作标志位,用户可以任意使用。
PD 设置为1,单片机进入断电模式,时钟停振,CPU/定时器/串口停止工作,只有外部中断继续工作,此时功耗<0.1uA
IDL 设置为1,单片机进入空闲模式,除了CPU停止工作外,其他部件继续工作

9.其他中断寄存器参考

STC51单片机中断与定时器配置参考

三、中断的使用

1.原理图

在这里插入图片描述

2. INT0#触发流程

  1. 主服务开始运行
  2. EA已开启总中断功能
  3. EX0已开启INT0#引脚中断功能
  4. INT0#引脚传入下降沿电平(中断的触发)
  5. CPU检测到IT0配置的下降沿电平就是中断开始工作的信号
  6. CPU 自动设置IE0为1
  7. IP中断优先级控制器
  8. 开始执行void xxx() interrupt 0中断服务
  9. 中断服务执行结束
  10. CPU自动设置IE0为0
  11. 程序返回主服务继续运行

3.中断的使用-下降沿触发

代码

#include <reg52.h>

sbit LED = P0^0;
sbit LED2 = P0^1;
void delay(unsigned int millis);
void main(){
	
	/**
	 * IE 中断允许寄存器
	 */
	EA=1;
	EX0=1;
	/**
	 * TCON 中断/定时器/计数器通用控制寄存器
	 */
	IT0=1;
	
	while(1){
		LED=0;
		delay(3000);
		LED=1;
		delay(3000);
	}
}
//中断0 服务
void switchLed2() interrupt 0 {
	LED2=0;
}

void delay(unsigned int millis){
 unsigned	int i2;
	unsigned int y=120;
		for(millis;millis>0;millis--)
		{
			for(i2=0;i2<y;i2++);
		}
}


4.中断的使用-低电平触发

将上边代码中 IT0=0;即可改变为低电平触发

5.中断实验效果

GND飞线接通INT0# 触发中断,P0^1位的黄灯点亮成功

在这里插入图片描述

注意
如果是低电平触发IT0=0,GND飞线持续接入INT0#时,红灯程序会近乎停止,(CPU跳转到中断服务运行时,主服务会停止)

四、定时器/计数器的使用

1.定时器中断原理图

在这里插入图片描述

2.定时器的使用

  1. IE位: 1 开启中断
  2. TR0/TR1: 1 启动定时器/计数器中断功能
  3. TMOD:确定T0/T1工作方式
  4. TH0/TL0(TH1/TL1) : 设置指定的初始值(未设置则从0开始)(计数到65536时触发中断)

如下代码程序为定时器0 计满65536后点亮LED2

代码

#include <reg52.h>

sbit LED = P0^0;
sbit LED2 = P0^1;
void delay(unsigned int millis);
void main(){
	
	/**
	 * IE 中断允许寄存器
	 */
	EA=1;
	ET0=1;
	
	/**
	 * TCON 中断/定时器/计数器通用控制寄存器
	 */
	TR0=1;
	/**
	 * TMOD 工作方式 选择 0000 0001 65536计满后触发中断
	 */
	TMOD=0x01;
	
	//定时器初始值
	TH0=0; //定时器初始值高8位
	TL0=0; //定时器初始值低8位
	
	while(1){
		LED=0;
		delay(3000);
		LED=1;
		delay(3000);

	}
}
// 中断1 服务
void switchLed2() interrupt 1 {
	LED2=0;
}

void delay(unsigned int millis){
 unsigned	int i2;
	unsigned int y=120;
		for(millis;millis>0;millis--)
		{
			for(i2=0;i2<y;i2++);
		}
}

如下代码程序通过多次定时控制,为近乎10秒切换一次LED2的状态

#include <reg52.h>

sbit LED = P0^0;
sbit LED2 = P0^1;
unsigned char count=0;
void delay(unsigned int millis);
void main(){
	
	/**
	 * IE
	 */
	EA=1;
	ET0=1;
	
	/**
	 * TCON 
	 */
	TR0=1;

	
	/**
	 * TMOD
	 */
	TMOD=0x01;
	
	TH0=(65536-46080)/256;
	TL0=(65536-46080)%256;
	
	while(1){
		LED=0;
		delay(3000);
		LED=1;
		delay(3000);
		if(count>=200)
		{
			LED2=~LED2;
			count=0;
		}

	}
}

void switchLed2() interrupt 1 {
	

	TH0=(65536-46080)/256;
	TL0=(65536-46080)%256;
	count++;
}

void delay(unsigned int millis){
 unsigned	int i2;
	unsigned int y=120;
		for(millis;millis>0;millis--)
		{
			for(i2=0;i2<y;i2++);
		}
}


如下代码,由两个定时器控制的不同频段闪烁的LED灯,LED1每秒改变一次,LED2每5秒改变一次
(一个定时器也可以控制多各种业务逻辑,此处演示两个定时器)

#include <reg52.h>

sbit LED1 = P0^0;
sbit LED2 = P0^1;
unsigned char count1,count2;
void main(){
	
	/**
	 * IE
	 */
	EA=1;
	ET0=1;
	ET1=1;
	
	/**
	 * TCON 
	 */
	TR0=1;
	TR1=1;
	
	/**
	 * TMOD
	 */
	TMOD=0x01;
	
	TH0=(65536-46080)/256;
	TL0=(65536-46080)%256;
	
	TH1=(65536-46080)/256;
	TL1=(65536-46080)%256;
	
	while(1){
		if(count1>=100){
			LED1=~LED1;
			count1=0;
		}
		if(count2>=100)
		{
			LED2=~LED2;
			count2=0;
		}
	}
}

void switchLed2() interrupt 1 {
	TH0=(65536-46080)/256;
	TL0=(65536-46080)%256;
	count2++;
}

void switchLed1() interrupt 3 {
	TH1=(65536-46080)/256;
	TL1=(65536-46080)%256;
	count1++;
}

3.计数器的使用

  1. IE位: 1 开启中断
  2. TR0/TR1: 1 启动定时器/计数器中断功能
  3. TMOD:确定T0/T1工作方式
  4. TH0/TL0(TH1/TL1) : 设置指定的初始值(未设置则从0开始)(计数到65536时触发中断)

与定时器的区别是修改TMOD的内容,准确的说是调整C/T位的值为1,表示使用计数器模式
注意
TMOD高4位和低4位分别指 定时器/计数器1 和定时器/计数器0 的配置

	/**
	 * TMOD 工作方式 选择 0000 0101 外部引脚计数满65536触发
	 */
	TMOD=0x05;

总结

本章主要为了解51单片机的中断与定时

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值