当前位置: 首页 > article >正文

【STM32】综合练习——智能风扇系统

目录

0 前言

1 硬件准备

2 功能介绍

3 前置配置

3.1 时钟配置

3.2 文件配置

4 功能实现 

4.1 按键功能

4.2 屏幕功能

4.3 调速功能

4.4 倒计时功能

4.5 摇头功能

4.6 测距待机功能


0 前言

由于时间关系,暂停详细更新,本文章中,只会记录重要代码,关于cubmx的配置以及引脚配置,请自行下载文件配置

【免费】基于STM32的多功能风扇资源-CSDN文库


1 硬件准备

STM32F103C8T6 * 1

面包板 * 1

OLED显示屏(SSD131590) * 1

RGB三色全彩LED模块 * 1

SG90舵机 * 1

HC-SR04超声波模块 * 1

130直流电机 * 1

风扇头 * 1

L298N电机驱动模块 * 1

直插2脚微动按键 * 2

USB转TTL模块-CH340模块 * 1

ST-LINK V2 * 1

杜邦线 (公对公、公对母、母对母)

跳线


2 功能介绍

(1)完成手动调节(按键)调节风扇三档转速(档位转速分别为30%、50%、80%)
(2)实现按键定时功能(短按一次时间加5秒,长按后倒计时开始,倒计时结束后风扇停止转动)
(3)实现风速不同档位显示,一档风速亮白灯,二档风速亮蓝灯,三档风速亮红灯,并通过OLED屏幕显示当前灯的颜色和定时时间(用英文和数字)
(4)实现通过串口显示当前风速
(5)以超声波为总开关控制系统运作(在20厘米内系统才可工作)
(6)利用舵机实现风扇摇头功能,并通过按键进行控制


3 前置配置

3.1 时钟配置

 设置高速外部时钟:晶振

设置时钟频率为72Mhz 


3.2 文件配置

修改文件名称以及选择IDE:MDK-ARM 

为每一个外设单独生成一对.c/.h文件(模块化,方便管理)


4 功能实现 

4.1 按键功能

在interrupt.c中使用回调函数判断定时器2,进行按键扫描(按键具体的功能不在此文件中) 

// interrupt.cif(htim == &htim2)	// button{keys[0].clickState = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6);	// left BUTTONkeys[1].clickState = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5);	// right BUTTONfor(int i=0; i<=1; i++){switch(keys[i].stage){case 0:{//judge clickif(keys[i].clickState == 0) keys[i].stage = 1; //go next stage}break;case 1:{if(keys[i].clickState == 0){// is true click// clear timekeys[i].pressTime = 0;// go next stagekeys[i].stage = 2;}}break;case 2:{if(keys[i].clickState == 1)	// release click{//judge click which button and its typeif(keys[i].pressTime < 30){// short clickchooseButton(i, click);} else {// long clickchooseButton(i, longClick);}// reset stage keys[i].stage = 0;} else {	// still click// time ++keys[i].pressTime++;}}break;}}}

按键具体的功能被拆分在了buttonFunciton.c中

从上到下依次为:

按键1的单击(调速)、按键1的长按(摇头)

按键2的单击(计时器加5)、按键2的长按(倒计时开始)

