历史上的今天
返回首页

历史上的今天

今天是:2025年08月20日(星期三)

正在发生

2019年08月20日 | 51单片机之外部中断应用实例(电平触发、边沿触发)

2019-08-20 来源:eefocus

硬件:STC89C52RC

开发工具:Keil uVision4

前言:8051是一款很经典的、历史悠久的单片机,作为一款入门级的单片机8051受到很多初学者的欢迎。89c52是8051系列的成员之一,拥有8K字节程序存储空间,512字节随机数据存储空间;I/O口控制端口、中断功能、定时器及串行接口。下面详细讲述外部中断功能的使用。


外部中断:单片机提供的系统紧急事件的输入控制。事件触发的方式包括输入信号的下降沿触发、低电平触发。当触发中断后,单片机会跳到某一个固定的地址去执行中断服务程序。


外部中断信号由INT0、INT1引脚传送进来,如图所示:


有关中断处理的相关控制寄存器如下:


计时计数器控制寄存器 TCON

中断允许控制寄存器 IE

中断优先权寄存器 IP

寄存器并不算多,配置起来也不复杂。先对各个寄存器进行说明:


TCON寄存器:

“T”开头的是计数/定时器相关位,“I”开头的是外部中断相关位,我们需要看的是后者:


IE寄存器:


IP寄存器:

CPU接到中断信号发生时会停止当前的工作跳转到中断服务程序。那么当CPU同时接到多个中断信号时,该怎么选择?当CPU正在中断函数时又接受到另一个中断信号,该怎么处理?


关于中断的优先级有一下原则:

1、CPU同时接收到几个中断时,首先响应优先级最高的中断请求,低优先的进入队列等待;

2、正在进行的中断过程不能被新的同级或低优先级的中断请求所中断;

3、正在进行的低优先级中断服务,能被高优先级中断请求中断;


那么,IP寄存器的某一中断配置为1就成为高优先级。每一个中断在IP里面只占一位配置位(IP.x=0或OP.x=1),也就是说系统里只存在两种优先级,要么是高优先级,要么是低优先级。


如果,任何中断都不配置IP寄存器的优先级,也等同于系统上电时,默认的优先级顺序如下:


外部中断0 > 定时/计数器0 > 外部中断1 > 定时/计数器1 > 串行中断


关于外部中断的寄存器已经了解清楚了,接下来看代码设计:


外部中断0(下降沿触发)

/*-----------------------------------------------

  功能:外部中断0边沿触发

  现象:首先将P3.2口通过上拉电阻接到电源,保证在空闲时P3.2处于高电平;

       当外部中断信号输出口P3.2接到GND时,产生了一个下降沿信号,接到P0.0

       口的LED灯反转;若此后P3.2持续接到GND,LED只反转一次,这与电平触发

       有区别。

------------------------------------------------*/

 

#include 

 

sbit LED=P0^0; //定义LED端口

 

void DelayMs(unsigned char t)     //大致延时1mS

{

 unsigned short T=500;

 while(t--)

 {

     while(--T);

 }

}

void INT0_init(void) //外部中断0初始化

{

  LED=1;       //LED口初始值

  EA=1;          //全局中断开

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

  IT0=1;         //边沿触发

}

 

main()

{

  INT0_init();

  while(1){

     //主循环

  }

}

 

//中断服务程序  interrupt 0 指明是外部中断0的中断函数

/*

interrupt 0  指明是外部中断0;

interrupt 1  指明是定时器中断0; 

interrupt 2  指明是外部中断1;

interrupt 3  指明是定时器中断1;

interrupt 4  指明是串行口中断;

*/

void ISR_Key(void) interrupt 0 using 1

{

 if(!INT0){

    DelayMs(10);       //防抖动

    if(!INT0){         

     LED=!LED;         //按下触发一次,LED取反一次

    }

 }

}

外部中断0(电平触发)

/*-----------------------------------------------

  功能:外部中断0电平触发

  现象:首先将P3.2口通过上拉电阻接到电源,保证在空闲时P3.2处于高电平;

       当外部中断信号输出口P3.2接到GND时,产生了一个低电平信号,接到P0.0

       口的LED灯反转;若此后P3.2持续接到GND,LED会反复反转,这与边沿触

       发有区别。

------------------------------------------------*/

 

#include 

 

sbit LED=P0^0; //定义LED端口

 

void DelayMs(unsigned char t)     //大致延时1mS

{

 unsigned short T=500;

 while(t--)

 {

     while(--T);

 }

}

void INT0_init(void) //外部中断0初始化

{

  LED=1;       //LED口初始值

  EA=1;          //全局中断开

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

  IT0=0;         //电平触发

}

 

main()

{

  INT0_init();

  while(1){

     //主循环

  }

}

 

//中断服务程序  interrupt 0 指明是外部中断0的中断函数

/*

interrupt 0  指明是外部中断0;

interrupt 1  指明是定时器中断0; 

interrupt 2  指明是外部中断1;

interrupt 3  指明是定时器中断1;

interrupt 4  指明是串行口中断;

*/

