单片机在自主运行的时候一般是在执行一个死循环程序,在没有外界干扰(输入信号)的时候它基本处于一个封闭状态。比如一个电子时钟,它会按时、分、秒的规律来自主运行并通过输出设备(如液晶显示屏)把时间显示出来。在不需要对它进行调校的时候它不需要外部干预,自主封闭地运行。如果这个时钟足够准确而又不掉电的话,它可能一直处于这种封闭运行状态。但事情往往不会如此简单,在时钟刚刚上电、或时钟需要重新校准、甚至时钟被带到了不同的时区的时候,就需要重新调校时钟,这时就要求时钟就必须具有调校功能。因此单片机系统往往又不会是一个单纯的封闭系统,它有些时候恰恰需要外部的干预,这也就是外部中断产生的根本原由。

实际上在第二个示例演示中,就已经举过有按键输入的例子了,只不过当时使用的方法并不是外部中断,而是用程序查询的方式。下面就用外部中断的方法来改写一下第二个示例中,通过按键来更改闪烁速度的例子(第二个例子)。电路结构和接线不变,仅把程序改为下面的形式。

#include

unsigned int t=500; //定义一个全局变量t,并设定初始值为500次

//===========延时子函数,在8MHz晶振时约1ms=============

void delay_ms(unsigned int k)

