STM32 UART串口printf函数应用及浮点打印代码空间节省 (HAL)

STM32 UART串口printf函数应用及浮点打印代码空间节省 (HAL)

在应用STM32的UART接口打印输出串口字符信息时,可以通过printf函数的重载和应用实现。但要打印输出浮点数据时,采用常规方式,对于Flash空间小的MCU,常常出现代码空间不够的报错,这里设计了替代的函数实现浮点转字符,从而解决空间不够报错的问题。

STM32 printf()函数重载

要使用printf函数通过串口输出字符打印,在工程里引入两个文件即可:

usart.h:

#ifndef _USART_H
#define _USART_H

#include "stm32g0xx_hal.h"
#include "stdio.h"	 	  	


int fputc(int ch, FILE *f) ;

#endif

注意这一行,根据实际所用的芯片进行调整:

#include "stm32g0xx_hal.h"

usart.c:

#include "usart.h"   


extern UART_HandleTypeDef huart2;   //声明串口

/* USER CODE BEGIN 1 */
#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
  HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}
/* USER CODE END 1 */

注意这两行,根据实际所用的串口号进行调整(这里用的是huart2):

extern UART_HandleTypeDef huart2;   //声明串口
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);

然后再主文件main.c里引入:

#include "usart.h"

就可以在需要的地方通过printf()函数进行打印输出,如:

printf("Do you have problem with float print?\r\n");

有一个顺序需要注意,必须在STM32CUBE配置UART后,进行一次编译后,再引入usart.h和usart.c文件,再编译运行,则printf输出功能正常。如果在STM32CUBE配置UART后,没有进行初次编译就直接引入usart.h和usart.c,然后编译,printf功能运行会出现异常不会输出。

STM32 printf浮点打印常规方式

要想进行浮点打印输出,如:

printf("Float Data: %f \r\n", 100.001);

编译则会告警,是因为没有把支持选项打开:
STM32 UART串口printf函数应用及浮点打印代码空间节省 (HAL)_第1张图片

在STM32CUBEIDE工具里,在此处选择printf支持浮点转换打印:
STM32 UART串口printf函数应用及浮点打印代码空间节省 (HAL)_第2张图片
STM32 UART串口printf函数应用及浮点打印代码空间节省 (HAL)_第3张图片

采用这种方式(snprintf()库函数也必须开启这种方式才能使用),引入的代码比较大,编译占用空间比较多,对于STM32F0, STM32L0, STM32G0等MCU, 容易超过FLASH空间导致不能用。

通过单独编写浮点转字符串的函数,则可以解决问题,占用的FLASH空间小很多。

STM32 printf浮点转字符串函数设计

设计的printf浮点转字符串函数如下:

/*
*Convert float to string type
*Written by Pegasus Yu in 2022
*stra: string address as mychar from char mychar[];
*float: float input like 12.345
*flen: fraction length as 3 for 12.345
*/
#include 
#include 
#include 
#include 
void py_f2s4printf(char * stra, float x, uint8_t flen)
{
	uint32_t base;
	int64_t dn;
	char mc[32];

	base = pow(10,flen);
	dn = x*base;
	sprintf(stra, "%d.", (int)(dn/base));
	dn = abs(dn);
	if(dn%base==0)
	{
		for(uint8_t j=1;j<=flen;j++)
		{
			stra = strcat(stra, "0");
		}
		return;
	}
	else
	{
		if(flen==1){
			sprintf(mc, "%d", (int)(dn%base));
			stra = strcat(stra, mc);
			return;
		}

		for(uint8_t j=1;j<flen;j++)
		{
			if((dn%base)<pow(10,j))
			{
				for(uint8_t k=1;k<=(flen-j);k++)
				{
					stra = strcat(stra, "0");
				}
				sprintf(mc, "%d", (int)(dn%base));
				stra = strcat(stra, mc);
				return;
			}
		}
		sprintf(mc, "%d", (int)(dn%base));
		stra = strcat(stra, mc);
		return;
	}
}

STM32 printf浮点转字符串函数应用及效果

采用如下的代码进行测试:

      char mychar[100];

	  py_f2s4printf(mychar, 0.000, 3);
	  printf("\r\n x: %s\r\n", mychar);

	  py_f2s4printf(mychar, 1.000, 3);
	  printf("\r\n x: %s\r\n", mychar);

	  py_f2s4printf(mychar, -1.000, 3);
	  printf("\r\n x: %s\r\n", mychar);

	  py_f2s4printf(mychar, -1.023, 3);
	  printf("\r\n x: %s\r\n", mychar);

	  py_f2s4printf(mychar, 1.023, 3);
	  printf("\r\n x: %s\r\n", mychar);

	  py_f2s4printf(mychar, -1.123, 3);
	  printf("\r\n x: %s\r\n", mychar);

串口打印输出效果:
STM32 UART串口printf函数应用及浮点打印代码空间节省 (HAL)_第4张图片

注意事项

如果采用单独的py_f2s4printf()函数后,编译空间仍然超过了Flash的空间,则需要摒弃printf()函数的使用,直接使用HAL函数调用方式替代printf()方式,如将

	  py_f2s4printf(mychar, -1.123, 3);
	  printf("\r\n x: %s\r\n", mychar);

改为:

     py_f2s4printf(mychar, -1.123, 3);
     HAL_UART_Transmit(&huart2, "  \r\n x: ", strlen("  \r\n x: "), 0xFFFF);
     HAL_UART_Transmit(&huart2, mychar, strlen(mychar), 0xFFFF);
     HAL_UART_Transmit(&huart2, "\r\n", strlen("\r\n"), 0xFFFF);

虽然处理繁杂一点(也可以用 strcat()函数先连接整个字符串,串口则只发送一次),但却可以进一步缩减编译后所占空间的大小。

–End–

你可能感兴趣的:(STM32,stm32,uart,printf,float,print,浮点打印)