IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32 UART串口printf函数应用及浮点打印代码空间节省 (HAL) -> 正文阅读

[嵌入式]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);

编译则会告警,是因为没有把支持选项打开:
在这里插入图片描述

在STM32CUBEIDE工具里,在此处选择printf支持浮点转换打印:
在这里插入图片描述
在这里插入图片描述

采用这种方式(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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
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);

串口打印输出效果:
在这里插入图片描述

注意事项

如果采用单独的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–

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 11:00:44  更:2022-08-06 11:01:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:52:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码