精华内容
下载资源
问答
  • 今天调试ECAP,捕获频率,发现进一次中断后,就再也不进中断了,而且其他中断也不...发现这个中断服务函数前没有加__interrupt关键字。后来,试着加上这个关键字,居然可以工作。所以,这个关键字还是不能省略。 ...

    今天调试ECAP,捕获频率,发现进一次中断后,就再也不进中断了,而且其他中断也不工作了。发现这个中断服务函数前没有加__interrupt关键字。后来,试着加上这个关键字,居然可以工作。所以,这个关键字还是不能省略。

     

    展开全文
  • 中断服务程序不用interrupt关键字也可实现中断,该关键字是否必须? 使用tools->pin connect,将INT5与pin.txt关联,模拟外部中断,主函数如下: 1 #include <stdio.h> 2 #include <gbl.h> 3...

    2013-06-20 11:13:35

    中断服务程序不用interrupt关键字也可实现中断,该关键字是否必须?

    使用tools->pin connect,将INT5与pin.txt关联,模拟外部中断,主函数如下:

     1 #include <stdio.h>
     2 #include <gbl.h>
     3 #include "pin_connect_cfg.h"
     4 
     5 int main()
     6 {
     7     C64_enableIER(1<<5);
     8 }
     9 
    10 interrupt void HWI_int5_isr()
    11 //void HWI_int5_isr()
    12 {
    13     printf("HWI int5 happen!\n");
    14 }

    中断服务程序加不加interrupt关键字,都可正常输出:

    HWI int5 happen!
    HWI int5 happen!
    HWI int5 happen!
    HWI int5 happen!
    HWI int5 happen!
    HWI int5 happen! 

    但文章http://www.cnblogs.com/youngforever/articles/3147153.html所述:

    在使用HWI对象时,若其中断处理函数使用C语言来编写则一定不能使用interrupt关键字或INTERRUPT pragma,因为HWI对象调用的函数已经包含了这些功能。

    是不是通过DSP/BIOS配置的HWI是不能使用interrupt关键字的?

    难道上面的因为是simulator,不能反映实际问题?

    转载于:https://www.cnblogs.com/youngforever/p/3145674.html

    展开全文
  • __interrupt double compute_area (double radius) {  double area = PI * radius * radius;  printf("\nArea = %f", area);  return area; } 答:这个函数有如下的错误: 1) ISR 不能...

    __interrupt double compute_area (double radius)
    {
        double area = PI * radius * radius;
        printf("\nArea = %f", area);
        return area;
    }

    答:这个函数有如下的错误:
    1) ISR 不能返回一个值。
    2) ISR 不能传递参数。
    3) 在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。此外,ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。
    4) 与第三点一脉相承,printf()经常有重入和性能上的问题。

    展开全文
  • C语言在8051单片机上的扩展(interrupt、using关键字的用法)直接访问寄存器和端口 定义sfr P0 0x80 sfr P1 0x81 sfr ADCON; 0xDEsbit EA 0x9F 操作ADCON = 0x08;  P1 = 0xFF; io_status = P0 ; EA = 1; 在...

     C语言在8051单片机上的扩展(interrupt、using关键字的用法)

    直接访问寄存器和端口

     定义

    sfr P0 0x80
    sfr P1 0x81
    sfr ADCON; 0xDE

    sbit EA  0x9F


    操作

    ADCON = 0x08;  
    P1 = 0xFF;   

    io_status = P0 ;
    EA = 1;   

            在使用了interrupt 1 关键字之后,会自动生成中断向量

            在 ISR中不能 与其他 “后台循环代码”(the background loop code) 共享局部变量,因为连接器会复用 在RAM中这些变量的位置 ,所以它们会有不同的意义,这取决于当前使用的不同的函数复用变量对RAM有限的51来讲很重要。所以,这些函数希望按照一定的顺序执行 而不被中断。

    void timer0_int(void) interrupt 1 using 2
    {
     unsigned char temp1;
     unsigned char temp2;
     executable C statements;
    }

            “interrupt”声明表向量生成在(8*n+3),这里,n就是interrupt参数后的那个数字这里,在08H的代码区域 生成LJMP timer0_int这样一条指令。

            “using” tells the compiler to switch register banks on entry to an interrupt routine. This “context” switch is the fastest way of

    providing a fresh registerbank for an interrupt routine’s local data and is to be preferred to stacking registers for very time-criticalroutines. Note that interrupts of the same priority can share a register bank, since there is no risk that they will interrupt each other.

            “using” 告诉编译器 在进入51danpi中断处理器 去切换寄存器的bank。这个”contet”切换是为中断处理程序的局部变量提供一个新鲜的寄存器bank最快的方式。对时序要求严格的程序,是首选的stack寄存器(保存寄存器到stack)方式。

            注意:同样优先级别的中断可以共享寄存器bank,因为他们每次将中断没有危险。

            If a USING 1 is added to the timer1 interrupt function prototype, the pushing of registers is replaced by a simple MOV to PSW to switch registerbanks. Unfortunately, while the interrupt entry is speeded up, the direct register addressing used on entry to sys_interp fails. This is because C51 has not yet been told that the registerbank has been changed. If no working registers are used and no other function is called, the optimizer eliminiates teh code to switch register banks.

           如果在timer1的中断函数原型中使用using 1, 寄存器的pushing将被MOV to PSW切换寄存器bank 所替换。

           不幸的是,当一个中断入口被加速时。用在入口的 直接寄存器寻址将失败。这是因为 C51没有告诉 寄存器bank已经改变。如果不工作的寄存器将被使用,如果没有其他函数被调用,优化器…..

            Logically, with an interrupt routine, parameters cannot be passed to it or returned. When the interrupt occurs, compiler-inserted code is run which pushes the accumulator, B,DPTR and the PSW (program status word) onto the stack. Finally, on exiting the interrupt routine, the items previously stored on the stack are restored and the closing “}” causes a RETI to be used rather than a normal RET.

            逻辑上,一个中断服务程序,不能传递参数进去,也不可返回值。当中断发生时,编译器插入的代码被运行,它将累加器,B,DPTR和PSW(程序状态字)入栈。最后,在退出中断程序时,预先存储在栈中 被恢复。最后的”}”结束符号将插入RETI到中断程序的最后,为了用 Keil C语言创建一个中断服务程序(ISR),利用 interrupt 关键词和正确的中断号声明一个static void函数。Keil C编译器自动生成中断向量,以及中断程序的进口、出口代码。Interrupt 函数属性标志着该函数为ISR。可用using属性指定ISR使用哪一个寄存器区,这是可选的。有效的寄存器区范围为1到3。

    中断源的矢量位置

    中断源               Keil中断编号           矢量地址
    最高优先级                 6                     0x0033
    外部中断0                 0                     0x0003
    定时器0溢出               1                     0x000B
    外部中断1                 2                     0x0013
    定时器1溢出               3                     0x001B
    串口                           4                     0x0023
    定时器2溢出               5                     0x002B
    DMA                           7                     0x003B
    硬件断点                    8                     0x0043
    JTAG                         9                     0x004B
    软件断点                   10                     0x0053

    监视定时器               12                     0x0063

    1.函数在调用前定义与在调用后定义产生的代码是有很大差别的(特别是在优化级别大于3级时)。(本人也不太清楚为什么,大概因为在调用前定义则调用函数已经知道被调用函数对寄存器的使用情况,则可对函数本身进行优化;而在调用后进行定义则函数不知被调用函数对寄存器的使用情况,它默认被调用函数对寄存器(ACC、 B、 DPH、 DPL、 PSW、 R0、 R1、 R2、 R3、R 4、 R5、, R6、 R7)都已经改变,因此不在这些寄存器中存入有效的数据)

    2.函数调用函数时除在堆栈中存入返回地址之外,不在堆栈中保存其它任何寄存器。(ACC、 B、 DPH、 DPL、 PSW、 R0、 R1、 R2、 R3、R 4、 R5、, R6、 R7)的内容。(除非被调用函数使用了using特性)

    3.中断函数是一个例外,它会计算自身及它所调用的函数对寄存器(ACC、 B、 DPH、 DPL、 PSW、 R0、 R1、 R2、 R3、R 4、 R5、, R6、 R7)的改变,并保存相应它认为被改变了的寄存器。

    4.使用C写程序时,尽量少使用using n (n=0,1,2,3)特性。(这个特性在本人使用的过程中存在一些问题,不知算不算是一个小bug)

            默认keil c51中的函数使用的是0寄存器组,当中断函数使用using n时,n = 1,2,3或许是对的,但n=0时,程序就已经存在了bug(只有中断函数及其所调用的函数并没有改变R0 —- R7的值时,这个bug不会表现出来)

            一个结论是,在中断函数中如果使用了using n,则中断不再保存R0—-R7的值。由此可以推论出,一个高优先级的中断函数及一个低优先级的中断函数同时使用了using n,(n = 0,1,2,3)当n相同时,这个存在的bug 是多么的隐蔽。(这恰是使人想象不到的)

            使用不同寄存器组的函数(特殊情况外)不能相互调用”using”关键字告诉编译器切换register bank

            如果中断程序不重要,using关键字能忽略。如果一个函数被从中断程序调用,而此中断强制使用using,当编译一个被调用的函数时,编译器必须告诉它
    1)在函数前 必须用伪指令

    #pragma NOAREGS

    在进入函数

    #pragma RESTORE
    或者
    #pragmas AREGS

    这样就不会使用 “绝对地址定位”

    2)#pragma REGISTERBANK(n)

    用这个指定告诉当前使用的bank

    用NOAREGS指令 移除 MOV R7,AR7

    中断服务例程

    void timer0_int(void) interrupt 1 using 1

     unsigned char temp1 ;  
     unsigned char temp2 ;  
    }

    被调用的函数

    #pragma SAVE // Rember current registerbank

    #pragma REGISTERBANK(1)     // Tel C51 base address of current registerbank.
    void func(char x)

    // Called from interrupt routine      
    // with “using1”  
     }

    #pragma RESTORE // Put back to original registerbank


            如果中断服务例程使用了using,被中断服务例程 调用的函数一定要REGISTERBANK(n),一个被ISR调用的函数也可能被后台程序调用为了函数”reentrant(可重入8051 系列MCU的基本结构包括:32 个I/O 口(4 组8 bit 端口);两个16 位定时计数器;全双工串行通信;6 个中断源(2 个外部中断、2 个定时/计数器中断、1 个串口输入/输出中断),两级中断优先级;128 字节内置RAM;独立的 64K 字节可寻址数据和代码区。中断发生后,MCU 转到5个中断入口处之一,然后执行相应的中断服务处理程序。中断程序的入口地址被编译器放在中断向量中,中断向量位于程序代码段的最低地址处,注意这里的串口输入/输出中断共用一个中断向量。8051的中断向量表如下:
    中断源 中断向量
    —————————
    上电复位          0000H
    外部中断0        0003H
    定时器0 溢出   000BH
    外部中断1        0013H
    定时器1 溢出   001BH
    串行口中断       0023H
    定时器2 溢出    002BH

            interrupt 和 using 都是C5 的关键字。C51中断过程通过使用interrupt关键字和中断号(0 到 31)来实现。中断号指明编译器中断程序的入口地址中断序号对应着8051中断使能寄存器IE 中的使能位,对应关系如下:
    IE寄存器 C51中的 8051的
    的使能位 中断号 中断源
    ——————————–
    IE.0 0 外部中断0
    IE.1 1 定时器0 溢出
    IE.2 2 外部中断1
    IE.3 3 定时器1 溢出
    IE.4 4 串口中断
    IE.5 5 定时器2 溢出

            有了这一声明,编译器不需理会寄存器组参数的使用和对累加器A、状态寄存器、寄存器B、数据指针和默认的寄存器的保护。只要在中断程序中用到,编译器会把它们压栈,在中断程序结束时将他们出栈。C51 支持所有 5 个 8051 标准中断从 0 到 4 和在 8051 系列(增强型)中多达 27 个中断源。
            using 关键字用来指定中断服务程序使用的寄存器组。用法是:using 后跟一个0 到3 的数,对应着 4 组工作寄存器。一旦指定工作寄存器组,默认的工作寄存器组就不会被压栈,这将节省 32 个处理周期,因为入栈和出栈都需要 2 个处理周期。这一做法的缺点是所有调用中断的过程都必须使用指定的同一个寄存器组,否则参数传递会发生错误。因此对于using,在使用中需灵活取舍。

    展开全文
  • 关键字using与interrupt

    千次阅读 2015-02-15 10:50:39
    1、关键字using (1)在函数的入口处将当前工作寄存器组保护到堆栈中,指定的工作寄存器内容不会改变; (2)函数返回之前将被保护的工作寄存器组从堆栈中恢复。 (3)带using属性的函数不能返回bit类型的值; ...
  • 转载自:... C语言在8051单片机上的扩展(interrupt、using关键字的用法) 直接访问寄存器和端口 定义 sfr P0 0x80 sfr P1 0x81 sfr ADCON; 0xDE sbit EA 0x9F 操作 ADCON = 0x08;
  • C语言在8051单片机上的扩展(interrupt、using关键字的用法) 直接访问寄存器和端口定义sfr P0 0x80 sfr P1 0x81 sfr ADCON; 0xDE sbit EA 0x9F操作ADCON = 0x08 ; P1= 0xFF 
  • MSP430 C语言的关键字扩展

    千次阅读 2011-02-23 09:27:00
    1.interrupt 用于中断函数。 定义如下: 语法: interrupt void 函数名... 说明:interrupt关键字声明了在处理器发生中断时调用;函数的参数必须为空 2.monitor 使函数进入原型(atomic)操作
  • C语言中的interrupt

    千次阅读 2018-09-13 22:20:37
    C/C++编译器通过interrupt关键字扩展了C语言。这个关键字用来制定一个函数应该被看成一个中断函数。 处理中断的函数要求特殊的寄存器保存规则,增加一些特殊的返回序列(return sequence)。当C/C++代码被中断时,...
  • 说明:interrupt关键字声明了在处理器发生中断时调用;函数的参数必须为空2.monitor 使函数进入原型(atomic)操作状态。定义如下:语法:monitor 函数类型 函数名(参数表)参数:该函数可以有参数,也可以没有参数。...
  • DSP关键字const,cregister,far,interrupt

    千次阅读 2017-08-18 16:05:56
    关键字就是已被C语言本身使用,不能作其它用途使用的字,例如关键字不能用作变量名、函数名等。那“关键字”到底有多关键?简单得说,就是如果不掌握它们的使用方法,程序就不能按照我们的设计产生预期的结果。C28
  • 大家都知道当线程的run方法走完或者run方法里面出现异常没有被捕获的时候,线程将终止.Jva在早期的时候曾提供过一个stop的方法用来打断线程,不过这个方法到现在已经被放弃了,不过又提供了一个interrupt方法来打断线程...
  • interrupt()方法并不能直接停止线程,而是会改变interrupt的标志位 public class Demo { private volatile static boolean shutdown; public static void main(String[] args) throws InterruptedException { ...
  • 1、类锁  一个类的所有对象共享一个class对象,共享一组静态方法,类锁的作用就是使持有者可以同步地调用静态方法 ... synchronized public static void mB(String value) throws Interrupt...
  • volatile 关键字精讲

    2021-01-08 09:56:42
    通过一个案例引出volatile关键字,例如以下代码示例 : 此时没有加volatile关键字两个线程间的通讯就会有问题 public class ThreadsShare { private static boolean runFlag = false; // 此处没有加 volatile public...
  • 嵌入式Linux C笔试题积累

    千次阅读 2017-01-20 13:22:08
    1.嵌入式系统中断服务子程序(ISR)  中断是嵌入式系统中重要...下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。 [cpp] view plain copy __in
  • volatile关键字

    2009-06-16 17:51:00
    由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。比如: static int i=0;... //dosomething永可能远也不会被调用 } } /* Interrupt service routine. */ void ISR_2(void...
  • 中断服务子程序

    千次阅读 2018-05-16 17:55:42
    中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准...下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。 __interrupt double compute_...
  • C语言关键字用法

    千次阅读 2016-06-22 14:04:21
    sbit:定义特殊功能寄存器的位变量,如:sbit P0_0=P0^0;//即定义P0_0为P0口的第1位 ...interrupt:中断的意思。 code:程序存储区。如定义一个数组uchar ad_data[],即把数组定义在RAM中,uchar code ad_da
  • 中断

    2020-02-14 19:25:47
    11. 中断是嵌入式系统中重要的组成部分,这...下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。 __interrupt double compute_area (double radius) { double area =...
  • 中断服务子程序 ISR

    千次阅读 2017-06-06 16:28:36
    中断是嵌入式系统中重要的组成部分,这导致了很多...下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。 __interrupt double compute_area (double radius)  {  
  • 1>.ISR-中断服务子程序 ...下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR) __interrupt double compute_area (double radius)  {  double area = PI * radius * radius;
  • 中断服务子程序(ISR)

    千次阅读 2018-09-11 20:33:36
    中断是嵌入式系统中重要的组成部分,这导致...下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。 __interrupt double compute_area (double radius)  { double are...
  • 今天看到的C/C++50个经典面试题中的问题: 中断是嵌入式系统中重要的...下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。 __interrupt double compute_area (double...
  • 中断是嵌入式系统中重要的组成部分,这...下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。 __interrupt double compute_area(double radius) { double area = pi*radi
  • 关于中断的面试题

    千次阅读 2018-08-13 10:29:32
    中断(Interrupts) 11. 中断是嵌入式系统中重要的组成...下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。   1 2 3 4 5 6 _...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 219
精华内容 87
关键字:

interrupt关键字