51单片机——中断

这篇具有很好参考价值的文章主要介绍了51单片机——中断。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

中断系统的设置,是为了让CPU能对外界紧急事件进行实时处理

中断的过程是,当中断请求源发出中断请求时,CPU响应中断后,CPU先暂停当时正在执行的主程序,转而去处理中断服务程序,处理完后继续原来的工作

微型机一般允许多个中断源,当几个中断源同时发出中断时,CPU先响应最高优先级的中断

中断嵌套:CPU在处理中断时,外界产生了更高优先级的中断,CPU暂停当前中断,处理了更高优先级的中断后,在回来处理之前的中断,具有中断嵌套功能的系统叫多级中断系统,不具有的叫单级中断系统

如何使用中断

此52单片机一般有8个中断请求源,分别对应8个中断查询次序号(中断号),这些中断被硬件所调用,通过编写中断查询次序号的中断服务程序,就可以让CPU在响应中断时,执行具体的功能代码;4个外部中断INT0,INT1,INT2,INT3,3个定时器中断,定时器0中断,定时器1中断,定时器3中断,1个串口中断。

每一个中断源都可用软件独立地控制为允许中断或关闭中断,每一个中断源的中断优先级均可用软件设置

中断相关寄存器

中断相关的寄存器有:中断请求标志寄存器TCON和SCON,中断允许寄存器IE,中断优先级寄存器IP

TCON寄存器中IE0和IE1位是外部中断请求0和1的中断请求标志位,IT0和IT1位用于选择外部中断请求是负跳变触发,还是电平触发,IT置0为电平触发,即当加到INT上的外部中断请求输入信号为低电平时,将IE位置1,发出中断,CPU介入后,硬件将IE置0

IE寄存器对中断的允许和禁止实现两级控制,可位寻址,总的中断开关位EA(IE^7),EA置0,所有中断都无效,EA置1,中断源是否运行还要由低位的中断请求允许控制位的状态决定,置1对应中断源中断允许,置0中断无效,其他位ET0到ET2控制定时器0到2的溢出中断,ES控制串口,EX0到EX1控制外部中断0到1

中断开关如图

51单片机——中断

IP寄存器用于配置中断请求源的优先级,不同位配置不同中断请求源

优先级相同的多个中断,CPU的响应次序按照中断查询次序号来响应,0为最先,7为最低

中断请求源顺序如图

51单片机——中断

案例一:定时器中断控制闪灯

#include "reg52.h"

sbit ledblue =P3^7;
sbit ledyellow =P3^6;
void delay1000(){
	int cnt=0;
	TR0=1;
	while(1){
	  if(TF0==1){ 
		 cnt++;
		 TF0=0; //定时器0爆表不中断,那么手动将TF0位置0
	   TL0=0x00;
	   TH0=0xDC;
	 }
	 if(cnt==100)break;
	}
	TR0=0;
}
void ClockInit(){
  TMOD&=0x00;
	TMOD|=0x11;
	TL0=0x00;
	TH0=0xDC;
	TL1=0x00;
	TH1=0xDC;
}
void main(){
	 ledblue=1;
	 ledyellow=0;
	 ClockInit();

	 EA=1;
	 ET1=1;
   TR1=1;
   while(1){
    ledblue=!ledblue;
		delay1000(); 
	 }
}

void Lightyellow() interrupt 3 //定时器1每10ms爆表一次,爆表时TF1位置1,进入中断,TF1位自动置0,然后将cnt++,加到50次,即0.5s后,黄灯电平翻转
{    static int cnt=0;
	   cnt++;
	   TL1=0x00;
	   TH1=0xDC; 
	   if(cnt==50){
       ledyellow=!ledyellow;
			 cnt=0;
     }
}

案例二:定时器中断控制SG90舵机切换角度转动

SG90舵机

SG90舵机需要的控制信号与一般的电平信号不同,他需要的控制信号是PWM信号,即占空比不同的方波信号

舵机接线为红线VCC,黑线GND,黄线PWM信号接收

SG90舵机有两个规格,180°类型的360°类型,对应PWM波的控制情况如图

51单片机——中断

180°版本 占空比越高,转动的角度越大,但是转动角度有些误差,需要微调,高电平时间大概90°要1570us,180°要2570us,2720us为最大角度(略微大于180°),220us为最小角度(略微小于0°);超过2730us,先转动到最大角度,然后按超出量多少,转动速度就是多少的转动速度转动一小会,然后再快速转动回最大角度,如此循环,小于220us同理,

