I am having a problem with getting a serial port interrupt. The timer 1 & serial port interrupts are being set to the high priority level. Timer1 is being used to create the 9600 baud for my serial IO. I can transmit out by writing to the SBUF register and clearing TI outside of the Interrupt Service Routine(ISR). The ISR vector is: interrupt [0x23] void RITI_int (void) { P2.0=0; P2.0=1; EA=0; if (TI != 0) TI=0; //clear transmit interrupt bit if (RI != 0) { // read in the byte & put the data in the buffer. incoming_msg_buffer[incoming_hdr_ptr++] = SBUF; if (incoming_hdr_ptr >= RXBUFFER_SIZE) incoming_hdr_ptr = 0; rx_empty=FALSE; // renable rx interrupt RI = 0; } EA=1; }. I believe I am setting the sfrs correctly they are as follows: TMOD= 0x20; //8bit auto-reload timer1 TH1=0xfd; //value for 9600 baud TCON=0x40; //timer1 on SCON=0x40; //mode1 8bit uart,reciever enabled IE=0x98; //enable serial port interrupts, timer 1 interrupt SPE=0; //disable SPI interface P1=0xF0; //configure P1 lower nibble as digital inputs for key row read REN=1; //set reciever enable IP=0x18 // set timer1 & uart interrupts to high priority WDE=0; //disable watchdog-for now As I understand the TI is set by hardware on the stop bit when a byte is written to SBUF. RI is set when the stop bit is recieved into SBUF(separate from tx SBUF). When the ISR starts EA is set low, disableing all interrupts, and set back high at the end. In the ISR I am toggling a port pin and montoring with a scope on the target. It appears that the ISR is never initiated although I can transmit & recieving data outside of the ISR. Is there anything that doesn't look right? Thanks,
I am defining the ISR for timer1, I am using it to update a count variable used and reset elsewhere in main. Here are the ISRs, As you can see I am toggling a port pin in each. //ISRs void interrupt [0x23] void RITI_int (void) { P2.0=0; P2.0=1; EA=0; if (TI != 0) { TI=0; //clear transmit interrupt bit REN=1; //reenable reciever ??auto disabled during Transmit interrupt } if (RI != 0) { // read in the byte & put the data in the buffer. incoming_msg_buffer[incoming_hdr_ptr++] = SBUF; if (incoming_hdr_ptr >= RXBUFFER_SIZE) incoming_hdr_ptr = 0; rx_empty=FALSE; // renable rx interrupt RI = 0; } EA=1; } interrupt [0x1B] void TF1_int (void) { EA=0; P2.2=0; P2.2=1; count++; EA=1; } correct me if I am wrong, the timer overflow bit is reset automaticly when entering the timer ISR. When I transmit data is is going out at the 9600 baud that I intended, but I measured the occurance of the timer interrupt to be 28.8KHz(every 35us). shouln't it be closer to 300kHz. Since the UART ISR insn't being initiated, I have the following routine for sending out a message: for (i=0;i<=tx_length;i++) { SBUF=message[i]; while(TI!=1); //wait for end of transmission ??to be implemented in ISR TI=0; } I would expect that the ISR would be called after the write to SBUF, but it never gets there, so I wait until TI goes HI. Mark, I do have ES and EA enabled, however I do set EA low while in the ISR and set back HI when finished.
I am defining the ISR for timer1, I am using it to update a count variable used and reset elsewhere in main. Here are the ISRs, As you can see I am toggling a port pin in each. Very bad idea. I believe you are warned against doing this in the 8051 documenation. Use Timer 0 for timing when Timer 1 is used for BRG. Don't disable interrupts inside an interrupt. It's bad form. If you have a higher priority interrupt enabled either disable that single interrupt or make your UART ISR interrupt safe. You do not need to touch REN after it is set during some init function. This is a real mess, no offense. Good greif just look at my UART example on my web site. Start there and hack away until you get just what you need. When sharing read and write access to a variable between main loop and ISR code you must make it volatile, e.g. count should be a volatile var. Boy, those ISR's sure look like they're from IAR not Keil.
Dave, > I measured the occurance of the timer interrupt to be 28.8KHz(every 35us). shouln't it be closer to 300kHz Therefore the TF1 interrupt is occurring about 10 times faster than the ISR can process it and is always asserted. High level code always gets one opcode processed before the next interrupt can interfere, so the high level code still is getting 1-3% of the processor time. But look at the rules for resolution of simultaneous interrupts of equal priority. For the 8051, the RI+TI is lower priority than TF1. Thus, no RI+TI. This is a theory to fit the facts, but I've never tested simultaneous interrupts. Actually, I had previously thought that the "polling sequence" meant that each of the simultaneous interrupts would eventually get priority. Now, I think not. Thanks, Robert
In your original post...
TH1=0xfd;