We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Dear All, I'm using this interrupt on my program
void timer1_ISR (void) interrupt 3 //timer1 interrupt services routine { .. } void it_ext1(void) interrupt 2 // external interrupt INT1 { .. } void timerisr(void) interrupt 1 //timer0 interrupt services routine { .. } static void com_isr (void) interrupt 4 //SERIAL COMMUNICATION INTERRUPT SERVICES ROUTINE { .. } void i2c(void) interrupt 5 //i2c interrupt services routines { .. }
"and I didn't specified which register bank to use on every interrupt routines." That's ok. "I've seen few example which specified the register bank. Can anyone explain more on the uses of register bank during interrupt service routine" If you specify which register bank an ISR should use then the compiler can just generate code to switch register banks rather than saving a whole bunch of registers. That makes the ISR go quicker. Unless you specify otherwise the compiler will use register bank 0 for everything. In general, if you can spare the 8 bytes of DATA memory per bank it is a good idea to specify a unique register bank for each of the most frequently called ISRs.
You don't need a register bank to be unique to each ISR. You can use the same register bank for each ISR that is at the same interrupt level. This is the case because an interrupt cannot itself be interrupted by an ISR at the same interrupt level. Assuming that main() uses register bank 0, then you can use register bank 1 for all low-priority interrupts and register bank 2 for all high priority interrupts. It is usually the case that an ISR with a specified register bank will run faster than the same ISR without a specified register bank. However, some ISRs are so simple that they do not actually use any of registers R0...R7 and consequently you will better off not switching register banks. If in doubt, specify a register bank.
"You don't need a register bank to be unique to each ISR. You can use the same register bank for each ISR that is at the same interrupt level. This is the case because an interrupt cannot itself be interrupted by an ISR at the same interrupt level." I'd never thought of that. Good point.
hi, You can use the same register bank for each ISR that is at the same interrupt level. ...as long as you do not use these registers as variables. There are tasks for which the speed is most important. In such case, usage of the registers to keep ISR's data is rather than memory locations. For example, one of my projects uses timer 2 for control PWM of PCA which plays sound. As digital stream frequence is about 22kHz and so ISR of timer 2 executes each ~45us. This ISR updates PWM with previously prepared value, checks is sound playback done, if not then reads next byte from external flash memory. Due lack of execution time I decided to keep flash memory address (3 bytes) and playback length (3 bytes) into R1...R6 of register bank I set for the ISR. You know, it increases the speed very well. Regards, Oleg
Graham Cole said: "You can use the same register bank for each ISR that is at the same interrupt level." Oleg Sergeev replied: "...as long as you do not use these registers as variables." Oleg: Presumably you are doing this in Assembler, not 'C'? I did wonder about the kind of thing you're suggesting, but I couldn't immediately see how you'd do it in C51.
hi, yes, Andy, ISR was wrote with ASM (actually it must be wrote such way as it requires high-speed optimization I done with hands). Then it was placed in separate .A51 file together with other ASM routines. Inside ASM I used bank switching, like:
CSEG AT 0x002B ; TF2 LJMP INT2_ISR ; ... INT2_ISR_SEG SEGMENT CODE RSEG INT2_ISR_SEG USING 1 ; register bank 1 INT2_ISR: PUSH PSW MOV PSW,#REGBANK_1 ; .... POP PSW RETI
data struct { unsigned char fa_lb; unsigned char fa_mb; unsigned char fa_hb; } flash_addr _at_ 0x09; data struct { unsigned char pbl_lb; unsigned char pbl_mb; unsigned char pbl_hb; } playback_length _at_ 0x12;
oops, I did a typpo. second structure is defined from 0x0C. Sorry, Oleg