51单片机——中断

360°版本

0到2.5%占空比,维持最快顺时针转速不变;2.5%到7.5%占空比,占空比越高,顺时针转速越慢;7.5%完全暂停;7.5%到12.5%占空比,占空比越高,逆时针转速越快;12.5%占空比往上,维持最快逆时针转速不变

SG90舵机还分为数字电机和模拟电机,数字电机,给一次PWM信号就能转动,模拟电机需要在一段时间内持续给PWM信号才能转动

我们采用的是180类型的模拟信号SG90舵机

注意:一般信号周期是固定的,对于控制不同仪器,可能信号周期会有所变化;而对于相应信号周期占空比可以变化,用来控制程度

什么是PWM

PWM是脉冲宽度调制,通过对一系列脉冲的宽度进行调制,通过调节占空比,等效出需要的模拟信号波形,相当于用调节高低电平的时间长度来等效模拟信号,PWM给出的信号仍然是数字的,简而言之,PWM是一种对模拟信号电平进行数字编码的方法,比如1s内给持续5v的电压信号,占空比60%,相当于是1s内给持续3v的电压信号,占空比20%,相当于1s内给持续1v的电压信号

PWM波有两个决定条件,一个是信号周期,另一个是占空比

信号周期:PWM波是由周期的占空比信号组成,信号周期就是一个占空比信号所占的时间长度

占空比:一个信号周期内,信号处于高电平状态的时间占整个周期的时间,比如方波的占空比就是50%

占空比不同,表示的模拟信号不同,输出的电压就不同,对应的舵机旋转角度就不同

PWM信号可以通过C52自带的硬件产生,也可以通过IO口软件模拟产生,精准度略差

如何控制舵机

PWM波的频率不能太高,一般50hz,即信号周期0.02s,信号周期用定时器来控制

频率高的话,周期就小,固定时间内接收到的信号数量就越多,频率低的话,周期就大,固定时间内接收到的信号数量就越少,但是固定时间内二者高低电平所占时间的比例是相同的,为占空比

占空比每提升2.5%,舵机就增加45°

在大于周期的一段时间内持续输出对应占空比的PWM波,电机就会转动相应角度

如何设定定时器定时的初值

因为定时器的初值由TH位和TL位设置,所以TH位可以等于(65536-定时时长/机器周期)/256得出,

TL位可以等于(65536-定时时长/机器周期)%256得出

注意:取模运算不可以用浮点数

PWM方波如何输出

方案1

用定时器0来输出周期占空比的高电平,定时器1来输出剩下周期时间的低电平。在电平跳变点(当前即定时器爆表)进入中断程序,来配置下一个定时器

将PWM波分为一段时间的高电平,一段时间的低电平,不断重复,起初打开定时器1,爆表后,进入中断程序,在中断程序中,设定输出高电平和定时器0的定时初值后,打开定时器0,结束中断程序,这样就输出了对应时间的高电平,等定时器0爆表后,进入中断程序,在中断程序中又设置输出低电平和定时器1的定时初值,然后结束中断程序

进入中断后要及时关闭当前定时器,再打开下一个定时器,这样保持定时器0运行一段时间,定时器1运行一段时间

代码

#include "reg52.h"
#include<intrins.h>
sbit ledb=P3^7;
sbit ledy=P3^6;
sbit sg90 =P1^6;

int flag=0;
void Delay2000()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 15;
	j = 2;
	k = 235;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void ClockInit(){
  TMOD&=0x00;
	TMOD|=0x11;
	TL0=0x66;
	TH0=0xbd;
	TH1=0xfa;
	TL1=0x9a;
	EA=1;
	ET0=1;
	ET1=1;	
}
void do1() interrupt 1
{
	
	TR0=0;
    sg90=0;
	ledy=0;
	ledb=1;
  if(flag==0){
    //TL1=0xcd;
	//TH1=0xb9; 
	  TH1=(65536-19500/1.085)/256;
	  TL1=(int)(65536-19500/1.085)%256;
  }
	if(flag==1){
	//TL1=0x66;
	//TH1=0xbd;
	  TH1=(65536-18500/1.085)/256;
	  TL1=(int)(65536-18500/1.085)%256;  //取模不能用浮点数,需要强转

  }
	TR1=1;
}
void do2() interrupt 3
{
	
	TR1=0;
	sg90=1;
	ledy=1;
	ledb=0;
	if(flag==0){//360°sg90舵机 2.5%占空比顺时针全速转动
//  TL0=0x33;
//	TH0=0xfe;
	TH0=(65536-500/1.085)/256;
	TL0=(int)(65536-500/1.085)%256;
  }
	if(flag==1){ //360°sg90舵机 7.5%占空比停止转动
//	TL0=0x9a;
//	TH0=0xfa;
	TH0=(65536-1500/1.085)/256;
	TL0=(int)(65536-1500/1.085)%256;	
  }
	TR0=1;
}
void main(){
	  ledy=1;
	  ledb=0;

	  ClockInit();
	  TR1=1;
	  while(1){
     flag=!flag; //切换占空比
     Delay2000();
    }
    
}


	

