基于RT-Thread和兆易创新GD32F527系列MCU的健康监测站 | 技术集结

本项目为RT-Thread嵌入式大赛获奖作品,基于RT-Thread和兆易创新GD32F527I-EVAL的健康监测站。

目录

项目概述

系统硬件框架结构

基础驱动程序实现

整体驱动实现

工程效果

演示视频及代码

演示视频链接:https://www.bilibili.com/video/BV1WgUoBXE2n/?pop_share=1&vd_source=e1bd226340c8b87027d5dcfc6b0c3344

1 项目概述

1.1 项目背景

血氧、心率监测是人们最常关心的,特别是一些特殊的群体比如老人,患有心血管系统、呼吸系统疾病的人。能方便及时的监测到心率与血氧。本项目主要利用了开发板的大内存、大屏幕,移植LVGL,能够让老年人也看得清楚。

1.2 系统功能介绍

基于GD32F527I-EVAL开发板实现如下功能:

  • 使用管方的RTTherad库,管理整个系统资源。

  • 移植LCD驱动,给LVGL提供显示基础

  • 移植触摸驱动,给LVGL提供用户输入基础

  • 移植USART5,实现与传感器的交互接口。

  • 移植LVGL,设计GUI界面

  • 实现传感器驱动,实现血氧、心率的监测。

1.3 系统使用的技术要点

  • 整个系统由国产开源操作系统RT-Thead实现驱动的模块化设计,以及系统调度。

  • 硬件:GD32F527I-EVAL

  • 开发板语言:C、GuiGuider

2 系统硬件框架结构

2.1 TFT—LCD接口

开发板板载了LCD屏,其原理图如下:

2.2 SDRAM接口

由于开发板上外扩了RAM,给LVGL驱动提供了大内存空间,原理图如下:

2.3 USART5接口

由于开发板的外设非常多,找到摄像头接口的PC6、PC7作为USART5的接口:

3 基础驱动程序实现

3.1 基础工程

3.1.1 下载RT-Thread源码

https://gitee.com/rtthread/rt-thread

下载源码到本地。

3.1.2 同步并打包

  1. 下载好源码后,进入rt-thread/tree/master/bsp/gd32/arm/gd32527I-eval目录下面执行pkgs —upgrade-force同步

  2. 然后进行pkgs —update

  3. 执行scons —target=mdk5

  4. 然后进行scons —dist打包单独的工程。

  5. 复制打包好的工程到单独的目录下。

现在单独的工程就创建好了。

3.2 移植LVGL

创建好工程后,首先就需要生成用户交互界面。我在论坛有单独的作品:

https://club.rt-thread.org/ask/article/a2dba0eaa063757a.html

3.3 移植触摸驱动

LVGL需要驱动触摸屏,我也有单独的作品:

https://club.rt-thread.org/ask/article/104ea5e6b33e788e.html

3.4 移植mks传感器串口接口

详见单独作品:

https://club.rt-thread.org/ask/article/1074357ba9757cdb.html

4 整体驱动实现

通过上的基工程的实现,接下来就是整合驱动,实整个工程。

4.1 界面设计

4.1.1 GuiGuide设计

我使用开源的GuiGuider设了用户交互界面:

控件1:btn_start,实现开始、停止测量的复用功能

控件2:label_heart 用于显示测量到的心率值

控件3:label_spo2 用于显示测量到的心率值

控件4:bar 用于显示测量的进度条

其余控件为固定标签。

4.1.2 事件添加

为btn_start 添加clicked事件

最后生成C语言的工程。

4.2 LVGL工程移植

4.2.1 复制guiguider工程

在生成工程的目录中,我复制generated文件夹到基础工程下的LVGL目录下面,替换掉原来的generated文件夹。

4.2.2 添加文件到工程

在mdk中,将generated下面的所有.c/h添加到mdk工程中:

4.2.3 添加bnt事件代码

根据传感器的手册,我们开始测量时,是向串口发送数据0x8A,停止是向串口发送0x88。

添加按键的的驱动代码如下:

extern lv_ui guider_ui;externintmks_cmd(int argc, char *argv[]);// 全局/静态变量:控制进度条和定时器(确保回调中可访问)staticlv_timer_t *progress_timer = NULL; // 进度条定时器staticint current_progress = 0; // 当前进度值(0-100)// 进度条定时器回调函数(每隔 200ms 触发一次)staticvoidprogress_timer_cb(lv_timer_t *timer){ current_progress++; // 每次进度 +1%(200ms × 100 = 20 秒) // 更新进度条值(关闭动画,避免和定时器冲突) lv_bar_set_value(guider_ui.screen_bar, current_progress, LV_ANIM_OFF); // 进度达到 100%,停止定时器并重置状态 if (current_progress >= 100) { lv_timer_del(progress_timer); // 删除定时器(释放资源) progress_timer = NULL; // 重置定时器指针 current_progress = 0; // 重置进度值 char *argv[] = {"mks_cmd", "stop", NULL}; int argc = 2; mks_cmd(argc, argv); // 可选:进度完成后,自动将按钮切回「开始」 lv_label_set_text(guider_ui.screen_btn_start_label, "Start"); lv_bar_set_value(guider_ui.screen_bar, 0, LV_ANIM_OFF); }}staticvoidscreen_btn_start_event_handler(lv_event_t *e){ lv_event_code_t code = lv_event_get_code(e); switch (code) { case LV_EVENT_CLICKED: { constchar *btn_text = lv_label_get_text(guider_ui.screen_btn_start_label);; if (btn_text != NULL && strcmp(btn_text, "Start") == 0) { rt_kprintf("start test\n"); // 停止已存在的定时器(避免重复启动,防止进度加速) if (progress_timer != NULL) { lv_timer_del(progress_timer); progress_timer = NULL; } // 初始化进度状态 current_progress = 0; lv_bar_set_range(guider_ui.screen_bar, 0, 100); // 设置进度条范围:0-100(百分比) lv_bar_set_value(guider_ui.screen_bar, 0, LV_ANIM_OFF); // 进度条归零 // 创建并启动定时器:周期 200ms,触发回调函数 progress_timer = lv_timer_create(progress_timer_cb, 200, NULL); lv_timer_resume(progress_timer); // 启动定时器(LVGL 定时器默认创建后启动,保险起见手动调用) // 构造参数并调用 char *argv[] = {"mks_cmd", "start", NULL}; int argc = 2; mks_cmd(argc, argv); lv_label_set_text(guider_ui.screen_btn_start_label, "Stop"); } elseif (btn_text != NULL && strcmp(btn_text, "Stop") == 0) { // 停止并删除定时器 if (progress_timer != NULL) { lv_timer_del(progress_timer); progress_timer = NULL; } // 进度条归零,状态重置 current_progress = 0; lv_bar_set_value(guider_ui.screen_bar, 0, LV_ANIM_OFF); char *argv[] = {"mks_cmd", "stop", NULL}; int argc = 2; mks_cmd(argc, argv); lv_label_set_text(guider_ui.screen_btn_start_label, "Start"); lv_obj_center(guider_ui.screen_btn_start_label); } break; } default: break; }}

4.2.4 添加初始化gui代码

在main.c中添加用于lvgl 心跳包的任务,与初始化lvgl的代码:

#define LED1_PIN GET_PIN(E, 3)#define LVGL_TASK_PERIOD 10 // ms#define LVGL_TICK_PERIOD 5 // mslv_ui guider_ui; staticrt_thread_t lvgl_task_thread = RT_NULL;staticrt_thread_t lvgl_tick_thread = RT_NULL;staticvoidlvgl_tick_thread_entry(void *parameter){ while (1) { lv_tick_inc(5); rt_thread_delay(5); }}staticvoidlvgl_task_thread_entry(void *parameter){ lv_init(); lcd_init(); lv_port_disp_init(); lv_port_indev_init(); setup_ui(&guider_ui); setup_ui(&guider_ui); events_init(&guider_ui); while (1) { lv_task_handler(); rt_thread_delay(10); }}intmain(void){ /* set LED1 pin mode to output */ rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT); exmc_synchronous_dynamic_ram_init(EXMC_SDRAM_DEVICE0); //在这里启用两个任务 lvgl_task_thread = rt_thread_create("lvgl_task", lvgl_task_thread_entry, RT_NULL, 4096, 25, 10); if (lvgl_task_thread != RT_NULL) rt_thread_startup(lvgl_task_thread); lvgl_tick_thread = rt_thread_create("lvgl_tick", lvgl_tick_thread_entry, RT_NULL, 512, 25, 10); if (lvgl_tick_thread != RT_NULL) rt_thread_startup(lvgl_tick_thread); while (1) { rt_thread_mdelay(1000); // 主线程可以做其他事情 } return RT_EOK;}