#include "buttonFunction.h"// to judge which button is press down
void chooseButton(uint8_t key, uint8_t type){switch(key){case 0:	// button 1{if(type == 0){// click —— Toggle Speed Mode and Oled Update//WindSpeedspeedLevel++;speedLevel %= 4;SetWindSpeed();UsartSpeed();HomePage();} else if (type == 1){// long click —— Toggle Shaking ModeisShake = !isShake;if(isShake){HAL_TIM_Base_Start_IT(&htim1);shakeIsBegin = 1;} else {HAL_TIM_Base_Stop_IT(&htim1);shakeIsBegin = 0;}}}break;case 1:	//	button 2{if(type == 0){// click —— Count Down Number Add and Oled UpdatetimeCount += 5;HomePage();} else if (type == 1){// long click	—— Count Down Startif(timeCount > 0){HAL_TIM_Base_Start_IT(&htim4);isBegin = 1;}}}break;}
}

4.2 屏幕功能

OLED使用Keysking的模块文件,这里就不展示了,使用方法见【STM32入门教程-2024】第14集 如何在OLED屏幕上挥毫_哔哩哔哩_bilibili

// page.c
#include "page.h"// ——————————————Init—————————————————
void PageInit(void){HAL_Delay(20); // 单片机启动比OLED上电快,需要延迟等待一下OLED_Init(); // 初始化OLED
}// ——————————————View——————————————————
void CopyrightPage(void) {OLED_NewFrame();OLED_DrawImage(5,1, &logoImg, OLED_COLOR_NORMAL);OLED_PrintString(85, 4, "创客", &font16x16, OLED_COLOR_NORMAL);OLED_PrintString(85, 24, "中心", &font16x16, OLED_COLOR_NORMAL);OLED_PrintString(85, 44, "出品", &font16x16, OLED_COLOR_NORMAL);OLED_ShowFrame();
}void HomePage(void){OLED_NewFrame();HomePageTitle();HomePageSpeedLight();if(timeCount > 0){HomePageCountDown();}OLED_ShowFrame();
}void SleepPage(void){OLED_NewFrame();OLED_PrintString(32, 10, "待机中...", &font16x16, OLED_COLOR_NORMAL);OLED_PrintString(4, 35, "~(p≧ w≦ q)~", &font12x12, OLED_COLOR_NORMAL);OLED_ShowFrame();
}// ————————————Component————————————————// Home Title
void HomePageTitle(void){OLED_PrintString(32, 10, "智能の扇", &font16x16, OLED_COLOR_NORMAL);
}// Home Body
void HomePageSpeedLight(void){StopAllLight();switch(speedLevel){case 0:{OLED_PrintString(50, 30, "STOP", &font16x16, OLED_COLOR_NORMAL);}break;case 1:{OLED_PrintString(46, 30, "WHITE", &font16x16, OLED_COLOR_NORMAL);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);}break;case 2:{OLED_PrintString(50, 30, "BLUE", &font16x16, OLED_COLOR_NORMAL);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);}break;case 3:{OLED_PrintString(54, 30, "RED", &font16x16, OLED_COLOR_NORMAL);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);}break;}
}// Home Bottom
void HomePageCountDown(void){char arr[40];sprintf(arr, "%d", timeCount);if(timeCount >= 10000){OLED_PrintString(46, 50, arr, &font16x16, OLED_COLOR_NORMAL);} else if(timeCount >= 1000){OLED_PrintString(50, 50, arr, &font16x16, OLED_COLOR_NORMAL);} else if(timeCount >= 100){OLED_PrintString(54, 50, arr, &font16x16, OLED_COLOR_NORMAL);} else if(timeCount >= 10){OLED_PrintString(58, 50, arr, &font16x16, OLED_COLOR_NORMAL);} else {OLED_PrintString(62, 50, arr, &font16x16, OLED_COLOR_NORMAL);}
}// Stop All Light
void StopAllLight(void){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
}
// page.h
#ifndef __PAGE_H__
#define __PAGE_H__#include "main.h"
#include "string.h"
#include "oled.h"
#include "stdio.h"
#include "stdbool.h"// ——————————————Internal Api————————————————
// view
void PageInit(void);
void CopyrightPage(void);
void HomePage(void);
void SleepPage(void);// Component
void HomePageTitle(void);
void HomePageSpeedLight(void);
void HomePageCountDown(void);
void StopAllLight(void);
// ——————————————External Api————————————————
// windSpeed
extern uint8_t speedLevel;
extern uint8_t tempSpeedLevel;
// countDown
extern uint16_t timeCount;
// ——————————————————————————————————————————
#endif

4.3 调速功能

// windSpeed.c
#include "windSpeed.h"void SetWindSpeed(void){switch(speedLevel){case 0:{__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, StopSpeed);}break;case 1:{__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, LowSpeed);}break;case 2:{__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, MidSpeed);}break;case 3:{__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, HighSpeed);}break;}
}void UsartSpeed(void){sprintf(arr, "当前档位为:%d", speedLevel);HAL_UART_Transmit(&huart1, (uint8_t *)arr, sizeof(arr), HAL_MAX_DELAY);}
// windSpeed.h
#ifndef __WINDSPEED_H__
#define __WINDSPEED_H__#include "main.h"
#include "tim.h"
#include "usart.h"
#include <stdio.h>// ————————————Internal Api——————————————————#define StopSpeed 0
#define LowSpeed 300
#define MidSpeed 500
#define HighSpeed 800
uint8_t speedLevel = 0;
uint8_t tempSpeedLevel = 10;
void SetWindSpeed(void);
void UsartSpeed(void);
char arr[99];// ————————————External Api——————————————————// 0// ——————————————————————————————————————————#endif