void ISR_Key(void) interrupt 0 using 1

{

  if(!INT0){

    DelayMs(20);       //防抖动

    if(!INT0){         

     LED=!LED;         //按下触发一次,LED取反一次

    }

 }

}

外部中断1(下降沿触发)

/*-----------------------------------------------

  功能:外部中断1边沿触发

  现象:首先将P3.3口通过上拉电阻接到电源,保证在空闲时P3.3处于高电平;

       当外部中断信号输出口P3.3接到GND时,产生了一个下降沿信号,接到P0.0

       口的LED灯反转;若此后P3.3持续接到GND,LED只反转一次,这与电平触发

       有区别。

------------------------------------------------*/

 

#include 

 

sbit LED=P0^0; //定义LED端口

void DelayMs(unsigned char t)     //大致延时1mS

{

 unsigned short T=500;

 while(t--)

 {

     while(--T);

 }

}

void INT1_init(void) //外部中断0初始化

{

  LED=1;       //LED口初始值

  EA=1;          //全局中断开

  EX1=1;         //外部中断1开

  IT1=1;         //边沿触发

}

 

main()

{

  INT1_init();

  while(1){

     //主循环

  }

}

 

/*

interrupt 0  指明是外部中断0;

interrupt 1  指明是定时器中断0; 

interrupt 2  指明是外部中断1;

interrupt 3  指明是定时器中断1;

interrupt 4  指明是串行口中断;

*/

void ISR_Key(void) interrupt 2 using 1

{

 if(!INT1){

    DelayMs(10);       //防抖动

    if(!INT1){         

     LED=!LED;         //按下触发一次,LED取反一次

    }

 }

}

 

#endif

外部中断1(电平触发)

/*-----------------------------------------------

  功能:外部中断1电平触发

  现象:首先将P3.3口通过上拉电阻接到电源,保证在空闲时P3.3处于高电平;

       当外部中断信号输出口P3.3接到GND时,产生了一个低电平信号,接到P0.0

       口的LED灯反转;若此后P3.3持续接到GND,LED会反复反转,这与边沿触

       发有区别。

------------------------------------------------*/

 

#include 

 

sbit LED=P0^0; //定义LED端口

void DelayMs(unsigned char t)     //大致延时1mS

{

 unsigned short T=500;

 while(t--)

 {

     while(--T);

 }

}

void INT1_init(void) //外部中断1初始化

{

  LED=1;       //LED口初始值

  EA=1;          //全局中断开

  EX1=1;         //外部中断1开

  IT1=0;         //电平触发

}

 

main()

{

  INT1_init();

  while(1){

     //主循环

  }

}

 

/*

interrupt 0  指明是外部中断0;

interrupt 1  指明是定时器中断0; 

interrupt 2  指明是外部中断1;

interrupt 3  指明是定时器中断1;

interrupt 4  指明是串行口中断;

*/

void ISR_Key(void) interrupt 2 using 1

{

 if(!INT1){

    DelayMs(10);       //防抖动

    if(!INT1){         

     LED=!LED;         //按下触发一次,LED取反一次

    }

 }

}

以上四种模式,代码都是大同小异,比较一下就知道哪些是关键点了。


注意点:


上面的程序已经是测试过没有问题的,如果出现led不反转,那么检测一下电路,有一些集成了很多元件的开发板里面电路复杂,几个外围元件可能共用一个IO口,容易被干扰,以至于达不到想要的效果。最好还是买一个最小系统的单片机,所有IO独立出来。

在选择“电平触发”模式下,因为低电平的持续时间比较长(虽然只是按一下,对于单片机来说已经持续很长),会出现反复进入中断,导致LED不会反转,解决方法就是在进入第一次中断后,先把该中断关闭掉并且用while循环,直到中断信号引脚退出低电平状态再打开中断并退出while循环,这么做缺点就是会阻塞在中断里面,可能导致主函数里面的程序不能及时运行。

上面的代码比较简单,需要根据实验出现的问题进一步优化。

外部中断还可以应用到检测波形的周期、占空比、频率以及红外接收处理,有兴趣可以试一下。

仅供参考,错误之处以及不足之处还望多多指教。

推荐阅读

史海拾趣

HCH Co公司的发展小趣事

背景:随着全球对环境保护和可持续发展的重视程度不断提高,HCH Co公司积极响应号召,开始了绿色转型之路。公司致力于开发环保型电子产品和绿色生产技术,以减少对环境的影响。

发展:通过不断的技术创新和生产工艺的改进,HCH Co公司成功推出了一系列环保型电子产品,如可回收材料制成的外壳、低功耗的显示屏等。同时,公司还加强了废弃电子产品的回收和再利用工作,实现了资源的循环利用。绿色转型不仅提升了公司的社会形象,也为公司的长期发展注入了新的动力。

极海半导体(Geehy)公司的发展小趣事

背景:随着全球经济一体化的加速推进,HCH Co公司意识到必须加快全球化步伐以拓展更广阔的市场空间。公司制定了详细的全球化战略,包括在海外设立研发中心、生产基地和销售网络等。