将程序下载到开发板后,按下按键,能在USART5上面看到的0x8A、0x88输出,说明程序运转正常。

4.3 mks传感器驱动

4.3.1 mks传感器通信协议:

根据通信协议进行串口的代码实现。

4.3.2 mks串口添加:

在menuconfig中,打开usart5,保存工程并重新生成工程。

4.3.3 mks串口驱动实现

  1. 在驱动中,按照rtthead srial的标准驱动。

  2. 由于mkd传感器的波特率为38400,因此需要在初始化后,重新配置serial的驱动结构体,并进行配置。

  3. 定义他为uart5 实现中断接收功能,详见驱动代码如下:

接收传感器并实现解码,并实时将接收到的数据通过LVGL显示到界面中。

#include"app.h"#include"string.h"#include<stdio.h>#include<rtthread.h>#include<rtdevice.h>#include"lvgl.h"#include"gui_guider.h"#define MAX_BUFFSIZE 128#define RECEIVE_LENGTH 88 #define PACKET_HEADER 0xFF#define SAMPLE_UART_NAME "uart5"/* 用于接收消息的信号量 */staticstructrt_semaphorerx_sem;staticrt_device_t serial;// --- 全局变量定义 ---int8_t mks_waveform_data[MKS_WAVEFORM_SAMPLES];uint8_t mks_heart_rate = 0;uint8_t mks_spo2 = 0;volatileuint8_t mks_new_data_flag = 0; // Use volatile as it might be checked in timer/ISR context later// --- 内部接收缓冲区 ---staticuint8_t mks_rx_buffer[MKS_PACKET_SIZE];staticuint8_t mks_bytes_received = 0;// lvglextern lv_ui guider_ui; staticchar buf[4];/* 接收数据回调函数 */staticrt_err_tuart_input(rt_device_t dev, rt_size_t size){ /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ rt_sem_release(&rx_sem); return RT_EOK;}/** * 串口接受线程 * @param parameter */staticvoidserial_thread_entry(void *parameter){ char ch; mks_bytes_received = 0; // Reset buffer state mks_new_data_flag = 0; // 初始无新数据 // 初始化数据为0 memset(mks_rx_buffer,0, RECEIVE_LENGTH); mks_heart_rate = 0; mks_spo2 = 0; while (1) { /* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */ while (rt_device_read(serial, -1, &ch, 1) != 1) { /* 阻塞等待接收信号量,等到信号量后再次读取数据 */ rt_sem_take(&rx_sem, RT_WAITING_FOREVER); } if(ch == PACKET_HEADER) { mks_bytes_received = 1; mks_new_data_flag = 0; mks_rx_buffer[0] = (uint8_t)ch; } else { if(mks_bytes_received>0) { //mks_bytes_received++; mks_rx_buffer[mks_bytes_received++] = (uint8_t)ch; if(mks_bytes_received >= RECEIVE_LENGTH) { mks_new_data_flag = 1; mks_bytes_received = 0; sprintf(buf, "%d", mks_rx_buffer[65]); lv_label_set_text(guider_ui.screen_label_heart, buf); //更新到LVGL sprintf(buf, "%d", mks_rx_buffer[66]); lv_label_set_text(guider_ui.screen_label_spo2, buf);//更新到LVGL memset(mks_rx_buffer,0, RECEIVE_LENGTH); mks_new_data_flag = 0; } } } }}staticintuart_sample(int argc, char *argv[]){ rt_err_t ret = RT_EOK; struct serial_configurecfg; // 配置结构体 char uart_name[RT_NAME_MAX]; char str[] = "hello RT-Thread!\r\n"; if (argc == 2) { rt_strncpy(uart_name, argv[1], RT_NAME_MAX); } else { rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX); } /* 查找系统中的串口设备 */ serial = rt_device_find(uart_name); if (!serial) { rt_kprintf("find %s failed!\n", uart_name); return RT_ERROR; } cfg.baud_rate = BAUD_RATE_38400; // 目标波特率(可改为 38400、19200 等) cfg.data_bits = DATA_BITS_8; // 8 数据位 cfg.stop_bits = STOP_BITS_1; // 1 停止位 cfg.parity = PARITY_NONE; // 无校验 cfg.bit_order = BIT_ORDER_LSB; // 低位优先(默认) cfg.invert = NRZ_NORMAL; cfg.bufsz = RT_SERIAL_RB_BUFSZ; cfg.flowcontrol = RT_SERIAL_FLOWCONTROL_NONE; cfg.reserved = 0; rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &cfg); /* 初始化信号量 */ rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); /* 以中断接收及轮询发送模式打开串口设备 */ rt_device_open(serial, RT_DEVICE_FLAG_INT_RX); /* 设置接收回调函数 */ rt_device_set_rx_indicate(serial, uart_input); /* 发送字符串 */ rt_device_write(serial, 0, str, (sizeof(str) - 1)); /* 创建 serial 线程 */ rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10); /* 创建成功则启动线程 */ if (thread != RT_NULL) { rt_thread_startup(thread); } else { ret = RT_ERROR; } return ret;}intmks_cmd(int argc, char *argv[]){ rt_err_t ret = RT_EOK; uint8_t send_data = 0; // 要发送的字节数据 // 第一步:检查串口设备是否已初始化(首次使用时查找并打开) if (serial == RT_NULL) { // 查找串口设备 serial = rt_device_find(SAMPLE_UART_NAME); if (serial == RT_NULL) { rt_kprintf("错误:未找到串口设备 %s!\n", SAMPLE_UART_NAME); return RT_ERROR; } // 打开串口(RT_DEVICE_OFLAG_RDWR:读写模式) if (rt_device_open(serial, RT_DEVICE_OFLAG_RDWR) != RT_EOK) { rt_kprintf("错误:打开串口设备 %s 失败!\n", SAMPLE_UART_NAME); serial = RT_NULL; // 打开失败,重置句柄 return RT_ERROR; } } // 第二步:解析命令参数 if (argc == 2) // 仅支持 "mks start" 或 "mks stop"(2个参数) { // 比较第二个参数(argv[1]) if (strcmp(argv[1], "start") == 0) { send_data = 0x8A; // start 对应发送 0x8A rt_kprintf("执行 mks start,发送数据:0x%02X\n", send_data); } elseif (strcmp(argv[1], "stop") == 0) { send_data = 0x88; // stop 对应发送 0x88 rt_kprintf("执行 mks stop,发送数据:0x%02X\n", send_data); } else { // 无效参数:提示正确用法 rt_kprintf("错误:无效命令参数!\n"); rt_kprintf("正确用法:\n"); rt_kprintf(" mks start - 发送 0x8A\n"); rt_kprintf(" mks stop - 发送 0x88\n"); return -RT_EINVAL; } // 第三步:通过串口发送数据(发送1个字节) ret = rt_device_write(serial, 0, &send_data, 1); if (ret != 1) // rt_device_write 返回实际发送的字节数,成功应为 1 { rt_kprintf("错误:串口发送失败!返回值:%d\n", ret); return -RT_ERROR; } } else { // 参数个数错误:提示正确用法 rt_kprintf("错误:命令格式错误!\n"); rt_kprintf("正确用法:\n"); rt_kprintf(" mks start - 发送 0x8A\n"); rt_kprintf(" mks stop - 发送 0x88\n"); return -RT_EINVAL; } return ret;}// 3. 导出命令到 FinSH 终端(支持在终端直接输入 mks 命令)MSH_CMD_EXPORT(mks_cmd, mks command: mks start/stop);/* 导出到 msh 命令列表中 */MSH_CMD_EXPORT(uart_sample, uart device sample);

