历史上的今天
今天是:2025年01月20日(星期一)
2020年01月20日 | STM32高级开发(12)-在GCC中使用printf打印串口数据
2020-01-20 来源:eefocus
在大家使用keil或是iar开发stm32等arm芯片的时候,想来最不陌生的就是使用print通过串口输出一些数据,用来调试或是其他作用。但是要明确的是由于keil iar gcc 他们使用的标准C语言库虽然都遵循一个标准,但他们底层的函数实现方式都是不同的,那么在GCC中我们能否像在keil中一样重映射print的输出流到串口上呢?答案是肯定的。
keil中的重映射方式及原理
/*
* libc_printf.c
*
* Created on: Dec 26, 2015
* Author: Yang
*
* 使用标准C库时,重映射printf等输出函数的文件
* 添加在工程内即可生效(切勿选择semihost功能)
*/
#include //include "stm32f10x.h" #pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE { int handle; }; FILE __stdout; //定义_sys_exit()以避免使用半主机模式 _sys_exit(int x) { x = x; } //重映射fputc函数,此函数为多个输出函数的基础函数 int fputc(int ch, FILE *f) { while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); USART_SendData(USART1, (uint8_t) ch); return ch; } 在keil中的C库中,printf、scanf等输入输出流函数是通过fputc、fgetc来实现最底层操作的,所以我们只需要在我们的工程中重定义这两个函数的功能就可以实现printf、scanf等流函数的重映射。 GNU下的C流函数重映射方式 我们来看看前几篇中提供的样例工程中的usart_stdio例程中的代码片段: #include #include #include /* * To implement the STDIO functions you need to create * the _read and _write functions and hook them to the * USART you are using. This example also has a buffered * read function for basic line editing. */ int _write(int fd, char *ptr, int len); int _read(int fd, char *ptr, int len); void get_buffered_line(void); /* * This is a pretty classic ring buffer for characters */ #define BUFLEN 127 static uint16_t start_ndx; static uint16_t end_ndx; static char buf[BUFLEN + 1]; #define buf_len ((end_ndx - start_ndx) % BUFLEN) static inline int inc_ndx(int n) { return ((n + 1) % BUFLEN); } static inline int dec_ndx(int n) { return (((n + BUFLEN) - 1) % BUFLEN); } /* back up the cursor one space */ static inline void back_up(void) { end_ndx = dec_ndx(end_ndx); usart_send_blocking(USART1, '




