Development environment: Keil RVMDK Using printf for serial communication in STM32 programs is very convenient, but it's common to run into issues when first implementing it. One frequent problem is that the program doesn't enter the main function when running on real hardware. However, this issue can be easily resolved with proper configuration. In this article, we’ll walk through how to configure your project to make sure that printf works correctly. There are two main approaches to configure printf in Keil RVMDK for STM32: First Method: Configure Project Properties 1. Include the standard input/output header file 2. Redefine the For receiving data, you can also define a custom This setup ensures that whenever you use 3. Make sure to check the option Second Method: Add "Regtarge.c" File to the Project 1. Include 2. Create a new file named 3. In your main file, define the following functions: Once these configurations are complete, you should be able to freely use Lcd Integrated Display,Lcd Panel Indoor Display,Good Angle Lcd Segment Display,Va Lcd Panel Display Wuxi Ark Technology Electronic Co.,Ltd. , https://www.arkledcn.com"stdio.h"
in your main file.fputc
function in your main file as follows:
// Send data
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (unsigned char)ch); // Replace USART1 with USART2 or other as needed
while (!(USART1->SR & USART_FLAG_TXE));
return (ch);
}
GetKey()
function:
// Receive data
int GetKey(void)
{
while (!(USART1->SR & USART_FLAG_RXNE));
return ((int)(USART1->DR & 0x1FF));
}
printf
, it calls your custom fputc
function to send characters over UART."Use MicroLIB"
under Target > Code Generation
in the project properties. MicroLIB is a lightweight C library provided by Keil and is often used for embedded applications."stdio.h"
in your main file.Regtarge.c
and add it to your project. Paste the following code into it:
#include "stdio.h"
#include "rt_misc.h"
#pragma import(__use_no_semihosting_swi)
extern int SendChar(int ch); // Declare external function defined in main
extern int GetKey(void);
struct __FILE {
int handle; // Add whatever you need here
};
FILE __stdout;
FILE __stdin;
int fputc(int ch, FILE *f) {
return (SendChar(ch));
}
int fgetc(FILE *f) {
return (GetKey());
}
void _ttywrch(int ch) {
SendChar(ch);
}
int ferror(FILE *f) { // Your implementation of ferror
return EOF;
}
void _sys_exit(int return_code) {
label: goto label; // Infinite loop
}
int SendChar(int ch) {
while (!(USART1->SR & USART_FLAG_TXE)); // Replace USART1 with your serial port
USART1->DR = (ch & 0x1FF);
return (ch);
}
int GetKey(void) {
while (!(USART1->SR & USART_FLAG_RXNE));
return ((int)(USART1->DR & 0x1FF));
}
printf
in your STM32 project without any issues. This setup ensures that all output from printf
is sent via the selected UART interface, making debugging and testing much easier during development.