Hi All, When simulating an interupt from serial port RX0, I cannot succeed in affecting SBUF0 to a local variable, the watch window shows this variable to 0 even if SBUF0 is set. Here is my code : static void serial_port_0_isr (void) interrupt COM0_VECT { unsigned char data_received; if (RI != 0) { RI = 0; data_received = SBUF0; ... } } on the above code, data_received is always 0 even if SBUF0 is set. To set SBUF0, I use the serial port window from the simulator. any idea would be appreciated.
Have you tried the interrupt-driven serial example at http://www.keil.com/download/docs/intsio2.zip.asp? Jon
are you sure that the simulator actually uses SBUF0, and not just SBUF?
I've not compiled this code but it is quite the same than mine ..
I currently compile on a EZ-USB chip which features 2 hardware serial ports, their corresponding buffers are SBUF0 & SBUF1. I forgot to mention that the generated asm seems correct !
So: how are you "simulating a serial port interrupt", then? Did you set a breakpoint in your ISR and see if execution ever actually got there? Did you step through it to observe what actually happens?
Did you set a breakpoint in your ISR and see if execution ever actually got there? Did you step through it to observe what actually happens? Yes the ISR is succesfuly called, the problem is while affecting the SBUF0 to a local register, the simulator watch window does not show me the affected value, which remains 0. The SBUF0 resgister is defined as follow in the ezregs.h sfr SBUF0 = 0x99; My code: static void serial_port_0_isr (void) interrupt COM0_VECT { unsigned char data_received; if (RI != 0) <<-- breakpoint here, the ISR is successfuly called { RI = 0; data_received = SBUF0; <<-- Here data_received is not affected ... } }
What do you do with data_received after this line? If you do nothing with it, the optimier may well have removed it! Have you looked at the generated assembler, or tried stepping at assembler level?
The next line is a test on data-received, as follow: static void serial_port_0_isr (void) interrupt COM0_VECT { unsigned char data_received; if (RI != 0) <<-- breakpoint here, the ISR is successfuly called { RI = 0; data_received = SBUF0; <<-- Here data_received is not affected ... if(data_received > 0xF8) Treat_Realtime_MIDI(data_received); ... } the line data_received = SBUF0 generates the following asm : MOV R7,SBUF0(0x99) anyway when stepping on asm, the R7 register remains to 0 while SBUF0 was 0x08 What about a memory configuration problem ? I currently use a EZUSB where only USB endpoints 0 & 1 are used, I therefore allow the compiler to use xdata memory from 0 to 0x1E40, using the modified startup.a51 code as follow: IDATALEN EQU 80H ; the length of IDATA memory in bytes. ; XDATASTART EQU 0H ; the absolute start-address of XDATA memory XDATALEN EQU 1E40H ; the length of XDATA memory in bytes. ; PDATASTART EQU 0H ; the absolute start-address of PDATA memory PDATALEN EQU 0H ; the length of PDATA memory in bytes. ; I dont know if there is a relation, I'm quite lost regarding this simulation issue !
"anyway when stepping on asm, the R7 register remains to 0 while SBUF0 was 0x08" Are you using the correct Register Bank?
well I'm new to keil and 8051, I was assuming the C compiler is able to use correct banking, which becomes transparent to the programmer, at least at the C level !? Am I wrong ? Do I have to manage banking in C ?
"Am I wrong?" Yes "Do I have to manage banking in C?" Yes - see the using keyword extension, and the REGISTERBANK Control Directive
Can you show us the assembler code generated for...
static void serial_port_0_isr (void) interrupt COM0_VECT { unsigned char data_received; if (RI != 0) <<-- breakpoint here, the ISR is successfuly called { RI = 0; data_received = SBUF0; <<-- Here data_received is not affected ... if(data_received > 0xF8) Treat_Realtime_MIDI(data_received); ... }
here is the code: #pragma NOAREGS Check_Midi_In_From_Con_Data_Received(data_received) { ... } #pragma AREGS static void serial_port_0_isr (void) interrupt COM0_VECT { unsigned char data_received; /* ********* Received data interrupt ******** */ if (RI != 0) { // clear interupt flag RI = 0; // Now treat itr from serial port 0 data_received = SBUF0; // Treat incoming data received if(data_received > 0xF7) Check_Midi_In_From_Con_Data_Received(data_received); } /* ********* Transmited data interrupt ******** */ if (TI != 0) { TI = 0; } } The ISR call works, I dont use any banking, it is compiled for a ezusb an21xx, with 8k internal ram. SFBUF0 is defined as sfr SBUF0 = 0x99; from ezregs.h. The affectation data_received = SBUF0 produces MOV R7,SBUF0(0x99) Thanks ...
here is the asm .. serial_port_0_isr: C:0x0BA9 C0E0 PUSH ACC(0xE0) C:0x0BAB C0F0 PUSH B(0xF0) C:0x0BAD C083 PUSH DPH(0x83) C:0x0BAF C082 PUSH DPL(0x82) C:0x0BB1 C0D0 PUSH PSW(0xD0) C:0x0BB3 75D000 MOV PSW(0xD0),#midi_in_from_con_buff(0x00) C:0x0BB6 C000 PUSH midi_in_from_con_buff(0x00) C:0x0BB8 C001 PUSH 0x01 C:0x0BBA C002 PUSH 0x02 C:0x0BBC C003 PUSH 0x03 C:0x0BBE C004 PUSH 0x04 C:0x0BC0 C005 PUSH 0x05 C:0x0BC2 C006 PUSH 0x06 C:0x0BC4 C007 PUSH 0x07 C:0x0BC6 30980D JNB RI(0x98.0),C:0BD6 C:0x0BC9 C298 CLR RI(0x98.0) C:0x0BCB AF99 MOV R7,SBUF0(0x99) C:0x0BCD EF MOV A,R7 C:0x0BCE D3 SETB C C:0x0BCF 94F7 SUBB A,#0xF7 C:0x0BD1 4003 JC C:0BD6 C:0x0BD3 120794 LCALL Check_Midi_In_From_Con_Data_Received(C:0794) C:0x0BD6 309902 JNB TI(0x98.1),C:0BDB C:0x0BD9 C299 CLR TI(0x98.1) C:0x0BDB D007 POP 0x07 C:0x0BDD D006 POP 0x06 C:0x0BDF D005 POP 0x05 C:0x0BE1 D004 POP 0x04 C:0x0BE3 D003 POP 0x03 C:0x0BE5 D002 POP 0x02 C:0x0BE7 D001 POP 0x01 C:0x0BE9 D000 POP midi_in_from_con_buff(0x00) C:0x0BEB D0D0 POP PSW(0xD0) C:0x0BED D082 POP DPL(0x82) C:0x0BEF D083 POP DPH(0x83) C:0x0BF1 D0F0 POP B(0xF0) C:0x0BF3 D0E0 POP ACC(0xE0) C:0x0BF5 32 RETI
OK, that looks about right. I created the following program and it works 100% correctly.
#include <reg51.h> #define COM0_VECT 4 #define SBUF0 SBUF void main (void) { SCON = 0x50; TMOD |= 0x20; TH1 = 221; TR1 = 1; ES = 1; EA = 1; while (1); } #pragma NOAREGS void Check_Midi_In_From_Con_Data_Received( unsigned char data_received) { P1 = data_received; } #pragma AREGS static void serial_port_0_isr (void) interrupt COM0_VECT { unsigned char data_received; /* ********* Received data interrupt ******** */ if (RI != 0) { // clear interupt flag RI = 0; // Now treat itr from serial port 0 data_received = SBUF0; // Treat incoming data received if(data_received > 0xF7) Check_Midi_In_From_Con_Data_Received(data_received); } /* ********* Transmited data interrupt ******** */ if (TI != 0) { TI = 0; } }