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