0
\$\begingroup\$

Now I'm trying to analyze STM32F103 Cortex-m3's UART code in IRQ and Polling mode.

Ans I found 2 types example code such as the below. This is IRQ.

/*------------------------------------------------------------------------------
  SenChar
  transmit a character
 *------------------------------------------------------------------------------*/
int SendChar (int c) {
  struct buf_st *p = &tbuf;

                                                  // If the buffer is full, return an error value
  if (SIO_TBUFLEN >= TBUF_SIZE)
    return (-1);

  p->buf [p->in & (TBUF_SIZE - 1)] = c;           // Add data to the transmit buffer.
  p->in++;

  if (tx_restart) {                               // If transmit interrupt is disabled, enable it
    tx_restart = 0;
    USART1->CR1 |= USART_FLAG_TXE;                // enable TX interrupt
  }

  return (0);
}

This is a Polling method.

/*----------------------------------------------------------------------------
  SendChar
  Write character to Serial Port.
 *----------------------------------------------------------------------------*/
int SendChar (int ch)  {

  while (!(USART1->SR & USART_FLAG_TXE));
  USART1->DR = (ch & 0x1FF);

  return (ch);
}

But I can't understand why do they have difference code?

\$\endgroup\$
  • \$\begingroup\$ The "IRQ" seems to use a DMA to transfer a whole buffer (tbuf) (Config not seen in your code example). The "Polling" method just sends a single char. \$\endgroup\$ – Batuu Aug 25 '17 at 8:15
1
\$\begingroup\$

Stupid answer: because one uses IRQ and the other polling... You can't really expect two different methods to have the same code?


For the IRQ method you are missing half of the implementation, as the interrupt handler is missing, which is actually putting the bytes of the send buffer into the data register of the UART.

And that is the main difference. The interrupt method has a send buffer, so you can stuff in bytes into the buffer and the method will return although the bytes have not been sent. This allows your controller to do some work while the interrupt will handle the sending of the bytes out of the buffer.


The polling method on the other hand sends the byte directly. It waits until an ongoing transfer of the UART is over and then sends the next byte.

In that case the method will block until an eventually ongoing transfer is finished and send the byte away.


If you just send a single byte, the interrupt method is overkill, because the use of a buffer for a single byte is just a waste if you could just put it in the UART directly.

But think of the context such a function is typically used:

SendString(char* string)
{
    int i=0;
    while (string[i] != 0)
    {
        if (string[i] == SendChar(string[i]))
        {
            i++;
        }
    }
}

Now in the case of the interrupt method, the SendString will have the possibility to stuff the whole string into the send buffer (if it is large enough), returning very quickly and your program can move on calculating stuff or whatever.

The polling method would take as long as it takes the UART to transfer the bytes (minus one because it doesn't wait for the last one, to be exact). Depending on the UART speed, that might be some costly milliseconds.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.