Вывод printf в UART STM32 в IAR

Я писал статью об USART в STM32, сейчас же речь пойдет о том, как сделать так, что бы при вызове самой обычной printf данные отправлялись в UART.
Это нужно скорее для удобства. Допустим вам нужно организовать вывод дробных чисел. Без использования printf Вам понадобиться написать функцию для преобразования данных в строку. В принципе это не сложно и можно использовать sfprintf, но можно просто перенаправить вывод printf в нужную периферию (в нашем случае UART).

В разных средах программирования это делается по разному (из-за различных компиляторов, а иногда и реализаций библиотечных функций).
Для перенаправления вывода в IAR нужно добавить в проект файл из каталога среды. У меня вот так:

С:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\src\lib\write.c

Теперь найдите в нем функцию __write и уберите #ifdef чтобы получилось вот так:

size_t __write(int handle, const unsigned char * buffer, size_t size)
{
  /* Remove the #if #endif pair to enable the implementation */
  

  size_t nChars = 0;

  if (buffer == 0)
  {
    /*
     * This means that we should flush internal buffers.  Since we
     * don't we just return.  (Remember, "handle" == -1 means that all
     * handles should be flushed.)
     */
    return 0;
  }

  /* This template only writes to "standard out" and "standard err",
   * for all other file handles it returns failure. */
  if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR)
  {
    return _LLIO_ERROR;
  }

  for (/* Empty */; size != 0; --size)
  {
    if (MyLowLevelPutchar(*buffer++) < 0)
    {
      return _LLIO_ERROR;
    }

    ++nChars;
  }

  return nChars;
}

Отлично, эта библиотека предполагает, что мы реализуем функцию MyLowLevelPutchar, которая и будет заниматься пересылкой байта данных в нужную периферию.

int MyLowLevelPutchar(int x){
  while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
  USART_SendData(USART2, x);
  return x;
}

Думаю эта функцию Вам знакома. Ведь она просто пересылает данные в UART, подождав перед этим пока уйдут предыдущие.
Готово, теперь можем отправлять данные:

int main()
{
  STM_EVAL_LEDInit(LED3);
  STM_EVAL_LEDOn(LED3);
  
  init_usart();

  printf("Hello from stm32 printf!\r\n");
  float b = 132.89f;
  printf("b = %e", b);

  while(1) {
     STM_EVAL_LEDToggle(LED3);
     Delay(0x3FFFFF);           
  }
}

Вот как это выглядит в терминале:

Вывод printf в USART STM32

Как видите все работает ;)
Скачать проект перенаправления printf для IAR

Просмотров:   10410