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.
hi, When I write into SBUF, the TI flag doesn't go high Is UART configured right? Have you initialized and run clock source for UART (timer, BRD...)? Regards, Oleg
Initialization Seems OK to me. The Initialization code as given below. SCON = 0x50; /* mode 1: 8-bit UART, enable */ TMOD = TMOD | 0x20; /* timer 1 mode 2, 00100000b */ TH1 = 0x87; /* 600 BAUD @ 20 MHZ */ TR1 = 1; /* timer 1 ON */ TI = 1; /* Set TI to send first char */ ES = 1; /* enable serial port interrupt */ EA = 1; /* enable interrupts */
a)When I write into SBUF, the TI flag doesn't go high even though I have enabled interrupts. b)TI = 1; /* Set TI to send first char */ a) TI should set regardless of interrupts enabled or not. b) probably not a problem, but I would set TI after the interrupt is enabled. anyhow, the first thing your ISR should do is to clear TI, could it be that it does get set, but you do not catch the state before it is reset in the ISR? Try a breakpoint between set TI and int enb. Erik Erik
hi eric, that's not an issue as I'm stepping through my program using the debugger. The problem is I'm not able to SIMULATE the TI flag going high. For example if I want to simulate the RI flag first I run the initialization routine [as shown above]. then I write into the command line (or debug scrip) SIN = 0x43 (or any other value) and you will see that the RI flag going high in the peripherals/serial window, and suppose you have void serial() interrupt 4 { if (RI == 1) { keypressed = SBUF; RI = 0; } Then I can actually see that 0x43 is being written to keypressed before RI being cleared. But I can't see the TI flag raise when I try reading SOUT or writing to SBUF.
hi, assume you have wrote something like that:
void serial() interrupt 4 { //... receive code //... if (TI == 1) { TI = 0; SBUF=0x34; }
Baud Rate calculator: http://www.keil.com/c51/baudrate.asp
Hey Guys, That was not the problem. It can work at any Baud rate. Finally got it working by seeing the HELLO.c in Examples, but I don't know how!. Here is my code:- if (TI == 1) /* check for transmit interrupt flag */ { TI = 0; P1 ^= 0x01; /* Toggle P1.0 each time we print */ SBUF = "H"; } Also Need to keep the serial window open for the output to print. Still can't understand why TI flag doesn't raise if I don't toggle port pin 1.0 (T2). Thanks.
Perhaps you could post the smallest complete, compilable program which shows the problem. Please cut and paste this from your editor to guarantee that what you post is what you are using.
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.
Hi VK, I am have facing the same problem as you have mentioned i.e not able to get TI interrupt but for some reason but RI interrupt is immediately addressed when I press a key. I was under the impression that as soon as you write something to SBUF you would get TI interrupt but it does not happen. Do you have any additional information on this? Please reply to my hotmail id (rohitsivakumar@hotmail.com)
TI is set after the entire Byte plus the start and stoip bit are transmitted. That is the point of doing it with an interupt.you can do other things while waiting for the byte to finish leaving. If it set immediatly why would you need to look at it. Set a break point at you serial interupt. It will get there. It may take awhile single stepping.
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'; } } ---------------------------------------