我正在使用Microchip C18编译器,并且在发生中断时,我在ISR代码开始运行之前经历了相当长的延迟。
作为一项实验,这是我的主要职能:
while(1)
{
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 0;
}
作为中断处理程序我正在使用这个代码我从一些例子中复制过(我不知道为什么这样做):
#pragma interrupt high_isr
void high_isr(void)
{
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 0;
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 1;
LATAbits.LATA4 = 0;
}
#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
_asm GOTO high_isr _endasm
}
我通过SPI接收字节,接收到一个字节后不久,主循环停止。然后在ISR代码开始运行之前延迟16.5μs。那是165个指令周期!
我知道有一些与中断相关的上下文保存,并且在低优先级中断时更糟糕。我已禁用 IPEN ,我只使用高优先级向量。 165条指令是正常的上下文保存时间吗?
答案 0 :(得分:3)
在某些情况下,中断开销可能会很大! 看看this。
答案 1 :(得分:0)
从PIC中断获得良好性能的关键是最小化所需的上下文保存/恢复代码的范围。在许多情况下,这意味着在机器代码中编写中断处理程序的时间关键部分。在具有至少一些可用于中断使用的无存储区寄存器的部分上(我真的不喜欢Microchip为了FSR2寻址而吞没大多数或所有公共存储体的决定,而不是为FSR2寻址分配例如15个字节,每个7字节用于FSR2寻址FSR0和FSR1寻址,以及每个FSR的一个“魔术操作”寄存器[我喜欢聊聊这些事情的想法])有时可以在没有任何上下文保存/恢复的情况下通过常见的情况。例如,在我的一个14位PIC项目中,我需要每1000个时钟周期进行一次中断。因此,在禁用RTCC预分频器的情况下,我的中断类似于:
INTERRUPT_ENTRY: bcf INTCON,TMR0IF decfsz int_counter,f retfie movwf saveW movf STATUS,w clrf STATUS ; Bank 0 movwf saveStat movlw 4 movwf int_counter movlw 1024+3-1000 ' TMR0 unadjusted time, plus 3 'slip', minus desired time addwf TMR0,f bsf INTCON,GIE ; Interrupts can safely nest after this point! ... other interrupt stuff movf saveStat,w movwf STATUS swapf saveW retfie ; Could just as well use RETURN, since interrupts are enabled
注意,在3/4的时间内,在执行了大量的三条指令后,中断将返回,从下面执行的任何代码总共执行大约6个周期。