在编写中断服务程序(ISR)的时候需要知道中断号,用于通知51内核,这个中断服务程序是为了响应哪个中断的。那么,从以上这句简单的描述可以看出,中断号必然对应于中断服务程序的入口地址,而入口地址又与中断向量(Interrupt Vector)有对应关系,所以:
(1)、中断号即是中断向量从小到大的编号,从0开始;
(2)、中断向量0x0000是上电复位,不计入中断向量的编号;
(3)、特别注意,有些中断源的默认中断优先级并不是中断向量从小到大的编号,所以默认的中断优先级并不能作为中断号使用。
什么是中断号
// Wake-up interrupt handler
void resume_isr(void) interrupt WKUP_VECT
{
EZUSB_CLEAR_RSMIRQ();
}
↑,这是EZ-USB的唤醒中断的中断服务程序,其中”WKUP_VECT”就是Resume中断的中断号,中断号用关键词”interrupt”标记。
EZ-USB的中断号
在固件源代码中,中断号的声明是:
// 中断名称 中断号
#define INT0_VECT 0
#define TMR0_VECT 1
#define INT1_VECT 2
#define TMR1_VECT 3
#define COM0_VECT 4
#define TMR2_VECT 5
#define WKUP_VECT 6
#define COM1_VECT 7
#define USB_VECT 8
#define I2C_VECT 9
#define INT4_VECT 10
#define INT5_VECT 11
#define INT6_VECT 12
文档中的描述:
可以看出,固件源码中的中断号和文档中的“Natural Priority”是不一致的,而和”Interrupt Vector”的从小到大的排列顺序是一致的。
这里,没有中断向量0x0000的中断,在标准的C51中他被用作上电复位,下面再举一个中断向量0x0000的例子。
C8051F34X的中断号
这是SILLICON LABS的C8051F34X芯片的中断号,他包含0x0000中断向量,但是不计入“排序”。官方给出的UART0的中断服务程序证明了这一点:
void UART0_Interrupt (void) interrupt 4
{
if (RI0 == 1)
{
if( UART_Buffer_Size == 0) { // If new word is entered
UART_Input_First = 0; }
RI0 = 0; // Clear interrupt flag
Byte = SBUF0; // Read a character from UART
if (UART_Buffer_Size < UART_BUFFERSIZE)
{
UART_Buffer[UART_Input_First] = Byte; // Store in array
UART_Buffer_Size++; // Update array's size
UART_Input_First++; // Update counter
}
}
if (TI0 == 1) // Check if transmit flag is set
{
TI0 = 0; // Clear interrupt flag
if (UART_Buffer_Size != 1) // If buffer not empty
{
// If a new word is being output
if ( UART_Buffer_Size == UART_Input_First ) {
UART_Output_First = 0; }
// Store a character in the variable byte
Byte = UART_Buffer[UART_Output_First];
if ((Byte >= 0x61) && (Byte <= 0x7A)) { // If upper case letter
Byte -= 32; }
SBUF0 = Byte; // Transmit to Hyperterminal
UART_Output_First++; // Update counter
UART_Buffer_Size--; // Decrease array size
}
else
{
UART_Buffer_Size = 0; // Set the array size to 0
TX_Ready = 1; // Indicate transmission complete
}
}
}