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

Some matter with my "printf()",what can i do ?

When program running to "printf()",the PC always stop at

C:0X0A2A 3099FD JNB TI(0X98.1),C:0A2A
I try adding some word as following :
ES = 0;   //UART INT is Enable before
TI = 1;
printf("%bd",3);
ES = 1;

So , the program running well.Can you tell why being disable UARTs'INT and Setting TI are necessary? How can i overleap this word ?

Another question,why "printf("%bd",3);" can send unsigned char variable to PC right while "printf("%c",3);" not ? What's different between %bd and %c?

  • C:0X0A2A 3099FD JNB TI(0X98.1),C:0A2A

    This instruction waits for the TI bit to get set. You need to read-up on that this bit is used for. You need to set it the first time but it is set by hardware thereafter.

    Can you tell why being disable UARTs'INT and Setting TI are necessary?

    The printf function calls putchar to send a byte. By default, the putchar routine uses a polled scheme to send characters. Did you write your own putchar for the interrupt?

    What's different between %bd and %c?

    A lot. %bd sends a number encoded in ASCII. %c sends the ASCII character. So, "%bd", 3 transmits the ASCII character 51 while "%c",3 transmits the ASCII character 3.

    Jon

  • Thanks Jon.
    The puchar() routine doesn't be changed ,I just write a UART INTTERUPT routine for receiving the data from Decode_Card and enable UART Interrupt in Initial().When debugged in UV3,the program output nothing without

      ES = 0; TI = 1
    ,and the same to running on object_board

  • The program outputs nothing because the interrupt is getting triggered each time TI is set. You can't mix polled and interrupt-driven serial I/O on an 8051.

    Jon

  • Catch your words,if enable UART-Interrupt then can't use printf() to poll flag's bit .Can you give me some example about sending data from 8051 with UART Interrupt routine?
    Thanks.

  • PUTCHAR.C:
    /***********************************************************************/
    
    #include <reg51.h>
    
    #define XON  0x11
    #define XOFF 0x13
    
    
    /*
     * putchar (full version):  expands '\n' into CR LF and handles
     *                          XON/XOFF (Ctrl+S/Ctrl+Q) protocol
     */
    char putchar (char c)  {
    
      if (c == '\n')  {
        if (RI)  {
          if (SBUF == XOFF)  {
            do  {
              RI = 0;
              while (!RI);
            }
            while (SBUF != XON);
            RI = 0;
          }
        }
        while (!TI);
        TI = 0;
        SBUF = 0x0d;                         /* output CR  */
      }
      if (RI)  {
        if (SBUF == XOFF)  {
          do  {
            RI = 0;
            while (!RI);
          }
          while (SBUF != XON);
          RI = 0;
        }
      }
      while (!TI);
      TI = 0;
      return (SBUF = c);
    }
    
    
    
    #if 0         // comment out versions below
    
    /*
     * putchar (basic version): expands '\n' into CR LF
     */
    char putchar (char c)  {
      if (c == '\n')  {
        while (!TI);
        TI = 0;
        SBUF = 0x0d;                         /* output CR  */
      }
      while (!TI);
      TI = 0;
      return (SBUF = c);
    }
    
    
    /*
     * putchar (mini version): outputs charcter only
     */
    char putchar (char c)  {
      while (!TI);
      TI = 0;
      return (SBUF = c);
    }
    
    #endif
    

    It's known that function printf() call the function putcha() .In the function putchar() ,why Transmitting Flag TI must be polled and set before sending a char ? And,when system reset ,SCON 's value is 00H,meaning flag TI also is 00H,how can printf() sending data this time?

  • There are knowledgeable people here who emphasize reading the manuals because no number of short answers from someone else can substitute for your own learning.
    TI must be polled because it takes the transmit module time to transmit the byte after it is loaded into the Tx buffer, at 9600baud it's around 1 ms, this is a LONG time for the cpu. It can do alot and come back around with the next byte to send before the Tx module is done sending the first byte. So the cpu polls the TI bit and waits until the transmission is complete because the TI bit is set at that time.
    After power up you don't need to set the TI bit, just load the Tx buffer with the first byte after transmission and interrupts are enabled. The module will set TI after the byte is sent and your isr will be called.
    Most of my applications set TI in "main loop" code to request transmission because there is some sort of packet structure and it's just neater to keep all of the state machine/error handling in the isr.

  • There are knowledgeable people here who emphasize reading the manuals because no number of short answers from someone else can substitute for your own learning.

    Stating the same in another way:
    If you study for a week, you can get going in a week. If you do not study and ask here for every step you will get going in a year.

    Erik