Hi, I'm trying to simulate working of a UART. When I write into SBUF, the TI flag doesn't go high even though I have enabled interrupts. Is there any way I can simulate it using SOUT VTREG. can't find example how to use SOUT.
Considering your example code, only two things come to mind: 1) reitteration of the question Oleg posed: Are you waiting long enough? 2) Make sure you don't have timer 1 overriden via inadvertently setting the RCLK and TCLK of a dormant Timer 2.
What is wrong in this below code? Why does the TI interrupt never fire. ie. why if something is written into SBUF, the hardware does not automatically set TI flag to fire the interrupt. I did single stepping and waited for too long and also did a continous execution using "F5" button still no luck. Any help would be very much appreciated and helpful to me. /////////////////////////////////////////// /* Serial Port Usage Example */ #include <AT89S52.H> char keyPressed; void serial_int (void) interrupt 4 using 1 { if(TI) { TI = 0; } else { keyPressed = SBUF; RI = 0; } } void main(void) { /* INITIALIZE THE UART*/ TMOD=0x20; /* use timer1, mode 2 */ TH1=0xFD; /* 9600 baud with a 11.059mHz clock */ SCON=0x50; /* enable receive */ TF1 = 0; TR1 = 1; EA = 1; ES = 1; TI = 1; RI = 1; while(1) { SBUF = 'Y'; }; } // end main
There are many errors in the code you have posted. I suggest you take a look at the interrupt driven serial comms example program available on this site.
I looked into the examples given by Keil where it uses some tbuf and rbuf. I want something very simple. Infact to my surpise the same code that I have pasted works if I introduce a delay using a for loop. (again the delay has to be changed for different baud rate). I am not sure what I am missing but it would be really very nice if you could send me a very simple serial example ie.in the same manner I have posted which I could use as a reference. Thanks.
The same code which I posted above, the same when modified as shown below works. The only difference between the two which brings the change is the for loop inside the main(). I am not sure why this delay is needed but then with this delay I am able to see 'Y' getting repeatedly displayed on the com port. Any idea as to why this delay is needed or what am I doing wrong? If I could get the same code modified with corrections then it would help in understanding. ------------------------------------------- #include <AT89S52.H> void serial_int (void) interrupt 4 { if (RI == 1) /* it was a receive interrupt */ { RI = 0; /* clear the received interrupt flag */ } else if (TI == 1) /* otherwise, assume it was a transmit interrupt */ { TI = 0; /* clear the transmit interrupt flag */ } } void main(void) { SCON = 0x50; /* mode 1, 8-bit uart, enable receiver */ TMOD = 0x20; /* timer 1, mode 2, 8-bit reload */ TH1 = 0xFD; /* reload value for 2400 baud */ ET0 = 0; /* we don't want this timer to make interrupts */ TR1 = 1; /* start the timer */ TI = 1; /* clear the buffer */ ES = 1; /* allow serial interrupts */ EA = 1; /* enable interrupts */ while (1) { unsigned int i; for (i = 0; i < 120; i++) {;} /* delay */ SBUF = 'Y'; } } ---------------------------------------
while(1) { SBUF = 'Y'; };
You need to choose whether to use interrupts or a polled approach. You are trying to mix the two - this will only make your life difficult.
Hi Stefan, I would like to use the interrupt based approach. Could you please post the same code in the way you suggest me to write. It would help a lot. Thanks.
Rohit, If you're trying to use an interrupt-based methodology just to prove to yourself that you can send a string of 'H's or 'Y's out the port, just change your code as follows: Make the ISR look like this:
void serial_int (void) interrupt 4 { if (RI) RI = 0; if (TI) { TI = 0; SBUF = 'Y'; } }
while (1){}
"I would like to use the interrupt based approach. Could you please post the same code in the way you suggest me to write." If I did that I'd be posting code nearly identical to Keil's example. If you are having trouble understanding the code in their example just post any questions you might have. If you want to use interrupt driven serial comms in your project you may as well bite the bullet and use a full implementation. The code is there, it's free and it (probably) works. Once you have compiled it into your project you can forget about SBUF, TI and RI, all you need to do is use the standard 'C' library functions.
View all questions in Keil forum