方案2

由于占空比每提升2.5%,舵机就增加45°,如果以45度为转动单位,那么可以将一个周期20ms秒分成40等分,每等分占0.5ms,每等分输出高电平或低电平

用一个变量cnt记录次数,爆表一次cnt++,将定时器爆表前可计时的时长定为0.5ms,每次爆表前持续输出高电平或者低电平,总共输出40次,代表一个周期;cnt自加到40后,cnt置0,代表循环

每增加2.5%的占空比,40次中,输出高电平的次数就多一次

代码

#include "reg52.h"
#include<intrins.h>

sbit sg90 =P1^6;
sbit ledb =P3^7;
sbit ledy =P3^6;
int cnt=0;
int jd;
void Delay2000()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 15;
	j = 2;
	k = 235;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void ClockInit(){
  TMOD&=0x00;
	TMOD|=0x11;
//	TL0=0xff;
//	TH0=0xb7;
	TL1=0x33;
	TH1=0xfe;
	EA=1;
//	ET0=1;
	ET1=1;
}
void main(){
    Delay2000();
	  ClockInit();
    TR1=1;	
	  while(1){
     jd=3;
		 cnt=0;
		 TL1=0x33;
	   TH1=0xfe;
		 ledb=0;
		 ledy=1;
		 Delay2000();
		 jd=4;
		 cnt=0;
		 TL1=0x33;
	   TH1=0xfe;
		 ledb=1;
		 ledy=0;
		 Delay2000();
    }

	
}

void do2() interrupt 3
{
	cnt++;
	if(cnt<=jd)sg90=1;
	else sg90=0;
	TL1=0x33;
	TH1=0xfe;
	if(cnt==40){
   cnt=0;
  }
}

	

案例三:超声波模块测距控制亮灯

超声波模块HC-SR04

通过发送和接收超声波,利用时间和声音传播速度计算出障碍物与模块的距离,测距范围2cm到400cm,精度为3mm

TRIG引脚,给予至少10us的高电平,产生发波指令,经过一小段时间产生8个40khz的超声波方波并发送出去,发送时,ECHO引脚由低电平跳转到高电平,当超声波反弹回来被接收时,ECHO引脚又高电平跳转到低电平

计算时间,ECHO引脚进入高电平时,打开定时器,ECHO引脚跳转会低电平时,关闭定时器,通过定时器的差值计算出超声波传播的时间,距离等于时间*340/2,定时器一次可计时71106us,最大测距为1208cm,所以满足400cm的测距范围

代码

#include "reg52.h"

sbit ledblue =P3^7;
sbit ledyellow =P3^6;
sbit Trig=P2^5;
sbit Echo=P2^6;
void Delay10us()		//@11.0592MHz
{
	unsigned char i;

	i = 2;
	while (--i);
}

void ClockInit(){
    TMOD&=0xf0;
	TMOD|=0x01;
	TH0=0x00;
	TH0=0x00;
}

void startHC(){
  Trig=1;
	Delay10us();
	Trig=0;
}
void main(){
    double dis=0;
	double time=0;
	ClockInit();
	while(1){
     startHC();
	 while(Echo==0);
	 TR0=1;
     while(Echo==1);
 	 TR0=0;
     time=(TH0*256+TL0)*1.085;
	 dis=time*0.017;
	 if(dis<10)ledblue=0;
	 else ledblue=1;
	 TH0=0x00;
	 TL0=0x00;
    }
}

终项目:感应开关盖垃圾桶

目标实现

1、测距控制垃圾桶开关盖

2、按键控制垃圾桶开关盖

3、振动控制垃圾桶开关盖

4、开关盖时蜂鸣器响应

需要的技术

