精华内容
下载资源
问答
  • 51在上电后,PSW的RS两个位默认为0,也即51默认使用工作寄存器组BANK 0,在默认状态下,对于普通的C语言函数,其传参、申请局部变量、导出函数的返回值等功能...对于51的中断服务函数,它没有形参,也不用返回值,...

    注:本文参考自https://blog.csdn.net/q2631837575/article/details/78776567

    51在上电后,PSW的RS两个位默认为0,也即51默认使用工作寄存器组BANK 0,在默认状态下,对于普通的C语言函数,其传参、申请局部变量、导出函数的返回值等功能,keil将其翻译成汇编以后,肯定要使用R0~R7;对于51的中断服务函数,它没有形参,也不用返回值,但是一般肯定有局部变量,这时就需要用到R0~R7了;试想,在执行普通函数时,R0~R7已经被使用了,在执行普通函数时,一旦发生中断,而中断函数也需要使用R0~R7,那怎么办?我们最先想到的是,在执行中断服务函数前先把R0~R7入栈(像累加器A、状态PSW等也要入栈这个不用说大家也知道),在中断服务完成后把R0~R7出栈,然后就能恢复现场,回到普通函数中去了,但是这8个Rn不能直接入栈,PUSH R0这样的语句是不允许的,要想R0入栈只能用两句:MOV A R0; PUSH A;这样的后果是,每次工作寄存器入栈都需要2*8=16条汇编语句才能完成,再加上A、B、PSW等寄存器入栈等,相当于每次中断都要消耗大量的时间来出栈入栈,影响程序速度。如何解决这一问题呢?51提供了这样一种机制,切换工作寄存器组,过程如下:

        普通函数的执行过程中正在使用BANK0的R0~R7,执行过程中突然发生了中断,而中断函数也想使用R0~R7,在执行中断服务函数前,我们切换工作寄存器组,切换的具体方法就是直接修改PSW的RS两个比特位,而不必把BANK 0入栈,本文开头的例子中using 2,就是说,在进入外部中断0的服务函数前,先入栈CPU寄存器,再把工作寄存器组由0切换成2,在退出中断服务后,先由BANK2切换回BANK0,并弹出CPU寄存器,由于BANK0和BANK2处在不同的RAM空间,互相不干扰,切换回BANK0之后就把那个普通函数的现场给恢复了。


    补图(过程图)

    展开全文
  • 中断服务函数

    千次阅读 2020-01-17 14:44:45
    中断问题也是面试嵌入式岗位时,面试官比较喜欢拷问的问题之一,作为一个嵌入式开发人员,自然少不了与中断打交道,裸机程序中...4.不要在中断函数中使用printf函数,会带来重入和性能问题 中断并不是程序一开始...

     

    中断问题也是面试嵌入式岗位时,面试官比较喜欢拷问的问题之一,作为一个嵌入式开发人员,自然少不了与中断打交道,裸机程序中作为前台服务程序,发挥着重要的作用。

    中断服务函数应该注意的四大点:


    1.中断服务函数不能传入参数;

    2.中断服务函数不能有返回值;

    3.中断服务函数应做到短小精悍;

    4.不要在中断函数中使用printf函数,会带来重入和性能问题


    中断并不是程序一开始就判断好会在那里发生,或者会在什么时候发生。中断发生的完全是随机的,中断源连接到硬件,由硬件来产生触发中断,而众所周知,函数、函数内变量等大部分是存储在堆栈区,但是中断是随机产生的,且由硬件告知,那么去哪分配存储位置,自然一二点是无法满足的。

    第三点,中断内应做到短小精悍,这个就要求我们要动动脑筋了,但是很多东西在没有需求的情况下,光靠乱猜想挺难的。我在一本书上看到一个作者写了一段关于中断处理代码的,就觉得很好,值得学习(作者也是源于项目的需求,然后动手)。


    //定义一个队列结构体,用于存储中断类型

    typedef struct tagIntQueue

    {

        int Type;   //中断类型

        struct tagIntQueue *next;

    }IntQueue;

    IntQueue IpIntQueueHead;

     

    __interrupt ISRexample()

    {

        int Type;

        Type = GetSystemType(); //获取类型

        QueueAddTail(IpIntQueueHead,Type);  //加入队列

    }

    //在猪程序中完成所有的工作

    while(1){

        Type = GetFirstInt();

        switch(Type)

        {

            case xxx:

            ...

            break;

            case xxx:

            ...

            break;

            .......

            default:

            ...

            break;

        }

    }
    把中断提炼到到短小精悍才是中断的灵魂所在,这里中断只做了两件事,就是获取中断类型,然后加入队列中,其余复杂的程序处理都在主函数中完成。 

    展开全文
  • 是这样的,飞思卡尔单片机.拿s12系列的来说,NON_BANKED一般位于0xc000-0xffff区域,而这个区域是16...所以,你可以这样理解:中断函数存放在CPU可以直接寻址的范围内,这样就可以节省中断函数的访问时间,方便调用中断函数(因
    是这样的,飞思卡尔单片机.拿s12系列的来说,NON_BANKED一般位于0xc000-0xffff区域,而这个区域是16位单片机可以直接寻址的区域,而__NEAR_SEG告诉编译器函数放在固定页中,只有固定页中的函数才能访问其他页的数据,同时CODE_SEG定义了一个代码段.
    所以,你可以这样理解:中断函数存放在CPU可以直接寻址的范围内,这样就可以节省中断函数的访问时间,方便调用中断函数(因为中断函数要求的就是实时性)...顺便再多说一句,如果你不写这一句,默认的是将函数存放在分页的flash里面,此时函数为far函数,访问far函数是相当耗费时间的一件事,中断函数毫无实时性可言.
    一般只有中断函数时才用__NEAR_SEG,对于一般函数来说__NEAR_SEG毫无作用...

    回答你的问题:非分页区是不能进行分页的区域(不需要设置PPAGE寄存器),cpu可以直接对其进行访问,访问速度快...



    在写到SCI 中断发送,中断接收程序的时候,在程序中会出现#pragma CODE_SEG __NEAR_SEG NON_BANKED/#pragma CODE_SEG DEFAULT,这两句话在程序中具体的代码如下:

    复制代码
     1 /*************************************************/
     2 /*               串口中端接受函数                */
     3 /*************************************************/
     4 #pragma CODE_SEG __NEAR_SEG NON_BANKED     //将接下来的代码(一般是中断函数)置于非分页区
     5 interrupt void recievedata(void) {
     6   data_recieve = SCI_recieve();
     7   if(data_recieve == 'O') {
     8     SCI_send('Y');
     9     LEDCPU = LED_ON;
    10   }
    11   if(data_recieve == 'C') {
    12     LEDCPU = LED_OFF;
    13   }
    14 }
    15 #pragma CODE_SEG DEFAULT
    复制代码

      总的来说这两句话是这样的意思:

    #pragma CODE_SEG __NEAR_SEG  NON_BANKED //中断函数置于非分页区内代码段
    #pragma CODE_SEG DEFAULT //后续代码置于默认区域内

      freescale16位的板子中断向量位是16位,中断函数只有被置于非分页区内才能被寻址到,这就是第一行的作用。由于单片机内部非分页区大小有限,非中断函数一般置于分页区内,最后一行即为此作用。

      这里要从FLASH分页和非分页的区别说起, FLASH里非分页工作机制如下:
      FLASH一共为128K,一页是16K,那么应该有8页才是,但是实际只有6个分页。有2个非分页放在4000-7FFF,和C000-FFFF两个逻辑地址窗里。那么,当程序的寻址在64K之内(2^16=64K,16位机的寻址能力是64K)时,就不用分页了,直接使用那两个非分页的数据。实际上,3E页 3F页是可见的,其实他们就是那2个非分页的映射。因此,使用非分页FLASH,就不须设置PPAGE寄存器,直接使用逻辑地址即可。

      这点我们可以从以下看出:

    /* non-paged FLASHs */
          ROM_4000      = READ_ONLY     0x4000 TO   0x7FFF;
          ROM_C000      = READ_ONLY     0xC000 TO   0xFEFF;
    PLACEMENT
          NON_BANKED,    INTO ROM_C000/*, ROM_4000*/;

     

      NON_BANKED一般位于0xc000-0xffff区域,而这个区域是16位单片机cpu可以直接寻址的区域,那么中断函数放在 NON_BANKED里,就可以把函数放在64K的寻址程序段中。这么一来,进中断就方便多了,效率也高很多(因为中断函数要求的就是实时性)...而 __NEAR_SEG告诉编译器函数放在固定页中,只有固定页中的函数才能访问其他页的数据,同时CODE_SEG定义了一个代码段.


    展开全文
  • 2.9中断函数集 Intrpt(Interrupt)函数集是提供具有输入中断信息的进程并可预设输出中断的核心函数的集合。   1. op_intrpt_schedule_self (time, code) 此核心函数的作用是为调用进程预设一个中断,其参数说明...

    2.9中断函数集

    Intrpt(Interrupt)函数集是提供具有输入中断信息的进程并可预设输出中断的核心函数的集合。

     

    1. op_intrpt_schedule_self (time, code)

    此核心函数的作用是为调用进程预设一个中断,其参数说明如表2-24所示。

    2-24  op_intrpt_schedule_self ()函数的参数说明

    参数

    类型

      

    time

    double

    预设的中断时间(该值为绝对仿真时间,而不是当前仿真时间的时延)

    code

    int

    与中断关联的用户自定义数值代码(该值是一个完全由用户自定义的整数值,可作为预设中断的标识代码。当中断调用进程时,可通过函数op_intrpt_code()获取该代码)

    1)返回值

    Evhandle­——预设中断的事件句柄。该返回值可存储在一个状态变量中,以用于以后调用函数op_ev_cancel()时取消中断。

    2)详解

    调用该函数时将在仿真事件列表中加入一个代表预设自中断的新事件。一旦预设了事件,函数将立即返回调用进程的控制权。在延时期间,调用进程可自由进行其他任何活动。如果没有其他高优先级事件,预设的事件将会按时发生。当执行完所有的前期事件后且自中断事件位于仿真事件列表的表头时,即将其仿真时间设为当前仿真时间并执行事件,引发调用进程的自中断。进程可通过函数op_intrpt_code()获取与中断相关的代码。

    当自中断表示超时或其他类似事件时,有必要取消无用的自中断。如在超时前收到了ack,则重置计时器。该函数返回的事件句柄将存储在一个状态变量中,将来就可利用该事件句柄调用函数op_ev_cancel()来取消中断,程序如下所示:

    /*State variable declaration*/

    Evhandle  evh;

     

    /*Self interrupt scheduling*/

    evh=op_intrpt_schedule_self(sch_time,5);

     

    /*Self interrupt canceling.*/

    op_ev_cancel(evh);

    此外,该核心函数的安全级别为Forced serialization

    3)目的

    该核心函数提供了预设自中断的机制,常用来限制某个进程状态的持续时间。当模拟超时时,状态将保持在等待包的到达,而超时自中断就表示该状态的结束。当模拟延时时,状态将保持在执行任务,而结束任务自中断意味着任务完成并释放资源。时间间隔结束后,进程通常转入空闲状态或确定是否有其他未决任务需要执行。

    4)错误

    Program Abort:内存分配失败。

    Program Abort:核心函数需要进程上下文。

    Recoverable Error:预设时间小于当前时间。

    Recoverable Error:预设时间是一个无效的double值。

    5)相关函数

    采用op_intrpt_schedule_remote()预设一个远程中断。

    采用op_intrpt_force_remote()强制预设远程中断。

    采用op_intrpt_schedule_call()预设一个过程中断。

    采用op_ev_cancel()取消未决的自中断、远程中断或过程中断。

    采用op_intrpt_code()获取与中断相关的代码。

     

    2. op_intrpt_schedule_remote (time, code, mod_objid)

    此核心函数的作用是为给定处理器或队列预设一个远程中断,其参数说明如表2-25所示。

    2-25  op_intrpt_schedule_remote()函数的参数说明

    参数

    类型

      

    time

    double

    预设的中断时间

    code

    int

    与中断相关的用户自定义数值代码

    mod_objid

    Objid

    给定处理器或队列的对象ID(处理器或队列ID可通过Id函数集中的op_id_self()op_topo_child()op_id_from_name()函数来获取)

    1)返回值

    Evhandle­——预设中断的事件句柄。该返回值可存储在一个状态变量中,用于以后调用函数op_ev_cancel()时取消中断。

    2)详解

    调用该函数时将在仿真事件列表中加入一个代表预设自中断的新事件。一旦预设了事件,函数将立即返回调用进程的控制权。在延时期间,调用进程可自由进行其他任何活动。如果没有其他高优先级事件,预设的事件将会按时发生。当执行完所有的前期事件后且自中断事件位于仿真事件列表的表头时,即将其仿真时间设为当前仿真时间并执行事件,引发调用进程的自中断。进程可通过函数op_intrpt_code()获取与中断相关的代码。

    该函数返回事件句柄并将其存储在一个状态变量中,当发生条件改变需要取消中断时,可以利用该事件句柄,调用函数op_ev_cancel()取消预设的远程中断,程序如下所示:

    /*Sstate variable declaration*/

    Evhandle \evh;

     

    /*Remote interrupt scheduling*/

    evh=op_intrpt_schedule_remote(stime,22,mod_objid);

     

    /*Remote interrupt canceling.*/

    op_ev_cancel(evh);

    此外,该核心函数的安全级别为Forced serialization

    3)目的

    该核心函数提供了无需物理包流或统计线的连接,进程可远程调用另一进程的机制,进程可用它来警告另一进程某事件的发生。

    注意:远程中断只能传递到处理器或队列,否则将引发错误。

    4)错误

    Program Abort:内存分配失败。

    Recoverable Error:预设时间小于当前时间。

    Recoverable Error:预设时间是一个无效的double值。

    Recoverable Error:对象ID溢出。

    Recoverable Error:对象类型错误。

    5)相关函数

    采用op_intrpt_schedule_self()预设一个自中断。

    采用op_intrpt_schedule_call()预设一个过程中断。

    采用op_ev_cancel()取消未决中断。

    采用op_intrpt_code()获取与中断相关的代码。

     

    3. op_intrpt_type ()

    此核心函数的作用是获取调用进程的当前中断类型。

    1)返回值

    int——当前中断类型。

    2)详解

    该函数返回的中断类型包括:

    OPC_INTRPT_FAIL(节点或链路失败中断);

    OPC_INTRPT_RECOVER(节点或链路失败中断);

    OPC_INTRPT_PROCEDURE(过程中断);

    OPC_INTRPT_SELF(自中断);

    OPC_INTRPT_STRM(流中断);

    OPC_INTRPT_REGULAR(常规中断);

    OPC_INTRPT_STAT(统计中断);

    OPC_INTRPT_REMOTE(远程中断);

    OPC_INTRPT_BEGSIM(仿真起始中断);

    OPC_INTRPT_ENDSIM(仿真结束中断);

    OPC_INTRPT_ACCESS(访问中断);

    OPC_INTRPT_PROCESS(进程中断);

    OPC_INTRPT_MCAST(广播中断);

    此外,该核心函数的安全级别为Forced serialization

    3)目的

    该核心函数提供了一种机制来确定是何原因唤醒调用进程。该函数是最基本的核心函数,几乎每个进程模型都会使用它。进程模型大多都有一个或多个分支状态,分支状态将该过程返回的值存储在一个临时变量中,然后根据该返回值来选取输出转换。

    4)错误

    该核心函数无错误捕获。

    5)相关函数

    采用op_intrpt_code()确定与当前中断相关的代码。

    采用op_intrpt_strm()确定与当前中断相关的流索引。

    采用op_intrpt_stat()确定与当前中断相关的输入统计索引。

    采用op_intrpt_ici()获取与当前中断相关的ICI

     

    4. op_intrpt_strm ()

    此核心函数的作用是获取与调用进程当前中断相关联的流索引。

    1)返回值

    int——与当前中断相关联的流索引。当使用函数op_pk_deliver…()将包传递到指定输入流时,将显式设置该值;当使用函数op_pk_send…()向包流中发送包或通过函数op_strm_access()访问包流时,将隐式设置该值。

    2)详解

    在与流相关联的中断后调用该函数,将只产生一个有效值。与流相关联的中断有两类:流中断和访问中断。前者的流是指包到达的输入流,而后者的流是指与之相连的模块访问的输出流。

    此外,该核心函数的安全级别为Forced serialization

    3)目的

    对于流中断,该函数确定了包是通过哪个输入流到达的;而对于访问中断,函数可确定所连处理器或队列访问的是哪个输入流。

    4)错误

    Program Abort:核心函数需要进程上下文。

    Recoverable Error:当前事件不是流中断或访问中断。

    5)相关函数

    采用op_intrpt_type()确定当前中断的类型。

    采用op_intrpt_code()确定与当前中断相关的代码。

    采用op_intrpt_stat()确定与当前中断相关的输入统计索引。

    采用op_pk_send…()op_pk_deliver…()将包发送或传递到模块输入流中。

    采用op_strm_access()访问处理器或队列的输出流。

     

    5. op_intrpt_ici ()

    该核心函数的作用是获取与当前中断相关联的ICI

    1)返回值

    Ici*——指向与当前中断相关联的ICI的指针。

    2)详解

    进程中断中携带的信息类型包括中断类型、与中断相关的标记或代码,有时还携带ICI信息。获取ICI的指针允许接收进程撮其内容。将ICI的内容完全处理后,可通过op_ici_destroy()重复利用该ICI。但只有当源进程为每个输出中断创建了新的ICI,才能销毁ICI

    此外,该核心函数的安全级别为Forced serialization

    3)目的

    该核心函数为进程提供了一种获取与当前中断相关的ICI指针的机制。一旦获取该指针,便可使用函数op_ici_attr_get()来提取ICI内容。

    4)错误

    该核心函数无错误捕获。

    5)相关函数

    采用op_ici_create()创建ICI

    采用op_ici_install()为输出中断建立一个ICI

    采用op_ici_destroy()解除已处理的ICI

    采用op_intrpt_type()确定当前中断类型。

    采用op_ici_attr_get()获取ICI属性值。

    采用op_ici_attr_exists()确定ICI是否包含特殊属性。

     

    6. op_intrpt_code ()

    此核心函数的作用是获取与调用进程当前中断相关联的数值代码。

    1)返回值

    int——与当前中断相关联的数值代码。

    2)详解

    当在具有与代码相关联的中断之后调用该函数时,将只产生有效值。支持代码的中断类型为自中断、进程中断和远程中断。

    此外,该核心函数的安全级别为Forced serialization

    3)目的

    该核心函数提供了一种机制来确定与中断相关联的用户自定义数值代码,从而确定其目的,主要用于存在多个相同类型、不同目的的中断的情况下。

    4)错误

    该核心函数无错误捕获。

    5)相关函数

    采用op_intrpt_type()确定当前中断类型。

    采用op_intrpt_strm()确定与当前中断相关的流索引。

    采用op_intrpt_stat()确定与统计中断相关的输入统计索引。

    采用op_intrpt_source()确定当前中断的源对象。

    采用op_intrpt_ici()获取与当前中断相关的ICI。
    展开全文
  • 面试题之二:中断服务函数

    千次阅读 2019-08-05 22:54:25
    中断问题也是面试嵌入式岗位时,面试官比较喜欢拷问的问题之一,作为一个嵌入式开发人员,自然少不了与中断打交道...4.不要在中断函数中使用printf函数,会带来重入和性能问题 中断并不是程序一开始就判断好会在那...
  • 中断服务函数函数调用的区别

    千次阅读 2019-12-23 17:02:06
    在《微机原理》和《计算机组成》等课程[1-4]教学中(本文以MCS-51单片机为例),中断过程既是教学难点又是教学重点,它与主程序调用子程序过程有一定相似性,但又有很大区别,调用子程序过程相对比较容易掌握,通过...
  • //*******************************************************************//作用:RS485初始化//参数:BPS-波特率//StopBit-停止位,1为1位,2为2位//Parity-校验方式,0为无校验,1为寄校验,2为偶校验//返回:无//...
  • request_irq的作用是申请使用IRQ并注册中断处理程序。 request_irq()函数的原型如下: /* kernel/irq/manage.c */ int request_irq( unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), ...
  • 1、基于trubo c rs232的串口通信程序源代码.。 2、包括教材[Visual.C.Turbo.C串口通讯编程实践].龚建伟&熊光明。 3、有详细的代码注释(包括寄存器...4、包括中断函数、主函数程序的流程图,可全面吃透程序运行流程。
  • STM32中的timers中断处理函数

    千次阅读 2018-05-03 14:04:38
    在固件库函数里面,用来读取中断状态寄存器的值判断中断类型的函数是:ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t)作用:判断定时器TIMx的中断类型TIM_IT是否发生中断。比如,我们要判断定时器3是否发生...
  • 程序, 中断, 调用, 函数 在《微机原理》和《计算机组成》等课程[1-4]教学中(本文以MCS-51单片机为例),中断过程既是教学难点又是教学重点,它与主程序调用子程序过程有一定相似性,但又有很大区别...
  • 写了一个按键中断服务程序,按下key1pwm输出,按下key2关闭pwm输出,在不加延时的时候key2可以关闭key1打开的pwm,但是加了延时之后key2就不起作用了,是因为在中断服务函数中加了延时导致key2无法响应了吗,即是在...
  • 中断函数调用的区别

    千次阅读 2012-04-18 13:49:25
    程序, 中断, 调用, 函数 在《微机原理》和《计算机组成》等课程[1-4]教学中(本文以MCS-51单片机为例),中断过程既是教学难点又是教学重点,它与主程序调用子程序过程有一定相似性,但又有很大区别...
  • 特邀~简单说下吧,这里题主需要弄明白两个问题,第一个,为...每次进中断函数的时候,都会有入栈和出栈的过程,这里不需要深究,只需要知道,如果你在中断函数,或者你自己定的任何一个函数里面,使用的变量,在不...
  • 这种用法的保护作用前提是大家都遵守先申请再访问,有一个地方没遵守这个规则,这功能就失效了。好比进程互斥,必需大家在访问临界资源的时候都得先获取锁一样,其中一个没遵守约定,代码就废了...
  • 回调函数作用

    千次阅读 多人点赞 2017-03-12 09:02:09
    回调函数作用 原文地址:http://wmnmtm.blog.163.com/blog/static/3824571420105484116877/ 一直不太理解回调函数作用,下面是找到的一些关于回调函数作用的解答。...2.回调函数就相当于一个中断
  • 编程中断言函数作用

    2018-03-15 15:02:27
    编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设。断言表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值...当需要在一个值为FALSE时中断当前操作的话,可以使用断言。单元测...
  • Linux sleep函数作用

    千次阅读 2011-09-14 14:52:18
    sleep把进程的运行状态改为睡眠,将其从系统可执行队列去掉,这样系统就不会调度到该进程,不会分配CPU...同时内核维持一个定时器队列,每一次时钟中断处理,都把当前到期的队列中的进程唤醒,加入到可运行进程队列中。
  • 因为js脚本很多都是基于函数的运行,return的作用中断函数的执行,提前退出该函数。所以在执行某个函数内部的时候可以通过返回return来退出js执行。见例子://错误情况,exit不存在对象,在ie下会报错$('.water....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 753
精华内容 301
关键字:

中断函数作用