4.4 倒计时功能

// interrupt.cif(htim == &htim4){	// Time Count Downif(timeCount > 1){timeCount--;} else {timeCount--;speedLevel = 0;SetWindSpeed();HAL_TIM_Base_Stop_IT(&htim4);isBegin = 0;HAL_TIM_Base_Stop_IT(&htim1);shakeIsBegin = 0;UsartSpeed();}HomePage();}

 倒计时功能主要在interrupt中实现,此处只声明了个全局变量 

// countDown.c
#include "countDown.h"
// countDown.h
#ifndef __COUNTDOWN_H__
#define __COUNTDOWN_H__#include "main.h"
#include "stdbool.h"
// ————————————Internal Api——————————————————uint16_t timeCount;
bool isBegin = 0;// ————————————External Api——————————————————// 0// ——————————————————————————————————————————#endif

4.5 摇头功能

舵机教程:【STM32】动画讲解输入捕获 并实现超声波测距_哔哩哔哩_bilibili 

// shake.c
#include "shake.h"int shakeNumber = 1500;	//500——2500 duty
bool shakeMode = 0;void shakeApi(void){if(shakeMode == 0){// forwardif(shakeNumber < 2500){shakeNumber += shakeSpeed;} else {shakeMode = 1;}__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, shakeNumber);} else {// reverseif(shakeNumber > 500){shakeNumber -= shakeSpeed;} else {shakeMode = 0;}__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, shakeNumber);}}
// shake.h
#ifndef __SHAKE_H__
#define __SHAKE_H__#include "main.h"
#include "tim.h"
#include "stdbool.h"// ————————————Internal Api——————————————————#define shakeSpeed 10	// 5(slow) 10(normal) 20(fast) 100(very fast)
void shakeApi(void);
bool shakeIsBegin = 0;// ————————————External Api——————————————————// 0// ——————————————————————————————————————————#endif

启用中断:

// interrupt.c
if(htim == &htim1){ // ShakeshakeApi();
}

4.6 测距待机功能

为了使系统正常工作时(20cm以内) ,能继续进行上一次的数据(如倒计时从上一次离开开始,继续倒计时),这里并没有直接修改存储该数据的变量,而是直接将所有功能暂停(具体实现见StopAll函数),恢复时再读取存储数据的变量

// ultrasound.c
#include "ultrasound.h"void TriggerUltrasound(void){// Send trigger signalHAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET);
//	HAL_Delay(1);for(uint32_t i=0; i<11; i++);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);// Reset counter__HAL_TIM_SET_COUNTER(&htim3, 0);// WaitHAL_Delay(50);
}void MeasurementDistance(void){timeCountBefore = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_1);timeCountAfter = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_2);distance = (timeCountAfter - timeCountBefore) * 0.034 / 2;
}void StopAll(void){// stop all lightStopAllLight();// stop wideSpeed__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 0);// stop count downHAL_TIM_Base_Stop_IT(&htim4);// stop shakeHAL_TIM_Base_Stop_IT(&htim1);// sleep pageSleepPage();
}void StartAll(void){// start count downif(timeCount > 0 && isBegin){HAL_TIM_Base_Start_IT(&htim4);}// start shakeif(shakeIsBegin){HAL_TIM_Base_Start_IT(&htim1);}// start wideSpeedSetWindSpeed();// home page - start all lightHomePage();
}
// ultrasound.h
#ifndef __ULTRASOUND_H__
#define __ULTRASOUND_H__#include "main.h"
#include "tim.h"
#include "stdbool.h"// ————————————Internal Api——————————————————uint16_t timeCountBefore;
uint16_t timeCountAfter;
float distance;
void TriggerUltrasound(void);
void MeasurementDistance(void);
void StopAll(void);
void StartAll(void);// ————————————External Api——————————————————// page - light
extern void HomePage(void);
extern void SleepPage(void);
extern void StopAllLight(void);
// windSpeed
extern uint8_t speedLevel;
extern void SetWindSpeed(void);
// count down
extern uint16_t timeCount;
extern bool isBegin;
// shake
extern bool shakeIsBegin;
// ——————————————————————————————————————————#endif

输入捕获中断:

测距思想:一个通道读上升沿,一组的另一个通道读下降沿,并且在读到下降沿的时候进行中断

