hello,小伙伴们,大家好。这里是左左右。在前面的视频中我们会频繁使用printf这个函数。它对我们调试和验证代码起到至关重要的作用。那么,在stm32中结合学习板和串口屏也是可以实现这样的功能的。
首先,我们打开串口屏软件。点击新建。这里随便起个名字就叫调试输出吧。接着,选择串口屏型号。导入我们之前创建好的字库。接着,导入两张图片,一张是清晰的,一张是模糊的。这是我用PS做的两张图,我将它们放到了我们的免费资料包中。对PS感兴趣的小伙伴们也可以自己去做。之后我们将主界面改为这张清晰的图片。
接下来我们创建一个按钮。和图标大小相同。点击新建好的按钮。在按钮的属性栏中将按钮上的文字删掉,在这里选择切图,分别在picc和picc2中放入清晰和模糊的图片。这样能达到一个什么样的效果呢?当按钮被按下时,按钮这一部分就会切换成模糊的图片。待会在调试过程中我们再来看实际的效果。
接着,点击这里的加号来新增一个页面。放入一个文本控件和两个按钮控件。其中一个按钮控件来实现清空数据的功能。另一个按钮控件来实现返回的功能。接着,我们将文本控件放大一些。这个文本控件就是用来显示我们调试输出内容的。在返回按钮的弹起事件中让它跳回page0,同理在调试这个图标按钮的弹起事件中让它跳转到page1。
随后在清空数据按钮的弹起事件中让它实现清空文本t0中的数据,也就是让t0中的内容为空,所以这里输入t0.txt等于空。这里有两点需要注意。等号两边不能有空格,末尾不能有分号。点击编译。这里0错误和0警告,说明我们前面的操作没有任何问题的。接着,点击调试。这里按下调试按钮,调试图标就变模糊了。

同时,在放开按钮的瞬间跳转到了page1。点击清空数据,文本框中的数据就被清空了。点击返回就回到了主界面。好的,我们结束调试对文本控件t0做一些优化。我们把文本位置改到左上方,把默认的显示内容清空,把文本最大显示数量改为1000,让它能够显示足够多的数据。串口屏制作就暂时到这里了。
接着,打开stm32cubeide。新建一个工程并命名。接下来。第一步SYS这里设置成这样。第二步设置生成单独的.c和.h文件。第三步这里要选择GB2312。第四步设置USART1这里为异步模式。波特率设置为9600。USART2也是同样的方法来设置。这些前面视频都讲过的,带大家再熟悉一下。
点击保存代码就自动生成了。接着,引用这两个常用的头文件。同时,给huart1起个别名。学过前面视频的小伙伴们都知道。在vscode这个软件中使用printf这个函数时。打印输出的结果会显示在输出窗口。我们现在想要实现的功能是打印输出的结果显示到串口屏,也就是需要实现printf这个函数的重定向。

这时我们就要重写_write这个函数。这个函数写法是固定的,在这里 调用熟悉的hal_uart_tramsmit这个函数,从而实现将printf中的内容输出到串口屏。也就实现了printf这个函数的重定向。接着,调用setvbuf这个函数。来设置无缓冲输出。这是因为在嵌入式系统中。
调试结果会先放入缓冲区。当遇到\n才会从缓冲区输出到串口屏。但是,由于串口屏不能识别\n。所以,就通过调用这个函数来实现无缓冲输出。按串口屏手册中写的是可以识别\n的,可能是和串口屏的版本有关系了。这里就不去纠结了。直接调用这个函数就行。接着,我们在while循环中调用printf这个函数。
这里的page1.t0.txt就是向串口屏t0这个文本控件中写入内容。三个xff是串口屏的结束符。这时连接我们的学习板或者最小系统板。点击运行。打开串口屏模拟器。点击用户mcu输入。点击开始。点击调试。这时t0这个控件输出的这就是我们想要的结果。
接下来我们将上期视频在vscode中写好的代码复制到cubeide中。接着,我们把之前printf中的内容复制到刚才写好的printf函数中。我们来看这里报错了。这是因为cudeide默认情况下printf是不能输出浮点数的。根据这里的报错提示来设置一下。接着,在这里加一个1秒的延时。
点击运行,打开串口屏模拟器。输出结果是不是和上期视频一模一样?这里的print是不是使用起来还是没有我们之前那么顺手?所以,我把它封装一个新的printf函数,就把他命名为my_printf。这个新封装的函数当做一个工具来用。不是我们学习的重点,不用关心具体的实现过程。
如果对c语言特别感兴趣的小伙伴们可以自行研究一下。我在里面我做了详细的注释。同时,引入这样一个头文件。最后,我们在while循环中调用封装好的输出函数。点击运行,打开串口屏模拟器。输出的结果是不是也没有问题?通过这期视频的学习。在以后的stm32的学习过程中,我们也可以随心所欲的调用my_printf这个函数。
来调试和验证我们写好的程序了。好的,今天的视频就到这里了。您的关注,点赞和收藏是我持续更新下去的最大动力。我们下期见。
#include<stdarg.h>
void my_printf(const char *format, ...)
{
static char buffer[512];
char temp_buffer[256]; // 用于存放格式化后的字符串
va_list args;
// 固定前缀和后缀
const char prefix[] = "page1.t0.txt+=\"";
const char suffix[] = "\\r\"\xff\xff\xff";
// 格式化用户输入的内容
va_start(args, format);
int len = vsnprintf(temp_buffer, sizeof(temp_buffer), format, args);
va_end(args);
if (len < 0) {
// 格式化错误
return;
}
// 检查总长度是否超出缓冲区
int total_len = strlen(prefix) + len + strlen(suffix);
if (total_len >= sizeof(buffer)) {
// 超出缓冲区,截断处理
len = sizeof(buffer) - strlen(prefix) - strlen(suffix) - 1;
if (len < 0) {
len = 0;
}
temp_buffer[len] = '\0';
}
// 组合字符串
strcpy(buffer, prefix);
strcat(buffer, temp_buffer);
strcat(buffer, suffix);
// 发送
HAL_UART_Transmit(&ss_huart, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
}