This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Can't get TI flag to be set when writing into SBUF

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.

Parents
  • Rohit,

    You are incorrect about the reentrancy problem. You need to learn a bit more about the way the 8051's interrupt system works. While you are servicing an interrupt, you WILL not be interrupted again by the same source. In other words, your ISR WILL finish running even if the character finished transmitting before you finished what you needed to do in the ISR. Look at the "RETI" assembly instruction for the 8051 to understand why a bit more.

    That being said, here is a way to do what you're trying to do, just to give you an idea how serial communications works. Also note, that this isn't the stylistically best way to do things, so just use this as a learning example.

    unsigned char xmitbuf[25];
    unsigned char outpos = 0;
    unsigned char outsize = 0;
    
    void serial_isr (void) interrupt 4 {
      if (RI)
        RI = 0;
      if (TI) {
        TI = 0;
        if (outpos < outsize) {
          SBUF = xmitbuf[outpos++];
        } else {
          outpos = 0;
          outsize = 0;
        }
      }
    }
    
    void some_func(char *str) {
      if (outsize == 0) {
        outsize = strlen(str);
        memcpy(xmitbuf, str, outsize);
        TI = 1;
      }
    }
    
    
    void main(void) {
      some_func("Hello World");
      while(1);
    }
    

    Note that this is STILL going to have problems until you resolve your difficulty with interrupt-based versus polled I/O. For instance, if you change main to be:

    void main(void) {
      some_func("Hello World");
      some_func("Next Message");
      while (1);
    }
    

    then only the FIRST message will be transmitted. This is because you'll be trying to overwrite the buffer that's being used to transmit and some_func will smartly not allow that. Again, I hope this helps you understand how this sort of this works with the 8051.

Reply
  • Rohit,

    You are incorrect about the reentrancy problem. You need to learn a bit more about the way the 8051's interrupt system works. While you are servicing an interrupt, you WILL not be interrupted again by the same source. In other words, your ISR WILL finish running even if the character finished transmitting before you finished what you needed to do in the ISR. Look at the "RETI" assembly instruction for the 8051 to understand why a bit more.

    That being said, here is a way to do what you're trying to do, just to give you an idea how serial communications works. Also note, that this isn't the stylistically best way to do things, so just use this as a learning example.

    unsigned char xmitbuf[25];
    unsigned char outpos = 0;
    unsigned char outsize = 0;
    
    void serial_isr (void) interrupt 4 {
      if (RI)
        RI = 0;
      if (TI) {
        TI = 0;
        if (outpos < outsize) {
          SBUF = xmitbuf[outpos++];
        } else {
          outpos = 0;
          outsize = 0;
        }
      }
    }
    
    void some_func(char *str) {
      if (outsize == 0) {
        outsize = strlen(str);
        memcpy(xmitbuf, str, outsize);
        TI = 1;
      }
    }
    
    
    void main(void) {
      some_func("Hello World");
      while(1);
    }
    

    Note that this is STILL going to have problems until you resolve your difficulty with interrupt-based versus polled I/O. For instance, if you change main to be:

    void main(void) {
      some_func("Hello World");
      some_func("Next Message");
      while (1);
    }
    

    then only the FIRST message will be transmitted. This is because you'll be trying to overwrite the buffer that's being used to transmit and some_func will smartly not allow that. Again, I hope this helps you understand how this sort of this works with the 8051.

Children
No data