Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

problem with TI flag in 89c5x microcontrollers

Status
Not open for further replies.
vietdung79 said:
So if you clear ES (don't use UART interrupt) could you send data?
without interrupt I can send data, but how could I receive data? I have two ways:
1- monitoring RI flag (waisting time)
2- using interrupt (that causes so much problem)
at the i don't know what to do. :?::?::?:
 

faraj said:
without interrupt I can send data, but how could I receive data? I have two ways:
1- monitoring RI flag (waisting time)
2- using interrupt (that causes so much problem)
at the i don't know what to do. :?::?::?:
Learn how to use properly interrupts :)

If you want to stick to interrupt-driven reception, you have to transmit in interrupt, too.

In fact, you don't need to actually pass characters in a buffer between "main" and the interrupt - although that's the most general case; it's enough to copy the TI flag into a bit variable in interrupt and clear it - and for the main, this bit variable is now the indicator that the character has been sent. Something like:
Code:
[...]

My_TI: dbit 1

[...]

UART_ISR:
   jnb   ri,UART_ISR_Tx
   [manage reception and clear ri]
UART_ISR_Tx:
   jnb   ti,UART_ISR_Exit
   setb My_TI
   clr    ti
UART_ISR_Exit:
   reti

[...]

TxByte:
   clr   My_TI
   mov   SBUF,a
   jnb   My_TI,$
   ret

[...]
JW
 

    faraj

    Points: 2
    Helpful Answer Positive Rating
There are some problem with your programme:

1) You didn't clear RI in your ISR
2) You didn't clear TI in your ISR
3) You use getkey() but I think you don't know how it work. You should rewrite this function
4) If you want to send the data and use the interrupt to receive data, you should change the putchar() as below:
Code:
/*
 * putchar (mini version): outputs charcter only
 */
char putchar (char c)  {
  SBUF = c
  while (!TI);
  TI = 0;
  return (c);
}
 

wek said:
faraj said:
without interrupt I can send data, but how could I receive data? I have two ways:
1- monitoring RI flag (waisting time)
2- using interrupt (that causes so much problem)
at the i don't know what to do. :?::?::?:
Learn how to use properly interrupts :)

If you want to stick to interrupt-driven reception, you have to transmit in interrupt, too.

In fact, you don't need to actually pass characters in a buffer between "main" and the interrupt - although that's the most general case; it's enough to copy the TI flag into a bit variable in interrupt and clear it - and for the main, this bit variable is now the indicator that the character has been sent. Something like:
Code:
[...]

My_TI: dbit 1

[...]

UART_ISR:
   jnb   ri,UART_ISR_Tx
   [manage reception and clear ri]
UART_ISR_Tx:
   jnb   ti,UART_ISR_Exit
   setb My_TI
   clr    ti
UART_ISR_Exit:
   reti

[...]

TxByte:
   clr   My_TI
   mov   SBUF,a
   jnb   My_TI,$
   ret

[...]
JW

ok. thanks, I'll try your suggession. hope to work.

Added after 1 minutes:

vietdung79 said:
There are some problem with your programme:

1) You didn't clear RI in your ISR
2) You didn't clear TI in your ISR
3) You use getkey() but I think you don't know how it work. You should rewrite this function
4) If you want to send the data and use the interrupt to receive data, you should change the putchar() as below:
Code:
/*
 * putchar (mini version): outputs charcter only
 */
char putchar (char c)  {
  SBUF = c
  while (!TI);
  TI = 0;
  return (c);
}

I'll try your suggession too. thank you so much.
 

I tried your suggession (rewriting the putchar() function) but the problem is existing yet.
vietdung79 said:
There are some problem with your programme:
1) You didn't clear RI in your ISR
I do not clear the RI flag because the getkey() function do it itself.
vietdung79 said:
2) You didn't clear TI in your ISR
I do not clear the TI flag because when I send data I disable serial interrupt and after sending data enable it and the TI flag is cleard when data has been sent. and except the sending data there is no instruction in my code to set the TI flag. but it gets set with an unknown reason.
vietdung79 said:
3) You use getkey() but I think you don't know how it work. You should rewrite this function
what changes should i do with getkey() function?
vietdung79 said:
4) If you want to send the data and use the interrupt to receive data, you should change the putchar() as below:
Code:
/*
 * putchar (mini version): outputs charcter only
 */
char putchar (char c)  {
  SBUF = c
  while (!TI);
  TI = 0;
  return (c);
}
 

Hi,
As WEK has shown, why don't you follow this simple logic of interrupt handling?

1. In the main routine you enable serial tx/rx interrupts and do whatever you want to do. Do not set TI bit. If data is there in buffer, either load SBUF with the first byte of data or simply set TI bit.
2. In your serial interrupt routine, follow the steps below:
a. Disable all interrupts.
b. Check if RI is set, If set, Clear RI and read data. Go to c.
c. check if TI is set , If set, Clear TI. Load next byte into SBUF if buffer not
empty .Go to d.
d. Enable Interrupt. Go to e.
e. RETI

DONOT CLEAR the interrupt flags either in Get() or Printf() functions. Do it always at the beginning of the interrupt routine as given above. Remember that a TI interrupt will only occur after 8 bits are shifted out and it takes time. So your
Printf() will not be able to clear the bit generated by its present action.

Regards,
Laktronics

Added after 4 hours 10 minutes:

Hi,
On further thinking, I feel some more constraints are to be put on step 1 given above. That is in the Main program, initiation of Tx operation should be done only under certain conditions.
Eg. Under step 1, you may initiate a TX, only when the buffer is full and will not initiate another Tx unless the buffer is empty and the interrupt due to the last character transmitted is also serviced. The catch here is due to the delay in transmission of each byte. At 9600 baud, each byte takes 1msec to be shifted out, including the start and stop bits and CPU can execute many instructions during this period. So during this period if the main routine simply checks the status of TI, it will be Zero, but it should not set TI bit now. In order to see if the last interrupt due to the last character transmitted is over, may be the interrupt routine should set a flag if a TX interrupt has occurred and there was no byte in the buffer to transmit. This flag should be checked by the main routine before initiating another TX and the flag should be cleared along with TX initiation.

Regards,
Laktronics
 

    faraj

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top