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
:指向第二个字符串的指针。
返回值:
-
如果
s1
和s2
相等,则返回 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
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)