接收传感器并实现解码,并实时将接收到的数据通过LVGL显示到界面中。

5 工程效果

6 演示视频及代码

演示视频链接:https://www.bilibili.com/video/BV1WgUoBXE2n/?pop_share=1&vd_source=e1bd226340c8b87027d5dcfc6b0c3344

源代码:https://club.rt-thread.org/file_download/a6fe3781d8bcf12d

非常感谢RTT论坛,通过这次参赛让我进一步的体会到了RT-Thread开源操作系统的强大。

RT-Thread Github 开源仓库,欢迎撒个星(Star)支持,更期待你的代码贡献: https://github.com/RT-Thread/rt-thread

添加小师弟微信↓,拉你进RT-Thread技术交流群,找到组织!

想要在RT-Thread平台或社区投放内容?

或想参与相关直播活动及赛事?

RT-Thread已开放对接窗口,

请通过邮件与我们取得联系,期待合作!

合作邮箱: tongfangyi@rt-thread.com

点击“阅读原文”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1193114.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows字体终极优化指南:用MacType轻松实现完美文字渲染

Windows字体终极优化指南&#xff1a;用MacType轻松实现完美文字渲染 【免费下载链接】mactype Better font rendering for Windows. 项目地址: https://gitcode.com/gh_mirrors/ma/mactype 还在为Windows系统下文字显示效果不佳而困扰吗&#xff1f;MacType作为一款开源…

