I am using Atmel AT89C51CC03, and it is configured so in Keil too. The data sheet lists the SPI interrupt vector as 0x0053h, and I do define my interrupt as interrupt #10. However, the map file show my SPI interrupt has address of 0x0026h.
Does anyone know why is that? Anything I can do to make it right?
Thanks in advance!
I checked disassembly, and it seems the compiler does put interrupt at 0026h. But I just don't understand why the compiler does that.
C:0x0023 022217 LJMP com_isr(C:2217) 469: static void SPICommISR(void) interrupt 10 470: { 471: static UINT8 SpiHeader; 472: UINT8 tmpchar; 473: static UINT8 crcvalue; 474: static BOOLEAN SpiValid; 475: C:0x0026 C0E0 PUSH ACC(0xE0) C:0x0028 C083 PUSH DPH(0x83) C:0x002A C082 PUSH DPL(0x82) C:0x002C 63A201 XRL AUXR1(0xA2),#0x01 C:0x002F C083 PUSH DPH(0x83) C:0x0031 C082 PUSH DPL(0x82) 476: if (SPSCR & 0x80) C:0x0033 E5D5 MOV A,0xD5 C:0x0035 30E70B JNB 0xE0.7,C:0043 477: { 478: #ifdef SPIDEBUG 479: tmpchar = SPDAT; C:0x0038 90036B MOV DPTR,#0x036B C:0x003B E5D6 MOV A,0xD6 C:0x003D F0 MOVX @DPTR,A 480: SPDAT = 0xCC; C:0x003E 75D6CC MOV 0xD6,#TL2(0xCC) 481: P4_0 = ~P4_0; C:0x0041 B2C0 CPL P4_0(0xC0.0) 624: } C:0x0043 D082 POP DPL(0x82) C:0x0045 D083 POP DPH(0x83) C:0x0047 63A201 XRL AUXR1(0xA2),#0x01 C:0x004A D082 POP DPL(0x82) C:0x004C D083 POP DPH(0x83) C:0x004E D0E0 POP ACC(0xE0) C:0x0050 32 RETI
The CPU vectors to the interrupt address. The compiler puts the address of the subroutine it wants call there. the full subroutine would most likely not fit since Intel only left a few bytes before the next interrupt vector.
Is there any setting I should change to make compiler do that? There are only 8 bytes from one interrupt vector address to next. And with all the push/pop, I do need a LJUMP. At address 0023, compiler does have a LJMP for my UART interrupt, but I just don't know why it would not do it for SPI interrupt.
For the UART interrupt I have
static void com_isr (void) interrupt 4 using 2
Does a different bank help?
I do need a LJUMP. At address 0023, compiler does have a LJMP for my UART interrupt, but I just don't know why it would not do it for SPI interrupt.
Why don't you disassemble the instruction that is at address 0x53 and see what it is? I'll bet i can guess.
CODE 0053H 0003H ABSOLUTE
And with all the push/pop, I do need a LJUMP.
And you got one. It's just not where you're looking for it. The LJMP is at 0x53, just where the interrupt vector for interrupt number 10 belongs. But it would be rather wasteful if the linker were to put nothing at all in the entire address range from 0x26 to 0x53. So it found something that fits in the gap and put it there. Your SPI interrupt routine apparently fit the bill.
If you wished, You could prevent that by ensuring that you do provide an ISR for all possible interrupts; eg,
static void dummyISRxx(void) interrupt xx { for(;;); }
You could use this to prevent any unexpected behaviour if one of the "unused" interrupts should, somehow, accidentally get enabled...
You guys are right. I do have a LJMP at 0x53. Then I still do not know what causes my problem. In my interrupt routine, I basically toggle P4_0, but on my scope, I can see the P4_0 toggles even when chip select is high. Too bad that I can not post screen shot here, but basically my MOSI rest at 2.7V, and every 12.5 usec, there are two small pulses pull the voltage to 3.6V. P4_0 toggles at the rising edge of the first small pulse, and my chip select is solid high. I know the voltage is a little strange and I don't know what cause these small pulses, but if the chip select is high, then it should not trigger interrupt at all, right? Any suggestions? Thanks,
Can you post it somewhere else, and then provide a Link here?
Take me a while to bypass company firewall, but here you are:
www.flickr.com/.../42986638@N02/3963290758/
www.flickr.com/.../42986638@N02/3963290852/