1、垃圾桶开关盖需要舵机转动角度来支撑,舵机转动不同的角度需要不同占空比的PWM波,实现PWM波,则需要定时器0和定时器1分别产生相应时间的高低电平循环,需要用到定时器中断

2、振动控制开关盖,如果只是把振动产生的信号或到测距控制开关盖中,则有可能发生振动已经产生,信号也产生了,但是代码没有捕获到这个信号,当运行到判断部分时,振动信号已经消失了,所以需要用到外部中断,信号产生时同时发起外部中断,用一个变量记录下这个信号,下次运行到判断部分时,能检测到这个变量,则会控制开关盖

外部中断IT0如果置0表示低电平触发,对于模块发出信号为低电平时会发出中断;置1表示下降沿触发,对于模块发出信号与高电平脉冲有效,因为发出脉冲后会跳变回低电平,跳回时发出中断文章来源地址https://www.toymoban.com/news/detail-413751.html

代码

#include "reg52.h"
#include<intrins.h>

sbit ledblue   =P3^7;
sbit ledyellow =P3^6;
sbit Trig      =P2^5;
sbit Echo      =P2^6;
sbit sg90      =P1^6;
sbit key1      =P2^1;
sbit zd        =P3^2;  //振动
sbit beep      =P2^4;  //继电器开关,用于控制喇叭
int jd=0;
int jdbake=0;
int flag=1;
int soundflag=0;
int zd_mark=0;
void Delay2000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 15;
	j = 2;
	k = 235;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
void Delay100ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 180;
	j = 73;
	do
	{
		while (--j);
	} while (--i);
}
void Delay10us()		//@11.0592MHz
{
	unsigned char i;

	i = 2;
	while (--i);
}

void startHC(){
    Trig=1;
	Delay10us();
	Trig=0;
}

double getDis(){
	 double time=0;
	 TH2=0x00;
	 TL2=0x00;
	 startHC();
	 while(Echo==0);
	 TR2=1;
   while(Echo==1);
 	 TR2=0;
   time=(TH2*256+TL2)*1.085;
	 return (time*0.017);
}

void ClockInit(){
  TMOD&=0x00;
	TMOD|=0x11;
	EA=1;
	ET0=1;
	ET1=1;	
	TR1=1;
}
void Sound(){
  int i=0;
	beep=0;
	for(i;i<3;i++){
  Delay100ms();
  }
  beep=1;
	i=0;
	for(i;i<3;i++){
  Delay100ms();
  }

}
void Clock2Init(){
	TH2=0x00;
	TL2=0x00;
}
void EX0Init(){
    EX0=1;//开启外部中断
	IT0=0;//中断触发为低电平

}
void main(){
    double dis=0;
	Clock2Init();
	ClockInit();
	EX0Init();
    while(1){
	   dis=getDis();
	   if(key1==0){
       Delay100ms();
       flag=!flag;
	   if(soundflag==0){
		 soundflag=0;
	   }else {
         soundflag=!soundflag;
      }
     }
	 if(flag==1){
		 EX0=1;
		 ledyellow=1;
	     if(dis<10||zd_mark==1){ 
			 EX0=0;
			 jd=180;
		     ledblue=0;
             if(jdbake!=jd){
			 Sound();
             }
             jdbake=jd;
		     Delay2000ms();
            zd_mark=0;
			 EX0=1;
        }
	    else {
		   jd=0;
           jdbake=jd;
		   ledblue=1;
		   Delay100ms();
	   }
     }else{
		   EX0=0;
           jd=180;
		   if(soundflag==0){
		     Sound(); //按键后只响一声
		   }
		   soundflag=1;
		   Delay100ms();
		   ledyellow=0;
     }
   }
}
void Low() interrupt 1
{
	TR0=0;
    sg90=0;
    if(jd==0){
    //	TL1=0xcd;
	//  TH1=0xb9;
	  TH1=(65536-(20000-500)/1.085)/256;  
	  TL1=(int)(65536-(20000-500)/1.085)%256;
  }
	if(jd==180){
	//TL1=0x66;
	//TH1=0xbd;
		TH1=(65536-(20000-2570)/1.085)/256;
		TL1=(int)(65536-(20000-2570)/1.085)%256;  //¼Çסȡģ²»¿ÉÒÔÓø¡µãÊý
  }
	TR1=1;
}
void High() interrupt 3
{
	TR1=0;
	sg90=1;
	if(jd==0){//ת¶¯
//  TL0=0x33;
//	TH0=0xfe;
	TH0=(65536-500/1.085)/256;    //1570 90°  210最小度数
	TL0=(int)(65536-500/1.085)%256;
  }
	if(jd==180){ //ÔÝÍ£
//	TL0=0x9a;
//	TH0=0xfa;
	TH0=(65536-2570/1.085)/256;   //2570 180°   2720最大度数 
	TL0=(int)(65536-2570/1.085)%256;	
  }
	TR0=1;
}
void get_zdsignal() interrupt 0
{
    zd_mark=1;

}