手把手教你部署Z-Image-Turbo,5分钟搞定AI绘图环境

手把手教你部署Z-Image-Turbo&#xff0c;5分钟搞定AI绘图环境 你是否还在为AI绘画模型动辄几十GB的下载、复杂的依赖配置和漫长的环境调试而头疼&#xff1f;现在&#xff0c;这一切都可以被彻底终结。本文将带你用不到5分钟的时间&#xff0c;在云端一键部署 Z-Image-Turbo …

ReTerraForged模组终极指南:5个技巧让Minecraft世界瞬间惊艳

ReTerraForged模组终极指南&#xff1a;5个技巧让Minecraft世界瞬间惊艳 【免费下载链接】ReTerraForged a 1.19 port of https://github.com/TerraForged/TerraForged 项目地址: https://gitcode.com/gh_mirrors/re/ReTerraForged 还在为Minecraft千篇一律的地形感到乏…

Sunshine游戏串流平台部署实战:5步构建高效远程游戏系统

Sunshine游戏串流平台部署实战&#xff1a;5步构建高效远程游戏系统 【免费下载链接】Sunshine Sunshine: Sunshine是一个自托管的游戏流媒体服务器&#xff0c;支持通过Moonlight在各种设备上进行低延迟的游戏串流。 项目地址: https://gitcode.com/GitHub_Trending/su/Suns…

Windows防休眠神器:彻底告别自动关机的终极指南

Windows防休眠神器&#xff1a;彻底告别自动关机的终极指南 【免费下载链接】NoSleep Lightweight Windows utility to prevent screen locking 项目地址: https://gitcode.com/gh_mirrors/nos/NoSleep 你是否曾经在重要会议演示时遭遇屏幕突然变暗的尴尬&#xff1f;或…

Paraformer-large SSH隧道映射:本地访问远程界面教程

Paraformer-large SSH隧道映射&#xff1a;本地访问远程界面教程 1. 章节概述与学习目标 你是否正在使用一个搭载了Paraformer-large语音识别模型的远程服务器&#xff0c;却苦于无法直接访问其Web界面&#xff1f;本文将手把手教你如何通过SSH隧道映射&#xff0c;把远程运行…

PyTorch通用镜像电商应用:推荐系统训练环境快速部署

PyTorch通用镜像电商应用&#xff1a;推荐系统训练环境快速部署 1. 引言&#xff1a;为什么电商推荐系统需要专用训练环境&#xff1f; 你有没有遇到过这种情况&#xff1a;刚接手一个电商推荐项目&#xff0c;第一件事不是设计模型&#xff0c;而是花一整天时间配环境&#…

Steam成就管理工具:游戏开发者的高效开发伴侣

Steam成就管理工具&#xff1a;游戏开发者的高效开发伴侣 【免费下载链接】SteamAchievementManager A manager for game achievements in Steam. 项目地址: https://gitcode.com/gh_mirrors/st/SteamAchievementManager 在当今游戏开发领域&#xff0c;成就系统已成为提…

Zotero插件Style终极配置完整指南:高效文献管理技巧

Zotero插件Style终极配置完整指南&#xff1a;高效文献管理技巧 【免费下载链接】zotero-style zotero-style - 一个 Zotero 插件&#xff0c;提供了一系列功能来增强 Zotero 的用户体验&#xff0c;如阅读进度可视化和标签管理&#xff0c;适合研究人员和学者。 项目地址: h…

AI配音新突破:IndexTTS 2.0支持音色与情感分离控制