教程:【STM32】动画讲解输入捕获 并实现超声波测距_哔哩哔哩_bilibili 

// interrupt.c
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){if(htim == &htim3 && htim -> Channel == HAL_TIM_ACTIVE_CHANNEL_2){	// ultrasound// Measurement Ultrasound DistanceMeasurementDistance();
//		sprintf(aeee, "%f", distance);
//		HAL_UART_Transmit(&huart1, (uint8_t *)aeee, sizeof(aeee), HAL_MAX_DELAY);if(distance > 22){// sleepStopAll();} else if(distance >= 0 && distance <= 22){// normalStartAll();}}}

相关文章:

【STM32】综合练习——智能风扇系统

目录 0 前言 1 硬件准备 2 功能介绍 3 前置配置 3.1 时钟配置 3.2 文件配置 4 功能实现 4.1 按键功能 4.2 屏幕功能 4.3 调速功能 4.4 倒计时功能 4.5 摇头功能 4.6 测距待机功能 0 前言 由于时间关系&#xff0c;暂停详细更新&#xff0c;本文章中&#xff0c;…...

MyBatis 动态 SQL 使用详解

&#x1f31f; 一、什么是动态 SQL&#xff1f; 动态 SQL 是指根据传入参数&#xff0c;动态拼接生成 SQL 语句&#xff0c;不需要写多个 SQL 方法。MyBatis 提供了 <if>、<choose>、<foreach>、<where> 等标签来实现这类操作 ✅ 二、动态 SQL 的优点…...

【重装系统】大白菜自制U盘装机,备份C盘数据,解决电脑启动黑屏/蓝屏

1. 准备 U 盘 U 盘容量至少 8G&#xff0c;备份 U 盘的数据&#xff08;后期会格式化&#xff09; 2. 从微软官网下载操作系统镜像 https://www.microsoft.com/zh-cn/software-download/windows11 3. 下载安装大白菜 https://www.alipan.com/s/33RVnKayUfY 4. 插入 U 盘&#…...

vue实现目录锚点且滚动到指定区域时锚点自动回显——双向锚点

最近在用vue写官网&#xff0c;别问我为什么用vue写官网&#xff0c;问就是不会jq。。。。vue都出现11年了。。。 左侧目录&#xff1a;点击时&#xff0c;右侧区域可以自动滚动到指定的位置。 右侧区域手动滚动时&#xff0c;左侧锚点可以自动切换到对应的目录上 从而实现…...

python——正则表达式

一、简介 在 Python 中&#xff0c;正则表达式主要通过 re 模块实现&#xff0c;用于字符串的匹配、查找、替换等操作。 二、Python的re模块 使用前需要导入&#xff1a; import re 三、常用方法 方法描述re.match(pattern, string)从字符串开头匹配&#xff0c;返回第一个匹…...

Flutter Invalid constant value.

0x00 问题 参数传入变量&#xff0c;报错&#xff01; 代码 const Padding(padding: EdgeInsets.all(20),child: GradientProgressIndicator(value: _progress), ),_progress 参数报错&#xff1a;Invalid constant value. 0x01 原因 这种情况&#xff0c;多发生于&#xff…...

libev实现Io复用及定时器事件服务器

客户端和服务器都绑定在了enp2s0网卡&#xff0c;需要SERVER_IP和SERVER_PORT改为其ip&#xff0c;注意不能是127.0.0.1&#xff0c;因为这个是lo虚拟网口。 安装libev sudo apt-get install libev-dev客户端&#xff1a; #include <iostream> #include <string>…...

【精品PPT】2025固态电池知识体系及最佳实践PPT合集(36份).zip

精品推荐&#xff0c;2025固态电池知识体系及最佳实践PPT合集&#xff0c;共36份。供大家学习参考。 1、中科院化学所郭玉国研究员&#xff1a;固态金属锂电池及其关键材料.pdf 2、中科院物理所-李泓固态电池.pdf 3、全固态电池技术研究进展.pdf 4、全固态电池生产工艺.pdf 5、…...

如何计算设备电池工作时长?

目录 【mAh&#xff08;毫安时&#xff09;计算方法】 【Wh&#xff08;瓦时&#xff09;计算方法】 【为什么仅用电流&#xff08;mA&#xff09;和时间&#xff08;h&#xff09;就能计算电池使用时长&#xff08;mAh&#xff09;&#xff1f;】 1. mAh 的本质是“电荷量…...

抽象类及其特性

目录 1、概念2、语法3、特性4、作用 1、概念 在面向对象中&#xff0c;所有对象都是通过类来描述的&#xff0c;但是并不是所有的类都可以用来描述对象。比如下述例子中的 Animal 类&#xff0c;Dog 类和 Cat 类是 Animal 类的子类&#xff0c;可以分别描述小狗和小猫&#xf…...

【教程】xrdp修改远程桌面环境为xfce4

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 xfce4 vs GNOME对比 配置教程 1. 安装 xfce4 桌面环境 2. 安装 xrdp 3. 配置 xrdp 使用 xfce4 4. 重启 xrdp 服务 5. 配置防火墙&#xff…...

利用python从零实现Byte Pair Encoding(BPE):NLP 中的“变形金刚”

BPE&#xff1a;NLP 界的“变形金刚”&#xff0c;从零开始的奇幻之旅 在自然语言处理&#xff08;NLP&#xff09;的世界里&#xff0c;有一个古老而神秘的传说&#xff0c;讲述着一种强大的魔法——Byte Pair Encoding&#xff08;BPE&#xff09;。它能够将普通的文本“变形…...

部署redis cluster

一。在所有的主机里面设置密码和文件地址 vi /etc/redis/6379.conf 注释&#xff1a;登陆则要使用auth 123456才可以进入redis 配置文件地址和超时时间 二。创建集群&#xff1a;上面主机为master&#xff0c;下面为slave&#xff0c;master和slave会随机分配 先写主节点&…...

Android 11 (API 30) 及更高版本中,查询的特定应用商店包,无需动态请求权限处理

在 Android 11 (API 30) 及更高版本中&#xff0c;通过在 AndroidManifest.xml 中添加 <queries> 元素声明需要查询的特定应用商店包名后&#xff1a; 1. 不需要额外请求权限 &#xff08;如 QUERY_ALL_PACKAGES &#xff09;即可查询这些应用的安装状态 2. 这是 Googl…...

基于springboot钻孔数据管理系统的设计与实现(源码+lw+部署文档+讲解),源码可白嫖!

摘要 本钻孔数据管理系统采用B/S架构&#xff0c;数据库是MySQL&#xff0c;网站的搭建与开发采用了先进的Java语言、Hadoop、数据可视化技术进行编写&#xff0c;使用了Spring Boot框架。该系统从两个对象&#xff1a;由管理员和用户来对系统进行设计构建。用户主要功能包括&…...

SpringBoot和微服务学习记录Day2

微服务 微服务将单体应用分割成更小的的独立服务&#xff0c;部署在不同的服务器上。服务间的关联通过暴露的api接口来实现 优点&#xff1a;高内聚低耦合&#xff0c;一个模块有问题不影响整个应用&#xff0c;增加可靠性&#xff0c;更新技术方便 缺点&#xff1a;增加运维…...

4.9复习记

1.地宫取宝--记忆化搜索&#xff0c;可以先写void dfs&#xff0c;然后在改成ll 形式的&#xff0c;边界条件return 0/1&#xff1b; 记忆化数组与dfs元素保持一致&#xff0c;记得记忆化剪枝 这个题特殊在value可能是0&#xff0c;不取的时候应该记为-1 https://mpbeta.cs…...

LinuxSocket套接字编程

1.介绍函数使用 1.创建套接字 int socket(int domain, int type, int protocol); domain&#xff1a;指定协议族&#xff0c;如AF_INET&#xff08;IPv4&#xff09;或AF_INET6&#xff08;IPv6&#xff09;。 type&#xff1a;指定套接字类型&#xff0c;如SOCK_DGRAM&#…...

动态科技感html导航网站源码

源码介绍 动态科技感html导航网站源码&#xff0c;这个设计完美呈现了科幻电影中的未来科技界面效果&#xff0c;适合展示技术类项目或作为个人作品集的入口页面&#xff0c;自适应手机。 修改卡片中的链接指向你实际的HTML文件可以根据需要调整卡片内容、图标和颜色要添加更…...

Java进阶版线程池(超详细 )

线程池 线程池工具类 Executors Executors 是 Java 提供的一个工具类&#xff0c;它包含了多个静态方法&#xff0c;能够方便地创建不同类型的线程池。 newFixedThreadPool 创建一个固定大小的线程池&#xff0c;线程池中的线程数量固定&#xff0c;当有新任务提…...

每日算法:洛谷U535992 J-C 小梦的宝石收集(双指针、二分)

题目描述 小梦有 n 颗能量宝石&#xff0c;其中第 i 颗的能量为 ai​&#xff0c;但这些能量宝石十分不稳定&#xff0c;随时有可能发生崩坏&#xff0c;导致他们全部消失&#xff01; 小梦想要留住宝石们&#xff0c;不希望他们发生崩坏&#xff0c;同时他发现&#xff1a;如…...

YOLOv11训练中精准率召回率与mAP@0.5的动态变化分析

目标检测模型的训练过程涉及多个关键性能指标和损失函数的变化&#xff0c;这些数据能够直观反映模型的收敛速度、最终精度以及改进效果。本文旨在通过绘制YOLOv11模型在训练过程中的精准率&#xff08;Precision&#xff09;、召回率&#xff08;Recall&#xff09;、mAP0.5 、…...

Java常用工具算法-6--秘钥托管云服务AWS KMS

前言&#xff1a; 之前我们介绍了一些常用的加密算法&#xff08;如&#xff1a;对称加密AES&#xff0c;非对称加密RSA&#xff0c;ECC等&#xff09;&#xff0c;不论是哪一种都需要涉及到秘钥的管理。通常的做法都是把秘钥放到配置文件中进行配置&#xff0c;但是对于一些高…...

11. Langchain输出解析(Output Parsers):从自由文本到结构化数据

引言&#xff1a;从"自由发挥"到"规整输出" 2025年某金融机构的合同分析系统升级前&#xff0c;AI生成的合同摘要需人工二次处理达47分钟/份。引入LangChain结构化解析后&#xff0c;处理时间缩短至3分钟。本文将详解如何用LangChain的解析器&#xff0c;…...

docker stack常用命令

1、Docker Stack介绍 Docker Stack管理swarm堆栈与Swarm协调器配合使用&#xff0c;是Docker Swarm环境中用于管理一组相关服务的工具。它使得在Swarm集群中部署、管理和扩展一组相互关联的服务变得简单。主要用于定义和编排容器化应用的多个服务。以下是Docker Stack的一些关…...

python reportlab模块----操作PDF文件

reportlab模块----操作PDF文件 一. 安装模块二. reportlab相关介绍三. 扩展canvas类四. 水平写入完整代码五. 垂直写入完整代码 一. 安装模块 pip install reportlab二. reportlab相关介绍 # 1. letter 生成A4纸张尺寸 from reportlab.lib.pagesizes import letter print(let…...

解锁基因密码之重测序(从测序到分析)

在生命科学的奇妙世界中&#xff0c;基因恰似一本记录着生命奥秘的“天书”&#xff0c;它承载着生物体生长、发育、衰老乃至疾病等一切生命现象的关键信息。而重测序技术&#xff0c;则是开启基因“天书”奥秘的一把神奇钥匙。 试想&#xff0c;你手中有一本经典书籍的通用版…...

TQTT_KU5P开发板教程---QSFP25G光口回环测试

文档实现功能介绍 本文档通过一个叫做ibert的IP&#xff0c;实现25G光口回环测试例子。工程新建方法请参考文档《流水灯》&#xff0c;其中只是将文件名进行修改。 Vivado 起始页&#xff08;或 file-->Project-->New 创建新工程(Create New Project) 向导起始页面 点…...

JVM虚拟机篇(七):JVM垃圾回收器全面解析与G1深度探秘及四种引用详解

JVM垃圾回收器全面解析与G1深度探秘及四种引用详解 JVM虚拟机&#xff08;七&#xff09;&#xff1a;JVM垃圾回收器全面解析与G1深度探秘及四种引用详解一、JVM有哪些垃圾回收器1. Serial回收器2. ParNew回收器3. Parallel Scavenge回收器4. Serial Old回收器5. Parallel Old回…...

柑橘病虫害图像分类数据集OrangeFruitDaatset-8600

文章目录 1. 前言2. 数据类别介绍3. 数据集地址 1. 前言 柑橘&#xff0c;作为水果界的 “宠儿”&#xff0c;不仅以其酸甜可口的味道深受大众喜爱&#xff0c;更是在全球水果产业中占据着举足轻重的地位。无论是早餐中的一杯橙汁&#xff0c;还是下午茶里的柑橘甜点&#xff…...