发展:通过全球化战略的实施,HCH Co公司成功进入了多个国际市场,并与当地的企业和机构建立了紧密的合作关系。公司的品牌影响力不断提升,产品销量也实现了快速增长。同时,全球化战略还为公司带来了更多的技术、人才和市场资源,为公司的长期发展奠定了坚实基础。

台湾双羽公司的发展小趣事

在成为全球领先的电子企业之后,富士通并没有停下脚步。公司开始积极拓展海外市场,将先进的技术和产品带到世界各地。通过在全球各地设立分支机构、与当地企业建立合作关系等方式,富士通成功地将自己的业务版图扩展到了全球60多个国家和地区。这一过程中,富士通不仅为当地市场带来了先进的技术和产品,也促进了全球电子产业的交流与合作。

Electronic公司的发展小趣事

AMD,曾经一度陷入困境的半导体公司,近年来实现了逆袭。AMD通过持续的技术创新和市场竞争策略的调整,成功在处理器和显卡市场取得了重要份额。AMD的产品性能不断提升,价格也更加亲民,赢得了消费者的广泛认可。同时,AMD还积极与游戏厂商和硬件厂商合作,推出了多款定制化的产品和解决方案。这些努力使得AMD在激烈的市场竞争中逐渐崭露头角。

HEC Inc公司的发展小趣事

小米,作为一家年轻的科技公司,在电子行业的发展中展现了惊人的成长速度。小米凭借出色的产品设计和创新的营销策略,迅速在手机市场获得了巨大成功。随着业务的不断拓展,小米还涉足了智能家居、物联网和互联网金融等领域,形成了完整的生态布局。小米通过提供高性价比的产品和优质的服务,赢得了大量年轻用户的喜爱和支持。

Bellin公司的发展小趣事

小米,作为一家年轻的科技公司,在电子行业的发展中展现了惊人的成长速度。小米凭借出色的产品设计和创新的营销策略,迅速在手机市场获得了巨大成功。随着业务的不断拓展,小米还涉足了智能家居、物联网和互联网金融等领域,形成了完整的生态布局。小米通过提供高性价比的产品和优质的服务,赢得了大量年轻用户的喜爱和支持。

问答坊 | AI 解惑

MCGS组态软件设计及其应用

一、引言     过去工业控制计算机系统的软件功能都靠软件人员编程实现。工作量大,软件通用性差,且易产生错误。随着工业控制要求的不断提高,专门用于工业控制的组态软件应运而生,它是一套功能齐全的组态生成工具软件,通用性强,而 ...…

查看全部问答>

ARM c程序的问题

_irqHandler PROC    1. STMFD   sp!,{r0-r4,r12,lr}    2. mov     r4,#0x80000000  //中断控制寄存器首地址(假设的)    3. ldr     r0,[r4,#0] ...…

查看全部问答>

给论坛的建议

我希望论坛能够在下载扣金币方面可以放松点,比如每次只扣一个或者在某个贴上下载只扣若干个就好了,因为有些文件确实比较大,要下好几个压缩文件才能行的,而每下一个就扣好几,很多人都有些不舍得,毕竟金币有比较难得,特别是新手就更麻烦了,我 ...…

查看全部问答>

计时制办公场地租赁,个人创业,兼职,自由职业人的最佳选择。

计时制办公场地租赁,个人创业,兼职,自由职业人的最佳选择。 请见网站: http://www.ingress.cn 打工者们,你是否在为每天要起早贪黑奔赴公司同时上下班交通拥堵而烦心? 创业者们,你是否在为寻找物美价廉随时可退租的办公场地而操心? 企业 ...…

查看全部问答>

wince 桌面快捷方式

请问: wince中的文件夹有没有后缀名? 我想把一个名为NandFlash的文件夹,放到桌面快捷方式, 我在WINCE500\\PLATFORM\\SMDK2440\\FILES创建了一个NandFlash.LNK文件,里面写上22#\\windows\\NandFlash 我又在Project.bib 里面加上 NandFlash ...…

查看全部问答>

uIP能不能抗死亡之ping?

能不能? 在代码的哪一部分证明?…

查看全部问答>

0

居然要全部下完才能都打开?这个有点不厚道…

查看全部问答>

LM3S程序求教

//————————————————头文件————————————————————#include \"inc/hw_ints.h\"//硬件中断#include \"inc/hw_memmap.h\"#include \"inc/hw_types.h\"//硬件类型#include \"driverlib/gpio.h\"//GPIO#include \"dri ...…

查看全部问答>

中断究竟是个怎么回事?

今天听单片机老师讲课讲中断,说分了好几种,被他弄得一头雾水,还是没明白他说的中断都有什么,怎么配置,查了查2553手册,愣是没找到讲解终端的地方,球大神指点123!不胜感激。…

查看全部问答>

DCDC电源中的电流检测

文章介绍了7中电流检测的办法,可以作为电流检测的入门读物 …

查看全部问答>