{

unsigned int i,j;

for(i=0;i

{

for(j=0;j<1140;j++)

;

}

}

//============主函数==================================

void main( void )

{

DDRB = 0xFF; //设置端口B为输出方向

PORTB = 0xFF; //设置端口B的输出为全高电平

DDRD = 0x00; //设置端口D为输入方向

PORTD = 0xFF; //设定端口D为内部上拉方式,无信号输入时处于高电平状态

MCUCR = 0x0A; //设定INT0、INT1为下降沿触发

GICR = 0xC0; //使能INT0、INT1中断

SREG = 0x80; //使能总中断

while(1)

{

PORTB = 0x55; //让接在端口B上的LED显示01010101

delay_ms(t); //延时t个ms

PORTB = 0xAA; //让接在端口B上的LED显示01010101

delay_ms(t); //延时t个ms

}

}

//============中断函数(外部0)==========================

#pragma vector = INT0_vect

__interrupt void INT0_Server(void)

{

t = 100; //设定t的值为100次

}

//============中断函数(外部1)==========================

#pragma vector = INT1_vect

__interrupt void INT1_Server(void)

{

t = 500; //设定t的值为500次

}

把上述程序进行编译并下载到单片机中,可以看到结果与第二个示例中的完全一致。下面就来分析一下键盘中断的程序原理。

在分析程序之前,先来了解一下什么叫“外部中断”。前面已讲述过,在没有打扰的情况下,单片机的程序在封闭状态下自主运行,但如果在某一时刻需要响应一个外部事件(比如有按键被按下),这时就需要用外部中断。具体来讲,外部中断就是在单片机的一个引脚上,由于外部因素导致了一个电平的变化(比如由高变低),而通过捕获到这个变化,单片机内部自主执行的程序就被暂时打断,转而去执行相应的中断处理程序,执行完后又回到原来中断的地方继续执行原程序。这个引脚上的电平变化,就申请了一个外部中断事件,而这个能申请外部中断的引脚就是外部中断的触发引脚。在上面的例子中,可以看到两个按键S1、S2被接到了ATMega16的PD3和PD2引脚,而这两个引脚正是该单片机的两个外部中断(INT1和INT0)的触发引脚(第二功能)。当按键没有按下时,这两个引脚都为高电平(执行过PORTD=0xFF),当按键被按下时,引脚电平跳变为低电平,这时若单片机设置成允许中断申请,就会触发外部中断事件,从而转去执行中断服务程序。明白了这个过程之后,接下来就可以分析程序了。

程序执行后,主程序就一直在不停的运行while(1)内的这个死循环,让LED以t=500ms的初始值来交替闪烁,直到有外部中断来打断它。假设某一时刻按键S2被按下,这时由于引脚PD2上的电平突然被拉低,申请了一个外部中断0(INT0),这时的程序就转去执行外部中断0的中断服务程序(即__interrupt void INT0_Server(void)函数)。这时全局变量t的值被该函数重新赋值为100(即延时为100ms),完成后又回到主函数中的while(1)内去继续执行,因此LED闪烁的速度就变快了。

观察程序可看出,如果没有中断去调用中断服务子程序,在主程序中是没有语句去调动它的。也就是说如果没有外部中断,中断服务子程序(即__interrupt void INT0_Server(void)函数)是永远不会被执行的。这也说明,中断服务子程序是一类特殊的子程序,它不能被主程序调用,只能被中断申请调用。因此,中断服务子程序有它固定的格式和写法。在不同的编译系统中的写法不完全一样,下面给出IAR下的中断服务子程序的格式。

#pragma vector = INT0_vect

__interrupt void INT0_Server(void)

{

中断服务程序代码

}

以上是固定格式,除斜体部分外,其余部分不可更改。斜体部分中的INT0_vect表示中断的向量号,不同的中断名称不一样(原型在头文件iom16.h中)。斜体部分中的INT0_Server是中断函数的名称,是由开发者自己定义的。虽然可以自定义,但名称还是要取得“见名知义”,这样一看就知道是什么中断服务了。

单片机中段程序_单片机外部中断详解及程序相关推荐

  1. STM32开发 -- 外部中断详解

    如需转载请注明出处:https://blog.csdn.net/qq_29350001/article/details/87376865 在讲三轴加速度计的时候,提到外部中断.接下来就看看中断为什么这 ...

  2. 【STM32学习笔记】(13)——外部中断详解

    EXTI 简介         EXTI(External interrupt/event controller)-外部中断/事件控制器,管理了控制器的 20 个中断/事件线.每个输入线可以独立地配置 ...

  3. STM32F4_外部中断详解(EXTI)

    目录 1. EXTI 是什么? 2. EXTI主要特性 3. EXTI框图 3.1 外部中断/事件线映射 4. EXTI寄存器 4.1 中断屏蔽寄存器 EXTI_IMR 4.2 事件屏蔽寄存器 EXT ...

  4. STM32入门笔记03_EXTI外部中断详解+案例:红外对射计数、旋转编码器计数

    EXTI外部中断 中断的相关概念 中断源: 可以引起中断的事件称为中断源 中断: 在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成 ...

  5. STM32 外部中断详解(原理+配置代码)

    本文介绍了STM32基于标准外设库的外部中断配置,以及基于参考手册如何更加寄存器配置外部中断 文章目录 1 前言 2 STM32的外部中断 3 中断服务函数的映射关系 4 外部中断的配置 5 寄存器的 ...

  6. c语言 定时器作用,单片机定时器的作用及使用方法详解

    单片机定时器的作用及使用方法详解 单片机定时器在单片机的功能是很重要的,它一般被用作定时功能,来做定时检测.定时响应和定时控制,并且可以产生毫秒宽的脉冲信号来驱动步进电机.计时和计数的最终功能是通过计 ...

  7. 单片机-bmp280大气压强与温度传感器使用详解

    单片机-bmp280大气压强与温度传感器使用详解" 转载: https://blog.csdn.net/sunshinebooming/article/details/79637822 最近 ...

  8. 51单片机串口通信发送以及接收代码详解1

    #include <reg51.h> //实验现象:单片接收电脑发送的字符串,并发回给PC端的代码.//函数声明 void uart_init(void); void uart_seng_ ...

  9. 51单片机串口通信发送以及接收代码详解2

    #include <reg51.h> //实验现象:在电脑端没按下发送的时候,单片一直给电脑发送aaa字符串: //实验现象:在电脑端按下发送的时候,结束字符串aaa的发送代码,执行单片接 ...

最新文章

  1. 查询liunx上磁盘占用情况
  2. OpenStack Heat 如何来实现和支持编排
  3. Array.Copy 方法 总结
  4. C#中调用API函数RegisterHotKey注册多个系统热键
  5. [译]Java 垃圾回收介绍
  6. 电脑故障维修:新手必看的修电脑技巧!
  7. 2-修改软件源让pip下载更快
  8. C#处理JSON 数据
  9. 转载:数据库表结构设计方法及原则
  10. 海信空调拥抱变革 扎实技术+多样产品组合引爆市场
  11. php日期数组,关于php日期数组的用法汇总
  12. Linux 命令(37)—— free 命令
  13. poj_3468 线段树
  14. 陆军装备环境可靠性试验|GJB150A-2009
  15. 南航大学计算机专业硕士学历,南航计算机科学与技术学院导师介绍:戴群
  16. java实现获取阿里云短信验证码
  17. 读书笔记5.1——《让数字说话:审计,就这么简单》:孙含晖
  18. Python合并pdf文件
  19. 如何利用python调用API接口获取数据进行测试
  20. window10关闭磁盘bitlocker加密

热门文章

  1. 朝代更替中的上下五千年
  2. 串行传输和并行传输有什么区别?
  3. Mac下QQ缓存账号目录
  4. Wireshark网络抓包工具
  5. 《ZigBee学习》点播
  6. 一个简单的基于python图书管理系统
  7. 长尾分布下的分类问题
  8. 通过串口打印DS18B20采集到的温度
  9. JVM与垃圾回收笔记
  10. Docker镜像加载原理