【Renesas FPB_RA6E2】Review——UART using printf
[Copy link]
UART uses printf function
As a common communication peripheral, the serial port is often used for communication debugging between MCU and host computer and controlling external modules. RA6E2 provides two SCI interfaces for UART communication.
By looking at the schematic, we can see that P109/P110 (UART9) is connected through the debugger's CDC port.
UART driver functions
The driver function of SCI UART mode is given in the FSP user manual.
Printf function redirection to UART
First, in FSP Configurator, click Stack->New Stack->Connectivity->UART(r_sci_uart) to add a serial port module.
The parameters of the serial port module are as follows:
Save the configuration file and generate the corresponding code.
To use the printf function, you need to set the stack size because the printf function needs to use stack space to store temporary variables and function call information during runtime. If the stack size is insufficient, it may cause a program crash or unexpected behavior. The printf function uses a variable parameter list. It uses the stack to store parameters when it is called and clears the parameters at the end of the function call, which requires sufficient stack space. In addition, printf also uses some temporary variables. If the stack space is insufficient, the program will crash. Therefore, in order to avoid such problems, the stack size should be set appropriately according to the needs of the program. Modify the heap size in BSP->RA Common Heap size in FSP Configurator.
When using printf to print in e2studio, if the --specs=rdimon.specs parameter is used in the linker script file, the compiler will use the system call function in the rdimon.specs file to implement the printf function. In this case, the output of the printf function will be redirected to a fixed address (usually a section of address in RAM) instead of being directly output to the console or serial port. In this way, a driver needs to be implemented in the program to read these outputs and output them to the console or serial port. If you want the output of the printf function to be directly output to the console or serial port, you need to delete the --specs=rdimon.specs parameter. In this way, the compiler will use the standard printf function implementation, and the output will be directly output to the console or serial port. In the menu bar, Project->Properties, C++ Build->Setting->Tool Settings->GNU ARM Cross C Linker->Miscellaneous, remove "--specs=rdimon.specs" in Other linker flags
Import the header file <stdio.h> into the source code and redefine the __io_putchar function and the _write function. The specific code is as follows.
#include <stdio.h>
#ifdef __GNUC__ //串口重定向
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
err = R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);
if(FSP_SUCCESS != err) __BKPT();
while(uart_send_complete_flag == false){}
uart_send_complete_flag = false;
return ch;
}
int _write(int fd,char *pBuffer,int size)
{
for(int i=0;i<size;i++)
{
__io_putchar(*pBuffer++);
}
return size;
}
The serial port sends data in an interrupt mode. The specific code is as follows:
volatile bool uart_send_complete_flag = false;
void user_uart9_callback (uart_callback_args_t * p_args)
{
if(p_args->event == UART_EVENT_TX_COMPLETE)
{
uart_send_complete_flag = true;
}
}
Combined with the previous PWM wave output project, call printf in the main loop to send data.
printf("The PWM duty count is %d.\r\n",duty_count);
The actual wiring is shown in the figure. Since the Jlink virtual serial port cannot communicate, the P109 and P110 pins are used here to communicate with the host computer through the serial port assistant.
The effect is shown in the figure.
Summarize
When using Jlink's virtual serial port to send data, the host computer cannot get the data. I'm not sure why. Does anyone know what's going on?
|