到了这里,关于51单片机——中断的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C51单片机中断系统与定时器/计时器(理论部分)

    前言 文章的开始,有人可能会问,我们在前几节课学了延时函数,为什么不用延时函数来取代定时器,而必须学定时器呢?这里,有如下几个理由: 1.使用delay函数时,单片机的cpu做不了其他事情,只能等待延时结束。 2.用了定时器cpu就可以做其他的事情,只要定时器溢出时

    2023年04月15日
    浏览(39)
  • 51单片机——中断

    中断系统的设置,是为了让CPU能对外界紧急事件进行实时处理 中断的过程是,当中断请求源发出中断请求时,CPU响应中断后,CPU先暂停当时正在执行的主程序,转而去处理中断服务程序,处理完后继续原来的工作 微型机一般允许多个中断源,当几个中断源同时发出中断时,

    2023年04月15日
    浏览(84)
  • 【51单片机】外部中断

    51的 外部中断 与 定时器(内部中断) 有一个共同特点,那就是与主程序是 并行 工作的,就是主程序在运行的时候,中断也在等待触发条件,当 中断被触发的时候会暂停主程序 转而执行中断服务程序,只有中断服务程序执行完后,才会继续执行主程序。 这里的触发条件是指:

    2024年02月02日
    浏览(63)
  • 51单片机中断

    1、什么是中断? CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生); CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务); 待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断 。 中断触

    2024年01月21日
    浏览(48)
  • 51单片机(九):中断

    一、“中断”与定时器的关系         前面我们学习过了定时器,实际上 定时器的一般用法都是采取中断的方式进行实现的 。需要明确的是,定时器和中断不是一回事,定时器是单片机模块的一个资源,确确实实存在的一个模块,而中断是单片机中的一种运行机制。 在单片

    2024年02月04日
    浏览(41)
  • 【51单片机——————外部中断】

    中断是指单片机主程序运行过程中,出现某些意外情况需要单片机处理,单片机能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。 在实际应用开发中,单片机不可能一直轮询查看按键是否按下,单片机还需要去执行其他任务,

    2024年02月06日
    浏览(46)
  • 51单片机 | 外部中断实验

       51 单片机外部中断有 2 个,外部中断 0 和外部中断 1 ,它们的使用方法是一样的,所以只要学会一个即可掌握所有外部中断使用。本节所要实现的功能是:使用独立按键 K3 控制 LED 亮灭, K3 连接外部中断 0 ( P3.2 )管脚。   上一节我们介绍了 51 单片机的中断系统,我

    2023年04月26日
    浏览(49)
  • 51单片机——定时器中断

    新版51单片机内部有 3 个16位可编程的定时器/计数器,即定时器 T0,T1,T2 。他们既有 定时 功能又有 计数 功能,我们可以通过配置与它们相关的特殊功能寄存器可以选择启用定时功能或计数功能;其中需要注意的是,这个定时器系统是单片机内部的一个独立的硬件部分,它与

    2023年04月10日
    浏览(40)
  • 单片机c51中断 — 中断键控流水灯

    项目文件 文件 关于项目的内容知识点可以见专栏单片机原理及应用 的第五章,中断   在第4章的实例2中,按键检测是采用查询法进行的,其流程图如图所示 问题是这样的:由于查询法 -按键查询、标志位修改及彩灯循环几个环节是串联关系,当CPU运行于彩灯时,将因不能及

    2024年02月08日
    浏览(55)
  • 51 单片机【外部中断、定时器中断、回调函数】

    ​这里的外部中断类似监听器,时时刻刻监视某引脚的电平变化;这里的定时器中断类似于定时任务,可以定时执行某函数;这里将回调函数和中断结合起来,案例里有点设计模式的味道(忘了哪个了,也可能就是感觉,关于高层不能调用低层的解决),也有点函数式编程的

    2024年02月04日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包