Я писал статью об 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 для IAR






