petard  

STM32 常用函数整理、debug调试(printf)

一、常用函数整理

标准库使用的API 用的都是 **char *** 数据类型

函数定义在 <string.h> 头文件中。

1、mem

1.清空缓冲区 memset
  memset((char *)uart2RxBuff, 0, UART2RXBUFF_SIZE);

把uart2RxBuff中长度为UART2RXBUFF_SIZE的字符都写为0

2.拷贝 memcpy —— 复制内存区域的内容
memcpy(数组1, 数组2, len);

把数组2的len长度的数据拷贝到数组1中

数组1与数组2都是指针

eg:

memcpy(&uart2ResponseBuff[uart2ResponseLen], uart2RxBuff, uart2RxLen);

把uart2RxBuff中该长度uart2RxLen的数据,拷贝到uart2ResponseBuff中(从uart2ResponseBuff中的第uart2ResponseLen开始拷贝

2、str

1.查找(strstr、strrchr) —— 返回指针类型数据
strstr((char *)Buff, "+IPD");	//从左向右找字符串
strrchr("abc/def", '/');	//从右向左找字符
2. 比较两个字符串(strcmp)

strcmp 是 C 语言中的一个标准库函数。它返回一个整数值,指示两个字符串之间的关系。

函数原型:

int strcmp(const char *s1, const char *s2);

参数:

  • s1:指向第一个字符串的指针。
  • s2:指向第二个字符串的指针。

返回值:

  • 如果 s1s2 相等,则返回 0。

  • 如果 s1 小于 s2,则返回负数。

  • 如果 s1 大于 s2,则返回正数。

3.切割字符串(strtok)
strtok((char *)Buff, ":");	//用:切割,第一次切割得到Buff数组中:前的数据指针
strtok(NULL, ":");	//第二次切割得到:后的数据指针
4. 将一个字符串复制到另一个字符串中 (strcpy)

函数原型:

char *strcpy(char *dest, const char *src);

参数:

  • dest:指向目标字符串的指针。目标字符串必须有足够的空间来存储源字符串。
  • src:指向源字符串的指针。

返回值:

  • strcpy 函数返回指向目标字符串的指针。

3、printf 、scanf 等衍生

1.printf

(1)

printf("%.*s", Len, uart2RxBuff);

从 uart2RxBuff 中 打印Len长度的数据

(2)%20s:输出宽度为20的字符串,高位用0补;
%4d:输出宽度为4的整型,高位用空格补齐

sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",	//%04d:宽度为4,高位用0补
		datetime.year,
		datetime.mon,
		datetime.day,
		datetime.hour,
		datetime.min,
		datetime.sec
		);

(3)`"%#x"输出前面带0x的十六进制数

​ "%#X" 输出前面带0X的十六进制数

printf函数输出一个以0x开头的十六进制数,使用"%#x"或者"%#X"格式化字符串。

%#x会输出小写字母的十六进制数,而%#X输出大写字母的十六进制数。

2. sprintf // 将格式化数据写入字符串
sprintf(cmd, "AT+CIPSEND=%d\r\n", dataLen);

把整合的数据(AT+CIPSEND=dataLen)给放到cmd中

3. sscanf

%*:后边加什么就表示跳过什么

​ eg:%*7c-跳过7个字符,%*f-跳过float

%.*s-打印对应数据长度的字符串

如果没有找到,strstr会返回NULL

uart2RxBuff:	+IPD,3,"192.168.43.197",9999:abc
sscanf((char *)uart2RxBuff,
                "%*[\r\n]+IPD,%d,\"%[^\"]\",%d",
                dataLen,
                dip,
                port);

拆分读取数组:(1)%*[\r\n] - 跳过多个\r\n (2)% [ ^ \ " ] - 匹配非双排引号

二、debug调试实现 - printf

printf 执行一次很费时间,所以需要在调试结束后,把printf去掉

1.设置一个开关/功能裁剪:打开时有printf 关闭没有

使用宏定义设计

#define DEBUG 1


#if (DEBUG == 1)		//在宏定义中if判断------------------------
#define debug_printf()	printf()	//表示DEBUG为1时,有功能

#else 	
#define debug_printf()	//表示DEBUG为0时,给它替换为空

#endif					//if判断结束-----------------------------
2.设置宏参数
#define debug_printf(format, ...)	printf(format, ##__VA_ARGS__)

format 表示参数格式
... 表示可变参数					通过宏##__VA_ARGS__传递可变参数
3.宏自动加\r\n
#define debug_printfln(format, ...)	printf(format "\r\n", ##__VA_ARGS__)

format "\r\n": 字符串常量连接	—— c语言中 "ab""c"	= "abc"	[只能拼常量]
4.打印出所在的行数

在宏里面定义添加 (自动生成)

//[文件名:行号] -- 具体的日志信息
//把文件名、行号求出来,用可变参数代替
/*
 *__FILE__:可以输入绝对路径加文件名  - 目前只要文件名
 *使用一个字符串进行查找并输出(strrchr)
 */
//行号的宏:__LINE__
#define __FILE_NAME__	((strtchr(__FILE__, '\\') ? (strtchr(__FILE__, '\\')+ 1 : __FILE__)		//找反斜杠的时候需要用 \ 转义下
#define debug_printfln(format, ...)	printf("[ %20s:%4d ] -- "format "\r\n", __FILE_NAME__, __LINE__, ##__VA_ARGS__)

整体实现:

#include "string.h"


#define DEBUG 1

#if (DEBUG == 1)		
#define __FILE_NAME__	((strtchr(__FILE__, '\\') ? (strtchr(__FILE__, '\\')+ 1 : __FILE__)	

//[文件名:行号] -- 具体的日志信息
#define debug_printf(format, ...)	printf("[ %20s:%4d ] -- " format, __FILE_NAME__, __LINE__, ##__VA_ARGS__)
#define debug_printfln(format, ...)	printf("[ %20s:%4d ] -- " format "\r\n", __FILE_NAME__, __LINE__, ##__VA_ARGS__)

#else 	
#define debug_printf(format, ...)	
#define debug_printfln(format, ...)

#endif	
posted on   岌岌无名  阅读(529)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
 
点击右上角即可分享
微信分享提示