CYRESS给出的USB例程,在periph.c中普遍在开头一行加了下列编译指令:
#pragma NOIV
它的注释是,不产生中断向量。查找C51手册,说明如下:
NOINTVECTOR Compiler Directive
Abbreviation |
NOIV
|
Arguments |
None.
|
Default |
INTVECTOR (0)
|
µVision |
Options — C51 — Interrupt vectors at address.
|
Description |
The NOINTVECTOR directive inhibits interrupt vector generation. This flexibility allows the user to provide interrupt vectors with other programming tools.
|
See Also |
INTERVAL, INTVECTOR
|
Example |
C51 SAMPLE.C NOINTVECTOR
#pragma noiv
|
它的意思是,不产生8051缺省的中断向量。对68013A来说,缺省的中断有13个,分别排列在中断向量表,位于内存0x0003~0x0063,默认优先级0~12。一般在编译选项里预留出0x80以下的内存,就是供这个中断向量表使用。
实际上,在程序开头加上#pragma NOIV,表示该文件使用的中断函数统统不遵循上述缺省的中断向量分配,而是自行分配中断向量,自行分配中断优先级。
这样才有了大量的USB函数采用interrupt 0的写法:
void ISR_Ep2eflag(void) interrupt 0;
void ISR_Ep4eflag(void) interrupt 0;
这样的写法,人为地把所有USB中断当成了最高优先级的中断0。(缺省的中断0只有WAKEUP/WU2引脚或者USB唤醒,其它25个USB中断是中断8)
从这一设置可以看出,位于该文件中的其它中断,也要人为地约定中断号。我的经验是,不如把其它类型的中断,如定时器,外部中断等,写到其它文件,只要这个文件不包含#pragma noiv,那么该文件中的中断还是可以使用缺省中断的(仅仅中断0被USB占用,其它都可用)。
另外C51中断语句后的using不用也罢!实在是没时间搞清68013和老51在这一部分的差别,不加的最坏可能是效率的降低,这个要查看汇编代码才能了解,不用就好了。
关键字:KEIL C51 NOIV
引用地址:
KEIL C51的#pragma NOIV
推荐阅读最新更新时间:2024-03-16 14:43
keil 中的重入问题解决
keil c 中可以用关键字 reentrant 定义, 如:void fun(void) reentrant{} 但函数中不可以使用BOOL变量,以为KEIL默认 将所有变量定位到外部RAM的最高处,而外部RAM不可以位寻址。 另外如果你的外部RAM不足64K(0XFFFF),你还的更改KEIL系统文件STARTUP.A51中 XBPSTACKTOP EQU 0FFFFH+1;这一行。 例如你的外部RAM是0-0x7fff, 则该为: XBPSTACKTOP EQU 07FFFH+1;
[单片机]
PID调节C51程序(5)
typedef struct PIDValue { uint32 Ek_Uint32 ; //差值保存,给定和反馈的差值 uint8 EkFlag_Uint8 ; //符号,1则对应的Ek 为负数,0为对应的Ek 为正数 uint8 KP_Uint8; uint8 KI_Uint8; uint8 KD_Uint8; uint8 B_Uint8; //死区电压 uint8 KP; //显示修改的时候用 uint8 KI; // uint8 KD; // uint8 B; // uint16 Uk_Uint16; //上一时刻的控制电压 }PIDValueStr; PID
[单片机]
keil生成bin文件
在烧写stm32程序的时候,有时候需要用到串口烧写。那么就需要一个可烧写的bin文件了。 我们可以直接用keil来直接生成,不过keil的默认配置是没有这个设置的。配置如下图 添加指令:fromelf.exe --bin -o $L@L.bin #L 然后编译就会生成bin文件了
[单片机]
C51编程2-输出电平(点亮LED2)
上一讲中,直接通过变量sbit来控制P2口中一个LED的亮灭。除了可以通过sbit位控制来设置LED,我们还可以通过P2口,直接控制P2口的LED。 下面的代码可以实现上一讲一样的功能,控制led0亮。 #include reg52.h void main(){ P2 = 0xfe; } 从上面的代码中,将0xfe直接赋值给P2为什么实现的功能跟位操作的一样?而我们学习的C语言中,貌似没有都见过sbit,P2这两个东西。 在《标准C与C51》的文章中,提到为发挥C51单片机的特性,编译器会增加对MCS51单片特性的支持,而sbit与P2就是为了发挥MCS51单片机增加的特性支持。有兴趣的,可以通过下面的连接看
[单片机]
Keil 出现Debug Error! DAMAGE:after Normal block
Keil编译程序没有问题,在下载程序的时候出现: 甚至于出现,Keil死掉的情况 因为程序可以编译过,所以程序本身并没有问题,当下载时出问题就应该是 程序太大超出了单片机Flash、RAM太大等地方的问题。 最后检查是因为程序太大,所用单片机的Flash只有16K。而程序大小超过了16K。
[单片机]
Keil C51对C语言的关键词扩展之十一: xdata
xdata声明的变量位于外部ram 64KB地址范围内某一位置。 程序示例: unsigned int xdata m=0; /* 声明一个全局变量,可位于外部ram 64KB地址范围内任意位置,由编译器决定 */ int main(void) { ...... }
[单片机]
keil5如何调试程序并查看数组值
1.首先打开一个程序,点击编译按钮。 2.然后点击调试按钮,进入调试界面。 3.在需要暂停调试的语句旁鼠标右键,添加断点。(注:只有在灰色区域才能添加断点,灰色区域表示有语句部分,其不包括空白行和括号) 4.点击运行按钮,程序会运行到断点处(断点行的程序并没有运行) 5.右下角有个观察框显示数据值,可以在表达式一栏敲入自己想查看的数据。
[单片机]
c51 interrupt 中断号写法
单片机interrupt 中断号写法 定义函数的时候按正常的方法定义,然后在小括号的后面大括号的前面写上interrupt X using Y就行了,X是你要用的中断号,Y是中断时用的寄存器组,通常用1组就行了,看下面的例子: void timer_isr(void) interrupt 1 using 1 {} 中断函数不能设置参数和返回值,都置为void吧。 using ** 不要写,写了易出错,不写绝对不出错. interrupt**是中断源.具体编号如下: 中断源 interrupt(中断号) INT0 0 T0 1 INT1 2 T1 3 UART
[单片机]