AI配音新突破&#xff1a;IndexTTS 2.0支持音色与情感分离控制 你有没有遇到过这样的情况&#xff1f;想给一段短视频配上主角的声音&#xff0c;却发现AI生成的语音虽然清晰&#xff0c;但语气平淡、节奏不准&#xff0c;完全对不上画面情绪。更麻烦的是&#xff0c;如果要换…

3大秘诀让你的iPhone界面焕然一新:个性化定制完全指南

3大秘诀让你的iPhone界面焕然一新&#xff1a;个性化定制完全指南 【免费下载链接】CowabungaLite iOS 15 Customization Toolbox 项目地址: https://gitcode.com/gh_mirrors/co/CowabungaLite 厌倦了千篇一律的iPhone界面&#xff1f;想让你的设备真正与众不同吗&#…

Gofile下载工具深度解析:你的专属云端资源管家

Gofile下载工具深度解析&#xff1a;你的专属云端资源管家 【免费下载链接】gofile-downloader Download files from https://gofile.io 项目地址: https://gitcode.com/gh_mirrors/go/gofile-downloader 还在为Gofile.io的资源下载而烦恼吗&#xff1f;无论是单个大文件…

Google Drive受保护PDF文档下载解决方案:高效突破技术限制

Google Drive受保护PDF文档下载解决方案&#xff1a;高效突破技术限制 【免费下载链接】Google-Drive-PDF-Downloader 项目地址: https://gitcode.com/gh_mirrors/go/Google-Drive-PDF-Downloader 在日常工作和学习中&#xff0c;我们经常遇到Google Drive上设置为&quo…

Google Drive受保护PDF下载完整解决方案:2025年免费高效工具使用指南

Google Drive受保护PDF下载完整解决方案&#xff1a;2025年免费高效工具使用指南 【免费下载链接】Google-Drive-PDF-Downloader 项目地址: https://gitcode.com/gh_mirrors/go/Google-Drive-PDF-Downloader 三个真实用户故事&#xff1a;为什么需要这个工具&#xff1…

魔兽争霸III性能提升秘籍:7大技巧让你的游戏体验焕然一新

魔兽争霸III性能提升秘籍&#xff1a;7大技巧让你的游戏体验焕然一新 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为魔兽争霸III在现代电脑上的…

nomic-embed-text-v1.5极限压缩实战:低资源环境部署性能翻倍指南

nomic-embed-text-v1.5极限压缩实战&#xff1a;低资源环境部署性能翻倍指南 【免费下载链接】nomic-embed-text-v1.5 项目地址: https://ai.gitcode.com/hf_mirrors/nomic-ai/nomic-embed-text-v1.5 当我们在边缘设备上尝试部署nomic-embed-text-v1.5时&#xff0c;面…

3步快速掌握深蓝词库转换:告别输入法迁移烦恼

3步快速掌握深蓝词库转换&#xff1a;告别输入法迁移烦恼 【免费下载链接】imewlconverter ”深蓝词库转换“ 一款开源免费的输入法词库转换程序 项目地址: https://gitcode.com/gh_mirrors/im/imewlconverter 还在为更换输入法时词库无法同步而困扰吗&#xff1f;深蓝词…

Sketch MeaXure终极指南:高效设计标注的完整解决方案

Sketch MeaXure终极指南&#xff1a;高效设计标注的完整解决方案 【免费下载链接】sketch-meaxure 项目地址: https://gitcode.com/gh_mirrors/sk/sketch-meaxure Sketch MeaXure是一款专为现代设计工作流程打造的开源标注插件&#xff0c;通过智能化的标注系统和直观的…

YOLOv12官版镜像真实项目应用:停车场车辆统计

YOLOv12官版镜像真实项目应用&#xff1a;停车场车辆统计 1. 引言&#xff1a;从技术突破到实际落地 你有没有遇到过这样的场景&#xff1f;一个大型商业中心的停车场&#xff0c;每天进出数百辆车&#xff0c;人工统计车位使用情况不仅效率低&#xff0c;还容易出错。如果能…

Z-Image-Turbo节省成本:避免重复下载,镜像直启省时又省带宽

Z-Image-Turbo节省成本&#xff1a;避免重复下载&#xff0c;镜像直启省时又省带宽 1. 为什么Z-Image-Turbo值得你立刻试试&#xff1f; 你是不是也经历过这些场景&#xff1a; 想试一个新模型&#xff0c;结果光下载权重就卡在99%一小时&#xff1f;部署完发现显存不够&…