精华内容
下载资源
问答
  • 案例分析:中断与查询相结合的方法是把系统中多个外部中断源按它们的重要程度进行排序,把其中最高级别的中断接到MCS-51的一个外部中断源输入端(例如接到 脚),其余的中断用线“或”的方法连接到另一个外部中断...

    20150323113254509.jpg

    案例分析:

    中断与查询相结合的方法是把系统中多个外部中断源按它们的重要程度进行排序,把其中最高级别的中断源接到MCS-51的一个外部中断源输入端(例如接到 脚),其余的中断源用线“或”的方法连接到另一个外部中断输入端( ),并同时接到一个I/O口,如图3中所示接到P1口。中断请求由硬件电路产生,而中断源的识别由程序查询来处理,查询顺序由中断源的优先级决定。图3为五个外部中断源的连接电路,其中设备1~4经OC门与 连接,并连接到P1.0~P1.3,均采用电平触发方式。设备0为最高级中断源,单独作为外部中断0的输入信号。这种办法扩展比较简单,但是当外部中断扩展的数量较多时,查询的时间比较长,导致程序的执行效率较低。

    程序代码:

    ORG 1000H

    LJMP INTR

    INTR: PUSH PSW ; 保护现场

    PUSH A

    JNB P1.0, IR1 ; P1.0引脚为0,转至设备1中断服务程序

    JNB P1.1, IR2 ; P1.1引脚为0,转至设备2中断服务程序

    JNB P1.2, IR3 ; P1.2引脚为0,转至设备3中断服务程序

    JNB P1.3, IR4 ; P1.3引脚为0,转至设备4中断服务程序

    INTR1: POP A ; 恢复现场

    POP PSW

    RETI ; 中断返回

    IR1: …… ; 设备1中断服务程序入口

    AJMP INTR1 ; 跳转到INTR1所指示的指令

    IR2: …… ; 设备2中断服务程序入口

    AJMP INTR1 ; 跳转到INTR1

    IR3: …… ; 设备3中断服务程序入口

    AJMP INTR1 ; 跳转到INTR1

    IR4: …… ; 设备4中断服务程序入口

    AJMP INTR1 ; 跳转到INTR1

    展开全文
  • 外部中断源系统设计

    4.9.1 定时器/计数器作为外部中断源的使用方法

    4.9.2 中断和查询结合的方法

    • 实际的应用中,两个外部中断请求源往往不够用,需对外部中断源进行扩充,如图4-11所示。系统有5个外部中断请求源IR0~IR4,高电平有效。
    • 最高级的请求源IR0直接接到AT89S52的一个外部中断请求输入端INT0*,其余4个请求源IR1~IR4通过各自的OC门(集电极开路门)连到AT89S52的另一个外中断源输入端 INT1* ,同时还连到P1口的P1.0~P1.3脚,供AT89S52查询。
    • 图4-11所示电路,除了IR0优先权级别最高外,其余4个外部中断源的中断优先权取决于查询顺序,中断优先权的高与低,取决于查询顺序。
    图4-11 中断和查询相结合的多外部中断请求源系统
    • 假设图4-11中的4个外设中有一个外设提出高电平有效的中断请求信号,则中断请求通过4个集电极开路OC门的输出公共点,即 INT1* 脚的电平就会变低。究竟是哪个外设提出的请求,要通过程序查询P1.0~P1.3引脚上的逻辑电平来确定
    • 本例假设某一时刻只能有一个外设提出中断请求,并设IR1~IR4这4个中断请求源的高电平可由相应的中断服务子程序清“0”,则中断服务子程序如下:
    • 查询法扩展外部中断源比较简单,但是扩展的外部中断源个数较多时,查询时间稍长。

    4.9.3 用优先权编码器扩展外部中断源

    • 当需要处理的外部中断源数目较多而又要求响应速度很快时,软件查询方法常常满足不了时间上的要求。因为在外部中断源很多的情况下,响应优先级最高和响应优先级最低的中断所需的查询时间可能相差很大。如果采用硬件对外部中断源进行优先级排队就可避免这个问题。下面介绍采用优先权编码器扩展外部中断源的方法。
    • 74LS148是一种优先权编码器,利用74LS148扩展AT89S52外部中断源的电路如图4-12所示,74LS148的真值表见表4-3。74LS148具有8个输入端“0~7”,用作8个外部中断请求IR0~IR7输入端,3个编码输出端A2~A0与单片机的P1.3~P1.1口线相连。
    图4-12 使用优先权编码器扩展8个外部中断源
    • 编码器输出控制端与单片机的外中断请求输入INT1*脚相连。在使能端为低电平的情况下,只要其8输入端中任一输入为低电平,就有一组相应的编码从A2~A0端输出,且同时编码器输出端输出低电平。
    • 如果8中断源IR0~IR7中有多个中断请求时(低有效),其优先权最高的一组编码就出现在单片机的P1.3~P1.1口线上,此时CS端为低电平,则AT89S52的INT1端就为低电平,若INT1*中断被允许,就可以响应外部中断源所提出的中断请求。
    • 例如,中断请求源IR1与IR4、IR6同时发出中断请求的情况下,GS端为低电平,向INT1发出中断请求,同时A2~A0端仅输出中断优先级最高的编码“001”,当单片机响应该中断请求信号后,进入INT1中断服务子程序,然后读入从P1.3~P1.1输入的编码“001”,从而去响应IR1*的中断请求。
    • 为了使程序转向各中断源的中断服务子程序,必须在AT89S52的INT1*的中断服务程序中编写如下引导程序:
    • 74LS148的输入端“7”(即IR0端)具有最高优先权,输入端“0”( IR7即端)优先权最低,这相当于给图中的8个外部中断请求源安排了一个中断优先级顺序。因此,当同时有多个中断源提出中断申请时,AT89S52只响应优先权最高的那个中断源的中断申请。
    • 上述电路结构简单,价格低廉,但该电路无法实现中断嵌套。即当一个中断申请正在被执行时,单片机不能响应别的中断源的中断申请(仅指IR0~IR7)。
    • 由于所扩展的外中断源都是向AT89S52提出中断申请,因此,这些外中断源在使用时应注意以下三个问题

      (1)中断响应时间
    • AT89S52的外中断响应时间在3~8个机器周期内,由于AT89S52在真正为所扩展的外中断源(IR0~IR7)服务之前需执行一段引导程序,因此对所扩展的外中断源而言,中断响应时间还要把执行引导程序所需的时间算在内。
      (2)中断申请信号低电平的宽度
    • 扩展的外部中断源,中断请求信号的低电平要有足够宽度,应一直保持到AT89S52将74LS148提供的编码取走为止,否则会出现错误。AT89S52读取这个编码要执行4条指令,需7个机器周期,若系统时钟频率为12MHz,则外中断请求信号低电平的宽度至少要大于15µs。
      (3)堆栈深度的问题
    • 由于AT89S52的堆栈只能设在片内RAM,字节有限,每次响应中断时都要把断点、现场的内容压入堆栈内,如果发生中断服务子程序中又调用子程序,则极容易发生堆栈溢出或侵占其它片内RAM内容,从而造成程序混乱,在使用中要特别注意。
    • 除上述3种方法外,还可采用可编程中断控制器接口芯片8259A来进行外部中断源的扩展,限于篇幅,不作介绍,读者可查阅相关资料。
    展开全文
  • STM32 中断原理及外部中断实现

    千次阅读 2021-01-18 15:39:09
    CM3支持256个中断,16个内核中断,240个外部中断,256级可编程中断设置。 STM32使用了其中一部分,16个内核中断,107系列有68个可屏蔽中断(103系列只有60个),16级可编程的中断优先级。 中断寄存器: ISER[8],...

    内容较充实,作为个人的学习记录

    NVIC 中断优先级管理

    Nested Vectored Interrupt Controller,嵌套向量中断控制器。

    CM3支持256个中断,16个内核中断,240个外部中断,256级可编程中断设置。

    STM32使用了其中一部分,16个内核中断,107系列有68个可屏蔽中断(103系列只有60个),16级可编程的中断优先级。




    中断寄存器

    • ISER[8],Interrupt Set-Enable Registers,中断使能寄存器组,用8个32位寄存器控制(256个可编程中断),每个位控制一个中断。由于STM32f103只有60个可屏蔽中断,于是只用了 ISER[0] 和 ISER[1] 64个中断中的前60位。

    • ISER[0] 的 bit0 至 bit31 对应中断0至31,ISER[1] 的 bit0 至 bit27 对应中断32至59,使能某个中断就将对应的 ISER 置1

    • ICER[8],Interrupt Clear-Enable Register,中断除能寄存器组。中断对应与ISER相同,但作用是置1清除中断使能

    • ISPR[8],Interrupt Set-Pending Register,中断挂起控制寄存器组。置1将正在进行的中断挂起,暂停等待执行,执行同级或更高级别的中断

    • ICPR[8],Interrupt Clear-Pending Register,中断解挂控制寄存器组,置1将挂起的中断解挂

    • IABR[8],Interrupt Active Bit Register,中断激活标志位寄存器组,只读寄存器为1表示该位对应的中断正在被执行

    • IP[240],Interrupt Priority Registers,中断优先级控制寄存器组,相当重要! STM32的中断分组与其密切相关。

      IP[240]有240个8bit寄存器组成,每个可屏蔽中断占用8bit,总共可表示240个可屏蔽中断,STM32f1使用其中60个,IP[59]至IP[0]分别对应中断59至0。每个可屏蔽中断只用高4位,分为抢占优先级响应优先级,抢占优先级在前、响应优先级在后,各占几位由SCB->AIRCR中的中断分组设置。采用库函数==NVIC_PriorityGroupConfig () ==配置。

      AIRCR
      如果组设置为3,则每个中断的中断优先寄存器高4位中前3位是抢占优先级,优先级级别0-7;低1位是响应优先级,优先级级别0-1。

      STM32的中断向量有抢占属性和响应属性,属性编号越小,优先级别越高。

      抢占属性是打断其他中断的属性,有这个属性就有嵌套中断。由库函数NVIC_IRQChannelPreemptionPriority() 进行参数配置。

      响应属性应用在抢占属性相同时(前提),两个中断向量的抢占优先级相同时,如果同时到达,则优先处理响应优先级高的中断。由库函数NVIC_IRQChannelSubPriority() 进行参数配置。




    库函数配置

    NVIC 中断管理函数声明在 misc.c 文件里


    1. 中断优先级分组函数 NVIC_PriorityGroupConfig()

    此函数在系统工程中只能被调用一次!一旦确定好中断分组就不能更改!

    目前了解到的在主函数中调用该函数


    F12 查看函数定义块:

    void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
    {
     	assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
    	SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
    }
    

    可以看到,这个函数通过设置 SCB->AIRCR 寄存器设置中断分组。

    补充:

    assert_param(),断言机制函数,在stm32f10x_conf.h文件中可以看到 assert_param() 是一个宏定义,作用就是检测传递给函数的参数是否是有效的参数,返回值是 0假 1真。


    中断优先组配置示例:分组值为2,2优先2抢占:

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    

    暂时看到的此函数调用都是在主函数里,以后看到其他程序结构再补充:
    main



    2. 中断初始化函数 NVIC_Init

    函数定义:

    void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
    

    查看结构体 NVIC_InitTypeDef 的成员变量:

    typedef struct
    {
     	uint8_t NVIC_IRQChannel; 
     	uint8_t NVIC_IRQChannelPreemptionPriority;
     	uint8_t NVIC_IRQChannelSubPriority; 
     	FunctionalState NVIC_IRQChannelCmd; 
    } NVIC_InitTypeDef;
    
    • NVIC_IRQChannel,定义初始化的是哪个中断,例如 USART1_IRQn
    • NVIC_IRQChannelPreemptionPriority,定义这个中断的抢占优先级别,级别数不超过2的“抢占优先级位数”次方。(一个是位数,一个是级别数)
    • NVIC_IRQChannelSubPriority,定义这个中断的响应优先级别,级别数不超过2的“响应优先级位数”次方。
    • NVIC_IRQChannelCmd,该中断是否使能

    IRQ全称为Interrupt Request,即是“中断请求”的意思


    中断初始化配置示例:

    NVIC_InitTypeDef NVIC_InitStructure;
    
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    //串口 1 中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;
    // 抢占优先级为 1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    // 响应优先级为 2
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    //IRQ 通道使能
    NVIC_Init(&NVIC_InitStructure); 
    //根据上面指定的参数初始化 NVIC 寄存器
    

    通常如果写外部中断时,此代码块放在 \exti.c\EXTI_Init() 函数内部,每个端口配置结束都需要一个NVIC_Init(&NVIC_InitStructure);




    小结

    中断优先级设置的步骤:

    1. 系统运行开始的时候设置中断分组。确定组号,也就是确定抢占优先级和子优先级的分配位数。调用函数为 NVIC_PriorityGroupConfig();
    2. 设置所用到的中断的中断优先级别,对每个中断调用函数为 NVIC_Init();




    STM32 外部中断

    基础知识

    STM32 外部 IO 口的中断功能

    文件: stm32f10x_exti.c/h

    每个 IO 口都可以作为外部中断的中断输入口,支持19个外部中断/事件请求,每个中断设有状态位、独立的触发/屏蔽设置。

    19个外部中断为:

    • 线 0-15:对应外部 IO 口的输入中断 (供 IO 口使用的中断线)
    • 线 16 :连接到PVD输出(Programmable Votage Detector,可编程电压监测器)
    • 线 17 :连接到RTC闹钟事件
    • 线 18 :连接到USB唤醒事件

    映射方式:

    映射关系
    每个中断线对应最多7个IO口,但每次只能连接到一个IO口上,利用选择器的配置来决定中断线配置到哪个IO口上去。



    库函数配置

    1. 映射关系配置 GPIO_EXTILineConfig()

    外部中断端口映射配置示例 (GPIOE_2 与 EXTI_2):

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
    


    2. 中断初始化 EXTI_Init()

    void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
    //结构体函数参数
    

    查看一下结构体:

    typedef struct
    {
     	uint32_t EXTI_Line; 
     	EXTIMode_TypeDef EXTI_Mode; 
     	EXTITrigger_TypeDef EXTI_Trigger; 
     	FunctionalState EXTI_LineCmd; 
    }EXTI_InitTypeDef;
    

    有4个需要设置的参数:

    1. 中断线标号,EXTI_Line0~EXTI_Line15
    2. 中断模式,中断 EXTI_Mode_Interrupt 和事件 EXTI_Mode_Event
    3. 触发方式,下降沿触发 EXTI_Trigger_Falling,上升沿触发 EXTI_Trigger_Rising,任意电平(上升沿和下降沿)触发EXTI_Trigger_Rising_Falling
    4. 使能,ENABLE

    中断事件的区别


    简而言之,中断是需要经过芯片内部程序处理,然后跳转的中断程序
    事件是检测到某一动作(电平边沿)触发事件发生了,进而由提前设置好的相应的联动硬件自动完成产生的结果


    中断是红线
    事件是绿线中断和事件


    外部中断初始化配置示例:

    EXTI_InitTypeDef EXTI_InitStructure;
    //定义结构体
    EXTI_InitStructure.EXTI_Line=EXTI_Line4;
    //中断线4
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    //中断模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    //下降沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    //使能
    EXTI_Init(&EXTI_InitStructure); 
    //根据 EXTI_InitStruct 中指定的参数初始化外设 EXTI 寄存器
    


    3. 设置中断线2的中断优先级

    优先级配置见第一部分NVIC的配置

    NVIC_InitTypeDef NVIC_InitStructure;
    //定义NVIC结构体
    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; 
    //使能按键外部中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; 
    //抢占优先级 2,
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; 
    //响应优先级 2
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    //使能外部中断通道
    NVIC_Init(&NVIC_InitStructure); 
    //中断优先级分组初始化
    


    4. 中断服务函数

    STM32一共15个IO口外部中断线,共有6个中断函数:

    EXPORT EXTI0_IRQHandler
    EXPORT EXTI1_IRQHandler
    EXPORT EXTI2_IRQHandler
    EXPORT EXTI3_IRQHandler
    EXPORT EXTI4_IRQHandler
    EXPORT EXTI9_5_IRQHandler
    EXPORT EXTI15_10_IRQHandler

    0-4每个中断线对应一个中断函数,5-9共用EXTI9_5_IRQHandler,10-15共用EXTI15_10_IRQHandler

    当多线共用一个处理函数的时候,就必须写EXTI_GetITStatus()判断到底是哪一线中断请求


    • 1. ITStatus EXTI_GetITStatus();

    用在中断服务函数的开头,判断中断是否发生

    EXTI_GetFlagStatus()与之的区别
    EXTI_GetITStatus() 函数中会先判断这种中断是否使能,使能了才去判断中断标志位
    而EXTI_GetFlagStatus() 直接用来判断状态标志位


    • 2. EXTI_ClearITPendingBit(EXTI_Line0);

    中断服务函数结束之前调用,清除某中断线上的中断标志位

    EXTI_ClearFlag(),与之功能相同


    常用的中断服务函数格式:

    void EXTI2_IRQHandler(void)
    {
    	if(EXTI_GetITStatus(EXTI_Line2)!=RESET)
    	//判断某个线上的中断是否发生 
    	{
    		中断逻辑…
    		
    		EXTI_ClearITPendingBit(EXTI_Line2); 
    		//清除 LINE 上的中断标志位 
    	} 
    }
    


    外部中断配置示例

    1. exit.c

    包含4个函数:

    • EXTI_Init()

      外部中断初始化,(以按键功能为例):

    void EXTIX_Init(void)
    {
     EXTI_InitTypeDef EXTI_InitStructure;
     NVIC_InitTypeDef NVIC_InitStructure;
     //调用结构体
    
    1. 调用 KEY_Init 函数,来初始化外部中断输入的 IO 口。
    KEY_Init();
    //初始化按键对应 io 模式
    
    1. 调用RCC_APB2PeriphClockCmd()函数来使能复用功能时钟。
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    //外部中断,需要使能 AFIO 时钟
    
    1. 接着配置中断线和 GPIO 的映射关系。
    //GPIOC.5 与中断线5映射
      	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
    
    1. 然后初始化中断线。
    EXTI_InitStructure.EXTI_Line=EXTI_Line5;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    
    1. 中断初始化、配置优先级
     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;					
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								
     NVIC_Init(&NVIC_InitStructure); 
    
    • EXTI0_IRQHandler()

    中断处理函数

    void EXTI0_IRQHandler(void)
    {
      delay_ms(10);   
    	if(WK_UP==1)//WK_UP在key.h文件中定义
    	{	  
    		LED0=!LED0;//LED0在led.h文件中定义
    		LED1=!LED1;	
    	}
    	EXTI_ClearITPendingBit(EXTI_Line0); 
    	//清除EXTI0线路挂起位
    }
    
    • EXTI9_5_IRQHandler()
    • EXTI15_10_IRQHandler()




    小结

    使用 IO 口外部中断的一般步骤:

    1. 初始化 IO 口为输入
    2. 开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。
    3. 初始化线上中断(EXTI),设置触发条件等。
    4. 配置中断分组(NVIC),并使能中断。
    5. 编写中断服务函数。
    展开全文
  • IE0(TCON.1),外部中断0中断请求标志位。 IT1(TCON.2),外部中断1触发方式控制位。 IE1(TCON.3),外部中断1中断请求标志位。 TF0(TCON.5),定时/计数器T0溢出中断请求标志位。 TF1(TCON.7),定时/计数器...

    1.中断系统的概念

    1.1中断的概念

    CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生);

    CPU暂时中断当前的工作,转去处理事件B(中断响应中断服务);

    待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断

    图片来自普中科技

    1.2中断系统的概念

    引起CPU中断的根源,称为中断源

    中断源向CPU提出的中断请求。CPU暂时中断原来的事务A,转去处理事件B。对事件B处理完毕后,再回到原来被中断的地方(即断点),称为中断返回。实现上述中断功能的部件称为中断系统

    1.3中断系统的优点

    • 解决了快速主机与慢速I/O设备的数据传送问题
    • 分时操作。CPU可以分时为多个I/O设备服务,提高了计算机的利用率;
    • 实时响应。CPU能够及时处理应用系统的随机事件,系统的实时性大大增强;
    • 可靠性高。CPU具有处理设备故障及掉电等突发性事件能力,从而使系统可靠性提高。

    1.4我们要说的三种中断源

    89C51/52的中断系统有5个中断源 ,2个优先级,可实现二级中断嵌套 。

    分别是外部中断0、计数/定时器中断0、外部中断1、计数/定时器中断1、串行通信中断。

    我们以外部中断0、计数/定时器中断0和串口通信中断来说说。

    下面这张图很关键,无论是那个中断都要走这个流程
    在这里插入图片描述

    TCON 定时/计数器控制寄存器
    在这里插入图片描述

    • IT0(TCON.0),外部中断0触发方式控制位
      当IT0=0时,为电平触发方式。
      当IT0=1时,为边沿触发方式(下降沿有效)。

    • IE0(TCON.1),外部中断0中断请求标志位

    • IT1(TCON.2),外部中断1触发方式控制位

    • IE1(TCON.3),外部中断1中断请求标志位

    • TF0(TCON.5),定时/计数器T0溢出中断请求标志位

    • TF1(TCON.7),定时/计数器T1溢出中断请求标志位

    IE 中断允许控制寄存器,CPU对 中断系统 所有中断以及某个中断源的开放和屏蔽是由中断允许寄存器IE控制的。
    在这里插入图片描述

    • EX0(IE.0),外部中断0允许位;
    • ET0(IE.1),定时/计数器T0中断允许位;
    • EX1(IE.2),外部中断0允许位;
    • ET1(IE.3),定时/计数器T1中断允许位;
    • ES(IE.4),串行口中断允许位;
    • EA (IE.7), CPU中断允许(总允许)位。

    IP 中断优先级控制寄存器
    这个我们一般不改,用缺省值,
    外部中断0 > 计数/定时器中断0 > 外部中断1 > 计数/定时器中断1 > 串行通信中断
    为什么是这样的排序呢?因为在单片机的ROM他们的入口地址也是按照这个顺序排序的。
    在这里插入图片描述

    要记住的是中断号,这在后面很重要
    在这里插入图片描述
    所以如果要有一个中断产生,要符合这样的顺序,以下三条同时满足时,CPU才有可能响应中断。

    在这里插入图片描述

    51单片机的中断优先级有三条原则

    1. CPU同时接收到几个中断时,首先响应优先级别最高的中断请求。
    2. 正在进行的中断过程不能被新的同级或低优先级的中断请求所中断
    3. 正在进行的低优先级中断服务,能被高优先级中断请求所中断

    为了实现上述后两条原则,中断系统内部设有两个用户不能寻址的优先级状态触发器。其中一个置1,表示正在响应高优先级的中断,它将阻断后来所有的中断请求;另一个置1,表示正在响应低优先级中断,它将阻断后来所有的低优先级中断请求。

    2.外部中断

    2.1 外部中断0 代码示范

    /* 用外部中断0来控制led灯闪烁 */
    #include<reg51.h>
    
    typedef unsigned char u8;
    typedef unsigned int u16;
    
    sbit led = P2^0;
    sbit K3 = P3^2;
    
    void delay(u16 i)
    {
    	while(i--);
    }
    
    void Int0Init() //初始化函数,你也可以写在主函数里面
    {
    	IT0 = 1; //TCON寄存器中,IT0是外部中断0 的触发方式控制位,ITO = 1,下降沿有效触发
    	EX0 = 1; //IE寄存器中,外部中断0允许位置1
    	EA = 1;  //IE寄存器中,CPU中断允许总开关
    }
    
    void main()
    {
    	Int0Init();//初始化函数
    	while(1); //在这里等待被外部中断0打断
    }
    
    void Int0() interrupt 0   //外部中断0的中断函数,函数名可以定义,interrupt 后面的中断号不能出错
    {
    	delay(1000);//按键消抖
    	if(K3==0)// k3被按下
    	{
    		led = ~led;
    	} 
    }
    

    2.2 外部中断 分析

    在这里插入图片描述
    可以看到,外部中断是非常符合上面这个中断流程的

    打个比方,我要在床上吹风扇,我自己的电线不够长,我要用我室友的插排。首先我先要和室友请求,室友同意我就插上去了,最后需要室友把总开关打开,我才能吹到风扇。

    3.计数/定时器中断

    3.1 计数/定时器中断0 代码示范

    #include<reg51.h>
    
    typedef unsigned char u8;
    typedef unsigned int u16;
    
    sbit led = P2^0;
    static u16 i;
    
    void Time0Init() //初始化函数,你也可以写在主函数里面
    {
    	TMOD|=0x01; //工作方式寄存器TMOD 
    	TH0 = 0xFC;  //给寄存器赋值 
    	TL0 = 0x66;
    	TR0 = 1;    //中断请求标志,置位1,启动定时/计数器工作 (控制寄存器TCON) 
    	ET0 = 1;    //计数器中断0允许控制位置1(中断允许寄存器IE) 
    	EA = 1;		//IE寄存器中,CPU中断允许总开关EA置1.
    	
    } 
    
    void main()
    {
    	Time0Init(); //初始化函数
    	while(1)
    	{
    		if(i == 1000)//每1000ms led状态翻转一次
    		{
    			i = 0;
    			led = ~led;
    		}
    	}
    	
    }
    
    void Time0() interrupt 1
    {
    
    	TH0 = 0xFC; //给寄存器赋值
    	TL0 = 0x66;
    	i++;  //每次加1,一次是 1ms
    }
    

    3.2 计数/定时器 分析

    其实根据我们上面的分析,我们只要知道下面这段初始化代码的含义就可以了

    TMOD|=0x01; //工作方式寄存器TMOD 
    TH0 = 0xFC;  //给寄存器赋值 
    TL0 = 0x66;
    

    在这里插入图片描述

    3.2.1 计数/定时器的概念

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

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

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

    3.2.2 计数/定时器的工作原理

    定时/计数器实质上是一个加1计数器。它随着计数器的输入脉冲进行自加1,也就是每来一个脉冲,计数器就自动加1,,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。

    可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值。

    这个原理决定了我们给计数/定时器的16位寄存器赋值的问题。

    3.2.3 计数/定时器的结构

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

    在这里插入图片描述

    TMOD 定时/计数器工作方式寄存器, 低四位用于T0,高四位用于T1.
    在这里插入图片描述
    GATE是门控位, 通常我们让GATE等于0,这样方便一些。

    • GATE=0时,用于控制定时器的启动是否受外部中断源信号的影响。只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;

    • GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚INT0/1也为高电平时,才能启动定时/计数器工作。即此时定时器的启动条件,加上了INT0/1引脚为高电平这一条件。

      C/T :定时/计数模式选择位。C/T =0为定时模式;C/T =1为计数模式。
      M1M0:工作方式设置位。定时/计数器有四种工作方式。
      在这里插入图片描述

    TIP:主要需要掌握方式1和方式2

    • 方式1一般是我们定时/计数器中断常用的。
    • 方式2一般是我们在串口通信时使用,用来计算频率。

    TCON 定时/计数器控制寄存器
    TCON的低4位用于控制外部中断,已在前面介绍。TCON的高4位用于控制定时/计数器的启动和中断申请。
    在这里插入图片描述

    • TF1(TCON.7):T1溢出中断请求标志位T1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时查询TF1的状态。 所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。
    • TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。
    • TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1类同。
    • TR0(TCON.4):T0运行控制位,其功能与TR1类同。

    这里主要说一下方式1和方式2
    方式1
    方式1的计数位数是16位,由TL0作为低8位,TH0作为高8位,组成了16位加1计数器 。
    TL0的8位溢出时向TH0进位,TH0溢出时,置位TCON中的TF0标志,向CPU发出中断请求。

    在这里插入图片描述

    在这里插入图片描述
    方式2
    方式2为自动重装初值的8位计数方式。
    计数个数与计数初值的关系为:X=2^8-N
    工作方式2特别适合于用作较精确的脉冲信号发生器。

    3.2.4 计数/定时器初值的设置

    51单片机内部时钟频率是外部时钟的12分频。也就是说当外部晶振的频率输入到单片机里面的时候要进行12分频。比如说你用的是12MHZ的晶振,那么单片机内部的时钟频率就是12/12MHZ,当你使用12MHZ的外部晶振的时候。

    机器周期=1/1M=1us。而我们定时1ms的初值是多少呢,1ms/1us=1000

    也就是要计数1000个数,初值=65535-1000+1(因为实际上计数器计数到66636才溢出)=64536=FC18H

    我们一般使用定时器工具,比较轻松就可以设置初值了。(需要这个工具的朋友可以在评论区留下邮箱)

    在这里插入图片描述

    3.3 小练笔

    用 定时计数器中断 和 动态八段数码管 做一个两位秒表:https://blog.csdn.net/m0_50679156/article/details/120097808

    4.串行口中断

    4.1串行口中断通信 代码示范

    /*pc连接51单片机,用串口助手发送一个数字会加1返回*/
    #include<reg52.h>
    
    typedef unsigned char u8;
    typedef unsigned int u16;
    
    void UstartInit()//串口初始化设置 
    {
    	TMOD = 0x20; //确定T1的工作方式(设置GATE,C/T非,M1M0 = 10 方式2 ,高四位用于T1) 
    	TH1 = 0xF4;  //高8位 
    	TL1 = 0xF4;  //低8位 
    	PCON = 0x80; //PCON中只有一位SMOD(最高位)与串行口工作有关 ,SMOD为1是波特率提高一倍 
    	TR1 = 1;     // 启动定时/计数器T1 定时或计数 
    	SCON = 0x50; // 0101 0000 设置串行口工作方式,方式1(10位异步收发器(8位数据)) 
    	ES = 1;     // 串行口中断允许 (IE寄存器)
    	EA = 1;     // CPU 中断总允许位 (IE寄存器)
    }
    
    void main()
    {
    	UstartInit();
    	while(1);
    }
    
    void startInit() interrupt 4
    {
    	u8 ReceiveData;
    	ReceiveData = SBUF;
    	RI = 0; //准备下次接受 
    	SBUF = ReceiveData + 1;
    	while(!TI);
    	TI = 0; //准备下次发送 
    } 
    

    在这里插入图片描述

    4.2串行口中断通信分析

    对于串口通信不是我们这篇博客分析的重点,主要说一下串行口中断

    4.2.1 80C51串行口的结构

    在这里插入图片描述

    有两个物理上独立的接收、发送缓冲器SBUF,它们占用同一地址99H
    这个概念很重要,SBUF是像是李信,光信和暗信是一个英雄,但是有不同的技能和外观。

    下面代码中的SBUF,一个是光信,一个是暗信,你懂了么?会心一笑的请点赞。

    void startInit() interrupt 4
    {
    	u8 ReceiveData;
    	ReceiveData = SBUF;
    	RI = 0; //准备下次接受 
    	SBUF = ReceiveData + 1;
    	while(!TI);
    	TI = 0; //准备下次发送 
    } 
    

    接收器是双缓冲结构 ;发送缓冲器,因为发送时CPU是主动的,不会产生重叠错误。

    4.2.2 使用到的新寄存器

    SCON(串行口控制寄存器) 是一个特殊功能寄存器,用以设定串行口的工作方式、接收/发送控制以及设置状态标志

    这个寄存器完全为串行口服务

    在这里插入图片描述

    SM0SM1为工作方式选择位,可选择四种工作方式
    在这里插入图片描述

    • SM2多机通信控制位,主要用于方式2和方式3
      当接收机的SM2=1时可以利用收到RB8来控制是否激活RI(RB8=0时不激活RI,收到的信息丢弃;RB8=1时收到的数据进入SBUF,并激活RI,进而在中断服务中将数据从SBUF读走)。
      当SM2=0时,不论收到的RB8为0和1,均可以使收到的数据进入SBUF,并激活RI(即此时RB8不具有控制RI激活的功能)。通过控制SM2,可以实现多机通信。
      在方式0时,SM2必须是0。在方式1时,如果SM2=1,则只有接收到有效停止位时,RI才置1。
    • REN允许串行接收位。由软件置REN=1,则启动串行口接收数据;若软件置REN=0,则禁止接收。
    • TB8在方式2或方式3中,是发送数据的第九位,可以用软件规定其作用。可以用作数据的奇偶校验位,或在多机通信中,作为地址帧/数据帧的标志位。
      在方式0和方式1中,该位未用。
    • RB8在方式2或方式3中,是接收到数据的第九位,作为奇偶校验位或地址帧/数据帧的标志位在方式1时,若SM2=0,则RB8是接收到的停止位。
    • TI发送中断标志位在方式0时,当串行发送第8位数据结束时,或在其它方式,串行发送停止位的开始时,由内部硬件使TI置1,向CPU发中断申请。在中断服务程序中,必须用软件将其清0,取消此中断申请
    • RI接收中断标志位。在方式0时,当串行接收第8位数据结束时,或在其它方式,串行接收停止位的中间时,由内部硬件使RI置1,向CPU发中断申请。也必须在中断服务程序中,用软件将其清0,取消此中断申请

    PCON 电源控制寄存器,中只有一位SMOD与串行口工作有关

    在这里插入图片描述
    SMOD(PCON.7) 波特率倍增位。在串行口方式1、方式2、方式3时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍。复位时,SMOD=0。


    我们主要使用方式1来进行串口通信,所以我们就主要讲讲方式1

    方式1是10位数据的异步通信口。TXD为数据发送引脚,RXD为数据接收引脚,传送一帧数据的格式如图所示。其中1位起始位,8位数据位,1位停止位。

    在这里插入图片描述
    1、方式1输出:
    在这里插入图片描述

    2、方式1输入:

    在这里插入图片描述
    用软件置REN(允许串行接收位)为1时,接收器以所选择波特率的16倍速率采样RXD引脚电平,检测到RXD引脚输入电平发生负跳变时,则说明起始位有效,将其移入输入移位寄存器,并开始接收这一帧信息的其余位。
    接收过程中,数据从输入移位寄存器右边移入,起始位移至输入移位寄存器最左边时,控制电路进行最后一次移位。当RI(接收中断标志位)=0,且SM2(多机通信控制位)=0(或接收到的停止位为1)时,将接收到的9位数据的前8位数据装入接收SBUF,第9位(停止位)进入RB8,并置RI(接收中断标志位)=1,向CPU请求中断。

    4.2.3 波特率的设置

    在串行通信中,收发双方对发送或接收数据的速率要有约定。通过软件可对单片机串行口编程为四种工作方式,其中方式0和方式2的波特率是固定的,而方式1和方式3的波特率是可变的,由定时器T1的溢出率来决定。

    串行口的四种工作方式对应三种波特率。由于输入的移位时钟的来源不同,所以,各种方式的波特率计算公式也不相同。

    方式0的波特率 = fosc/12
    方式2的波特率 =(2SMOD/64)· fosc
    方式1的波特率 =(2SMOD/32)·(T1溢出率)
    方式3的波特率 =(2SMOD/32)·(T1溢出率)

    当T1作为波特率发生器时,最典型的用法是使T1工作在自动再装入的8位定时器方式(即方式2,且TCON的TR1(定时/计数器1运行控制位)=1,以启动定时器)。
    这时溢出率取决于TH1中的计数值。T1 溢出率 = fosc /{ 12×[256 -(TH1)]}
    在单片机的应用中,常用的晶振频率为:12MHz和11.0592MHz。所以,选用的波特率也相对固定。常用的串行口波特率以及各参数的关系如表所示。

    在这里插入图片描述

    4.3串口如何使用

    串行口工作之前,应对其进行初始化,主要是设置产生波特率的定时器1串行口控制中断控制
    具体步骤如下:

    1. 确定T1的工作方式(编程TMOD寄存器);
    2. 计算T1的初值,装载TH1、TL1;
    3. 启动T1(编程TCON中的TR1位);
    4. 确定串行口控制(编程SCON寄存器);
    5. 串行口在中断方式工作时,要进行中断设置(编程IE、IP寄存器)。

    5.参考资料

    1. 普中科技A2开发板参考资料
    2. 《单片机原理及应用》(第四版)
    3. 《新概念51单片机C语言教程》郭天祥编著
    4. 单片机原理及应用课堂笔记
    展开全文
  • STM32F103外部中断实现

    2021-10-13 19:43:44
      中断是单片机中最重要的一个功能了,通过中断可以提高程序的运行效率,可以是单片机及时的响应各种外设的请求。STM32系列单片机的中断主要由嵌套向量中断控制器来管理。   嵌套向量中断控制器特性如下: 68个...
  • 6.STC15W408AS单片机外部中断

    千次阅读 2021-07-15 09:29:24
    STC15W408AS单片机有4个外部中断,它们分别是:外部中断0(INT0)、外部中断1(INT1)、外部中断2(INT2)、外部中断3(INT3)。 外部中断0(INT0)和外部中断1(INT1)触发有两种触发方式,上升沿或下降沿均可触发方式 和仅...
  • 每按一下按键(外部 0 中断 P3.2),8 个 LED 从下向上流水 1 次。 电路图: 代码: #include<reg51.h> #include<intrins.h> void delay(unsigned int m) { unsigned int i; for(;m>0;m--) { ...
  • 利用外部中断0实现数码管按键加减

    千次阅读 多人点赞 2021-03-24 09:25:01
    利用外部中断0实现数码管按键加减 实现的结果: # 程序: /*程序功能:在单片机的INT0,INT1引脚分别接两个按钮,通过按扭向单片机申请中断 中断一次实现变量加1或减1,并将结果显示在数码管*/ #include <reg51.h...
  • 51单片机外部中断拓展(两个以上的外部中断

    千次阅读 多人点赞 2021-05-14 14:17:03
    在很多单片机中,外部中断的个数都是有限的,而很多现实场景需要有多个外部中断同时进行,这时候单片机自带的外部中断端口可能就不够用了,那么,怎么解决这个问题呢,本文将会用最典型的51单片机为例,介绍两种较...
  • 要学习51单片机中断的朋友,拥有这一篇博文就够了,深入浅出,里面包含了寄存器,外部中断、定时器中断、中断嵌套等的讲解,还有代码实战。快一万字,写得不容易,还请大家点赞支持一下,后续持续更新(一)寄存器1....
  • 设置中断优先级寄存器,当有外部中断0请求中断时,中断程序执行发光二极管程序,在此过程中,外部中断1也有中断请求外部中断0的中断程序将被中断去执行外部中断1的中断程序(数码管加1显示程序)。 #include<...
  • 51单片机——外部中断

    千次阅读 2021-04-16 12:35:06
    一、外部中断 1.1 中断 关于中断的概念在上一篇博客中已经提到了。(传送门:51单片机入门教程(5)——定时器中断) 中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并...
  • 外部中断执行流程

    2021-10-22 18:45:44
    中断请求芯片->CPU->中断向量表(RAM)->中断程序 1、设备向中断请求芯片发出中断请求 2、中断请求芯片根据优先级排序选择响应优先级较高的中断 3、根据响应的中断引脚在其内部存储器取与引脚对应位置的中断...
  • STM32F407的中断控制器支持22个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F407的22个外部中断为:EXTI线0~15:对应外部IO口的输入中断。EXTI线16:连接到PVD输出。EXTI...
  • STM32实现外部中断

    2021-08-27 17:14:26
    如何配置外部中断,一共分为五步。 1) 初始化用来产生中断的 GPIO; 2) 配置 NVIC; 3) 初始化 EXTI; 4) 选择 EXTI 的信号 5) 编写中断服务函数; 下面进行具体操作。 初始化用来产生中断的 GPIO 1.打开...
  • 实验板子:tiny210(芯片:s5pv210)实验目的:通过外部中断操作两个按键实现对LED灯的亮灭控制步骤:①初始化GPIO端口,使GPIO为外部中断状态;(寄存器:GPxxCON)例:②配置外部中断触发模式,上升沿触发,下降沿触发...
  • STM32-外部中断

    2021-10-02 22:07:22
    1 外部中断概述 EXTI(External interrupt/event controller)—外部中断/事件控制器,和在STM32NVIC中断优先级管理(中断向量表)中讲述的CM3内核的外部中断不同。特指的是,在中断向量表中的EXTI的外部中断。STM...
  • 2.21实例功能前面例子中分别介绍了按键控制发光二极管的亮灭,但是我们注意到,在程序中需要一直检测按键的状态,这样明显的浪费了单片机的资源,...在本例中,通过利用外部中断实现单片机对按键事件的响应和处理...
  • 外部中断

    2021-06-19 17:20:19
    课程名称: 单片机原理与接口技术 实验项目名称:中断系统 实验时间: ...1、51单片机的P0口连接数码管的字段, P2口连接数码管的位段,K1独立按键连接外部中断0的请求信号输入引脚P3.2,要求中断一次计
  • STM32外部中断

    2021-05-22 21:58:11
    STM32的中断控制器支持19个外部中断/事件请求: 线0~15:对应外部IO口的输入中断 线16:连接到PVD输出 线17:连接到RTC闹钟事件 线18:连接到USB唤醒事件 每个外部中断线可以独立的配置触发方式(上升沿,下降沿或
  • STM32中断分组STM32 的每一个GPIO都能配置成一个外部中断触发,这点也是 STM32 的强大之处。STM32 通过根据引脚的序号不同将众多中断触发分成不同的组,比如:PA0,PB0,PC0,PD0,PE0,PF0,PG0为第一组,那么...
  • 外部中断常用库函数 外部中断的一般配置步骤 实验代码
  • GPIO外部中断

    2020-12-30 17:15:22
    STM32的“中断”机制很复杂,看了PM(Cortex-m4)和RM,对它只了解了一个大概。首先,与“中断”相关的术语就有 exception, interrupt, event 三个。Cortex-m4核中包含一个NVIC控制器,用于处理 exception。而 ...
  • 外部中断源2个 1.INT0 — 由P3.2端口控制引入,低水平或者下降沿引起。(下降沿就是给5V后给0V形成下降电压) 2.INT1 —由P3.3端口控制引入,低水平或者下降沿引起。 (这两个中断标志与中断方式由特殊功能寄存器...
  • 先来说一说“中断请求”的实际场景,当页面有多个tab页签时,每次切换页签都会去请求数据,频繁的切换就会去请求很多次,比如A页签切换到B页签,A页签请求完全是不必要的,这时候可以在切换时中断请求。...
  • 外部中断0(INT0)和外部中断1(INT1)均有两种触发方式:上升沿或下降沿均可触发方式和仅下降沿触发方式。 因为引脚的状态有0和1,0代表低电平,1代表高电平。从高电平变为低电平,这种电平突然下降的地方叫做下降...
  • 按键 K1 用于触发外部中断 0 main.c /** * Interrupt Registers Definition */ sfr IE = 0xA8; /* Interrupt Enable Register */ /** * Interrupt Registers Bits Definition */ /** IE */ #define GLOBAL_IE_...
  • 在proteus中绘制单片机和可编程中断控制器8259实现通过4个按键触发中断作为8259的中断源输入,来控制单片机P3.3~P3.5的状态反转,数码管计数器的值加1,直到显示数字9,重新回0计数。
  • LPC2000系列——LPC2124(定时器、外部中断实现流水灯(跑马灯) 文章目录LPC2000系列——LPC2124(定时器、外部中断实现流水灯(跑马灯)开发环境配置环境引脚连接及结果展示源码本次课设可能用到的部分需要...
  • 13 . 外部中断实验

    2021-05-13 10:50:46
    STM32F10x 外部中断/事件控制器(EXTI)包含多达20 个用于产生事件/中断请求的边沿检测器。EXTI 的每根输入线都可单独进行配置,以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发),还...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 85,584
精华内容 34,233
关键字:

外部中断源如何实现中断请求