Stm32 serial communication uses printf to send data configuration

Development Environment: Keil RVMDK

Using printf for serial communication in STM32 programs is very convenient. However, it's common to face issues when using it for the first time. One of the most frequent problems is that the program doesn't enter the main function when running on real hardware. The good news is that this can be easily fixed with some simple configurations. In this article, we'll walk through the steps required to configure printf properly.

There are two main methods to set up printf in Keil RVMDK:

First Method: Configure Project Properties

1. Include the "stdio.h" header file in your main file. This is necessary for using standard input/output functions like printf.

2. Redefine the "fputc" function in your main file as shown below:


// Send data
int fputc(int ch, FILE *f)
{
    USART_SendData(USART1, (unsigned char)ch); // Replace USART1 with your desired USART port
    while (!(USART1->SR & USART_FLAG_TXE));
    return (ch);
}

// Receive data
int GetKey(void)
{
    while (!(USART1->SR & USART_FLAG_RXNE));
    return ((int)(USART1->DR & 0x1FF));
}

This custom implementation of fputc will be called whenever you use printf, allowing you to send characters over the serial port.

3. Make sure to check the "Use MicroLIB" option under "Target" > "Code Generation" in the project properties. MicroLIB is a lightweight C library that provides support for standard I/O functions and is essential for proper printf functionality.

Second Method: Add the "Regtarge.c" File

1. Include "stdio.h" in your main file as well.

2. Create a new file named "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 an external function defined in your main file
extern int GetKey(void);

struct __FILE {
    int handle; // You can add any additional fields 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
}

3. In your main file, define the following two functions:


int SendChar(int ch) {
    while (!(USART1->SR & USART_FLAG_TXE)); // Replace USART1 with your desired serial port
    USART1->DR = (ch & 0x1FF);
    return (ch);
}

int GetKey(void) {
    while (!(USART1->SR & USART_FLAG_RXNE));
    return ((int)(USART1->DR & 0x1FF));
}

Once these configurations are complete, you can freely use the printf function in your STM32 application. This setup ensures that all output from printf is sent via the serial port, making debugging and data transmission much more efficient. Whether you're working on a simple project or a complex embedded system, having a working printf setup is essential for real-time monitoring and troubleshooting.

5*7 Dot Matrix LED Display

Wuxi Ark Technology Electronic Co.,Ltd. , https://www.arkledcn.com