STM32 I2C驱动开发全解析:从理论到实战 | 零基础入门STM32第五十步
主题 | 内容 | 教学目的/扩展视频 |
---|---|---|
I2C总线 | 电路原理,跳线设置,I2C协议分析。驱动程序与调用。 | 熟悉I2C总线协议,熟练调用。 |
师从洋桃电子,杜洋老师
📑文章目录
- 引言
- 一、I2C驱动分层架构
- 二、I2C总线驱动代码精析
- 2.1 初始化配置(i2c.c)
- 2.2 数据发送函数(I2C_SAND_BUFFER)
- 2.3 数据接收函数(I2C_READ_BUFFER)
- 三、总线速度配置原理
- 四、用户应用实战(main.c)
- 五、器件驱动开发(LM75A示例)
- 5.1 温度读取函数
- 六、常见问题排查指南
- 七、进阶优化技巧
- 八、相关资源
- 总结
▲ 回顾上期🔍STM32入门之I2C总线应用详解(附LM75A温度传感器实战) | 零基础入门STM32第四十九步
引言
I2C总线是嵌入式系统中广泛使用的通信协议,具有接线简单、多设备共享总线等优点。本文将深入解析STM32的I2C驱动开发,通过分层架构设计、代码逐行分析和实战案例演示,帮助开发者快速掌握I2C通信的核心技术。
一、I2C驱动分层架构
- 硬件抽象层(HAL)
ST官方提供的固件库(如stm32f10x_i2c.c
),直接操作寄存器实现基础功能。 - 总线驱动层
封装I2C协议的核心操作(发送/接收数据),提供I2C_Configuration()
等接口。 - 器件驱动层
针对具体外设(如LM75A温度传感器)的驱动实现。 - 用户应用层
调用驱动函数实现业务逻辑,如温度显示。
二、I2C总线驱动代码精析
2.1 初始化配置(i2c.c)
void I2C_Configuration(void) {// GPIO配置:SCL=PB6, SDA=PB7GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; // 复用开漏模式GPIO_Init(GPIOB, &GPIO_InitStruct);// I2C参数配置I2C_InitStruct.I2C_ClockSpeed = 100000; // 100kHz标准模式I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 时钟占空比I2C_Init(I2C1, &I2C_InitStruct);I2C_Cmd(I2C1, ENABLE); // 使能I2C
}
- 关键点:
- GPIO必须配置为复用开漏模式(支持总线仲裁)
- 时钟速度需匹配从机设备(如LM75A支持400kHz)
2.2 数据发送函数(I2C_SAND_BUFFER)
void I2C_SAND_BUFFER(u8 SlaveAddr, u8 WriteAddr, u8* pBuffer, u16 NumByteToWrite) {I2C_GenerateSTART(I2C1, ENABLE); // 发送起始信号while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); // 等待EV5I2C_Send7bitAddress(I2C1, SlaveAddr, I2C_Direction_Transmitter); // 发送设备地址while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); // 等待EV6I2C_SendData(I2C1, WriteAddr); // 发送寄存器地址while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // 等待EV8while(NumByteToWrite--) { // 循环发送数据I2C_SendData(I2C1, *pBuffer++);while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));}I2C_GenerateSTOP(I2C1, ENABLE); // 发送停止信号
}
- 协议流程:
- 起始信号 → 2. 发送地址+写方向 → 3. 发送寄存器地址 → 4. 发送数据 → 5. 停止信号
2.3 数据接收函数(I2C_READ_BUFFER)
三、总线速度配置原理
在i2c.h
中定义总线速率:
#define BusSpeed 200000 // 200kHz
- 计算公式:
SCL频率 = APB1时钟频率 2 × ( I2C_ClockSpeed + 1 ) \text{SCL频率} = \frac{\text{APB1时钟频率}}{2 \times (\text{I2C\_ClockSpeed} + 1)} SCL频率=2×(I2C_ClockSpeed+1)APB1时钟频率
- 注意事项:
- APB1时钟需在初始化时正确配置(默认为36MHz)
- 实际速率可通过示波器测量SCL引脚验证
四、用户应用实战(main.c)
int main(void) {u8 tempData[3];I2C_Configuration(); // 初始化I2CTM1640_Init(); // 初始化显示模块while(1) {LM75A_GetTemp(tempData); // 读取温度// 显示温度值(示例代码略)delay_ms(200); // 控制采样频率}
}
- 调用链:
main()
→LM75A_GetTemp()
→I2C_READ_BUFFER()
→ 硬件寄存器操作
五、器件驱动开发(LM75A示例)
5.1 温度读取函数
void LM75A_GetTemp(u8 *Tempbuffer) {u8 rawData[2];I2C_READ_BUFFER(LM75A_ADD, 0x00, rawData, 2); // 读取原始数据// 数据解析(示例)int16_t temp = (rawData[0] << 8) | rawData[1];temp = temp >> 5; // 有效数据为11位*Tempbuffer = temp * 0.125; // 转换为实际温度值
}
- 关键参数:
LM75A_ADD = 0x9E
(包含R/W位)- 温度数据为16位(高11位有效)
六、常见问题排查指南
现象 | 可能原因 | 解决方案 |
---|---|---|
总线无响应 | 1. 硬件连接错误 | 检查SCL/SDA上拉电阻(4.7kΩ) |
数据校验失败 | 2. 时序不匹配 | 降低时钟速度或调整延时 |
重复地址冲突 | 3. 从机地址配置错误 | 使用I2C扫描工具检测设备地址 |
七、进阶优化技巧
- DMA传输
使用DMA减少CPU占用:I2C_DMACmd(I2C1, I2C_DMAReq_Tx | I2C_DMAReq_Rx, ENABLE);
- 错误恢复机制
检测总线忙状态时自动复位:if(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) {I2C_SoftwareResetCmd(I2C1, ENABLE);I2C_SoftwareResetCmd(I2C1, DISABLE); }
八、相关资源
[1] 洋桃电子B站课程-STM32入门100步
[2] STM32F103xx官方数据手册
[3] STM32F103X8-B数据手册(中文)
[4] STM32F103固件函数库用户手册(中文)
[5] I2C总线规范(中文)
[6] LM75(温度传感器)数据手册+编程说明+应用
[7] 温度传感器数码管显示程序
[8] I2C驱动程序分析.pptx
总结
本文从STM32的I2C驱动架构出发,详细解析了总线初始化、数据收发和速度配置的实现原理,并结合LM75A温度传感器展示了实际应用场景。掌握以下核心要点:
- 分层架构设计提升代码可维护性
- 严格遵循I2C协议时序
- 合理配置总线速率匹配外设
- 善用调试工具(如逻辑分析仪)验证通信波形
通过理论结合实践的方式,开发者能够快速构建稳定可靠的I2C通信系统。
💬 技术讨论(请在评论区留言~)
📌 下期预告:下一期将探讨LM75A驱动程序分析,欢迎持续关注!
点击查阅🔍往期【STM32专栏】文章
版权声明:本文采用[CC BY-NC-SA 4.0]协议,转载请注明来源
实测开发版:洋桃1号开发版(基于STM32F103C8T6)
更新日志:
- v1.0 初始版本(2025-03-07)
相关文章:
STM32 I2C驱动开发全解析:从理论到实战 | 零基础入门STM32第五十步
主题内容教学目的/扩展视频I2C总线电路原理,跳线设置,I2C协议分析。驱动程序与调用。熟悉I2C总线协议,熟练调用。 师从洋桃电子,杜洋老师 📑文章目录 引言一、I2C驱动分层架构二、I2C总线驱动代码精析2.1 初始化配置&a…...
Ragflow技术栈分析及二次开发指南
Ragflow是目前团队化部署大模型+RAG的优质方案,不过其仍不适合直接部署使用,本文将从实际使用的角度,对其进行二次开发。 1. Ragflow 存在问题 Ragflow 开源仓库地址:https://github.com/infiniflow/ragflow Ragflow 当前版本: v0.17.0 Ragflow 目前主要存在以下问题: …...
力扣hot100二刷——链表
第二次刷题不在idea写代码,而是直接在leetcode网站上写,“逼”自己掌握常用的函数。 标志掌握程度解释办法⭐Fully 完全掌握看到题目就有思路,编程也很流利⭐⭐Basically 基本掌握需要稍作思考,或者看到提示方法后能解答⭐⭐⭐Sl…...
【Godot4.3】斜抛运动轨迹曲线点求取函数
概述 原文写于去年9月。一篇测试性的文章。 基于初始位置和初始速度的抛物线 # 抛物运动轨迹曲线 - 基于初始位置和初始速度计算 func projectile_motion_curve(start_pos:Vector2, # 物体的起始位置velocity:Vector2, # 初始速度nums:int, …...
SpringBoot基础Kafka示例
这里将生产者和消费者放在一个应用中 使用的Boot3.4.3 引入Kafka依赖 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId> </dependency>yml配置 spring:application:name: kafka-1#kafka…...
【安卓逆向】安卓病毒介绍及其简单案例分析
目录 引言 一、Android 病毒介绍及分析方法 1.1 Android 病毒预览 1.2 Android 病毒分析必备知识 1.3 Android 病毒的常见类型及恶意行为 1.3.1 常见病毒类型 1.3.2 常见病毒行为 1.4 病毒激活条件 1.5 Android 病毒的传播方式 1.6 Android 病毒分析的一般方法 二…...
Git的命令学习——适用小白版
浅要了解一下Git是什么: Git是目前世界上最先进的的分布式控制系统。Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。Git 并不保存这些前后变化的差异数据。实际上…...
Bad owner or permissions on ssh/config - 解决方案
问题 在Windows系统通过ssh连接远程服务器时报错: ssh [ssh_user][ip] Bad owner or permissions on C:\\Users\\[win_user]/.ssh/config原因 这是因为.ssh文件夹或.ssh/config文件的权限异常,当前Windows账号没有读写权限导致的。 Windows系统重装&a…...
AI 赋能软件开发:从工具到思维的全面升级
喜欢可以到主页订阅专栏 引言 在当今技术飞速发展的时代,人工智能(AI)正以前所未有的速度渗透到各个领域,软件开发行业也不例外。AI 不仅改变了开发工具的使用方式,更深刻地影响了开发者的思维模式和工作流程。从代码生成到错误检测,从性能优化到项目管理,AI 正在全面…...
【Ubuntu系统设置固定内网ip,且不影响访问外网 】
Ubuntu系统安装后,由于每次重新开机会被重新分配内网ip,所以我们可以设置固定内网ip,且不影响访问外网,亲测有效 打开【终端】,查看当前内网ip(inet),子网掩码(netmask&a…...
VSCode集成C语言开发环境
下载MinGW https://sourceforge.net/projects/mingw/ 点击download按钮下载exe文件到本地 点击exe文件安装 选择基础包和c编译版 vscode安装部分跳过 安装code runner和c/c插件 **(1) 创建 C 文件** 新建一个测试文件(例如 hello.c)…...
力扣:3305.元音辅音字符串计数
给你一个字符串 word 和一个 非负 整数 k。 返回 word 的 子字符串 中,每个元音字母(a、e、i、o、u)至少 出现一次,并且 恰好 包含 k 个辅音字母的子字符串的总数。 示例 1: 输入:word "aeioqq"…...
vscode接入DeepSeek 免费送2000 万 Tokens 解决DeepSeek无法充值问题
1. 在vscode中安装插件 Cline 2.打开硅基流动官网 3. 注册并登陆,邀请码 WpcqcXMs 4.登录后新建秘钥 5. 在vscode中配置cline (1) API Provider 选择 OpenAI Compatible ; (2) Base URL设置为 https://api.siliconflow.cn](https://api.siliconfl…...
【ELK】ElasticSearch 集群常用管理API操作
目录 常用_cat 概览 集群状态 集群配置 集群磁盘使用 索引信息与配置 shard - 分片 查看段信息 nodes -节点 用户与权限 tasks 和 pending_tasks allocation - 均衡 thread_pool -线程 templete 模版 ILM 生命周期 其他 集群版本: 7.17.6 API地址&…...
BambuStudio学习笔记:MTUtils
# MTUtils.hpp 功能解析## 文件概述 该头文件提供了多线程同步工具和数值生成功能,主要包含以下组件:### 核心组件1. **自旋锁 (SpinMutex)**- 基于原子操作的高性能锁- 实现Lockable概念,可与标准库锁守卫配合使用2. **缓存对象模板 (Cached…...
DeepSeek开启AI办公新模式,WPS/Office集成DeepSeek-R1本地大模型!
从央视到地方媒体,已有多家媒体机构推出AI主播,最近杭州文化广播电视集团的《杭州新闻联播》节目,使用AI主持人进行新闻播报,且做到了0失误率,可见AI正在逐渐取代部分行业和一些重复性的工作,这一现象引发很…...
Ubuntu 22.04 安装配置 FTP服务器 教程
今天搞定在 Ubuntu 22.04 系统上安装和配置 VSFTPD ,还会涉及防火墙设置、SSL/TLS 设置,以及创建专门登录 FTP 服务器的账户。开始! 一、安装 VSFTPD 首先,咱得让系统知道有啥新软件包可以安装。打开终端,输入下面这…...
2021-05-28 C++自己写一个strcmp函数
规则 当s1<s2时,返回为负数-1; 当s1s2时,返回值 0; 当s1>s2时,返回正数1。 即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇…...
版本控制器Git(3)
文章目录 前言一、分支管理策略二、Bug分支管理遇到Bug时的处理方法使用 git stash 暂存工作区内容创建并切换到Bug修复分支恢复之前的工作 三、临时分支的删除总结 前言 我们在上篇讲到了分支,现在我们就着这个继续来讲解! 一、分支管理策略 master分支…...
TDengine 使用教程:从入门到实践
TDengine 是一款专为物联网(IoT)和大数据实时分析设计的时序数据库。它能够高效地处理海量的时序数据,并提供低延迟、高吞吐量的性能表现。在本文中,我们将带领大家从 TDengine 的安装、基本操作到一些高级功能,帮助你…...
Python Web项目的服务器部署
一.部署运行 1.虚拟环境的安装:(一行一行运行) wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh bash miniconda.sh -b -p /opt/miniconda3 echo export PATH"/opt/miniconda3/bin:$PAT…...
linux - ubuntu 使用时一些小问题整理 --- 持续更新
目录 ubuntu 中 root用户默认不存在解决办法 在Ubuntu系统中,将用户添加到sudoers文件中,使其能够以超级用户权限执行命令,通常可以通过以下几种方法实现: 方法1:将用户添加到sudo组 方法2:直接编辑sud…...
道路运输安全员考试:备考中的心理调适与策略
备考道路运输安全员考试,心理调适同样重要。考试压力往往会影响考生的学习效率和考试发挥。 首先,要正确认识考试压力。适度的压力可以激发学习动力,但过度的压力则会适得其反。当感到压力过大时,要学会自我调节。可以通过运动…...
关于WPS的Excel点击单元格打开别的文档的两种方法的探究【为单元格添加超链接】
问题需求 目录和文件结构如下: E:\Dir_Level1 │ Level1.txt │ └─Dir_Level2│ Level2.txt│ master.xlsx│└─Dir_Level3Level3.txt现在要在master.xlsx点击单元格进而访问Level1.txt、Level2.txt、Level3.txt这些文件。 方法一:“单元格右键…...
深入理解Tomcat:Java Web服务器的安装与配置
大家好!今天我们来聊聊Java Web开发中最重要的工具之一——Apache Tomcat。Tomcat是一个开源的Java Servlet容器和Web服务器,它是运行Java Web应用程序的核心环境。无论是开发、测试还是部署Java Web应用,Tomcat都是不可或缺的工具。本文将详…...
【从零开始学习计算机科学】编译原理(五)语法制导翻译
【从零开始学习计算机科学】编译原理(五)语法制导翻译 语法制导翻译语法制导定义SDDSDD的求值顺序两类重要的SDD语法制导的翻译方案SDTSDT的实现L属性定义的SDT左递归翻译方案语法制导翻译 语法表述的是语言的形式,或者说是语言的样子和结构。而程序设计语言中另一方面,是…...
Git使用(二)--如何配置 GitHub 远程仓库及本地 Git 环境
在日常的开发过程中,使用版本控制工具 Git 是一个非常重要的技能,特别是对于管理和协作开发。通过 GitHub,我们可以轻松地进行代码版本管理和共享。这篇博客将带您一步步学习如何配置 Git 环境并将本地仓库与 GitHub 远程仓库连接起来。 一、…...
【MySQL是怎么运行的】0、名词解释
聚簇索引:聚簇索引和数据在一起,又名主键索引,是主键id构建的一颗B树,非叶节点是主键id,叶子节点是真实数据。其他索引统称二级索引,也称为非聚簇索引。覆盖索引:查找的数据就在索引树上&#x…...
网络安全事件响应--应急响应(windows)
应用系统日志 Windows主要有以下三类日志记录系统事件:应用程序日志、系统日志和安全日志。 系统和应用程序日志存储着故障排除信息,对于系统管理员更为有用。安全日志记录着事件审计信息,包括用户验证(登录、远程访问等&#x…...
使用 UNIX 命令在设计中搜索标识符:vcsfind 的入门指南
在现代软件开发和硬件设计中,快速准确地定位和搜索特定标识符是提高开发效率的关键。本文将介绍如何使用 UNIX 命令 vcsfind 在设计中搜索标识符,帮助您更高效地管理您的项目。 什么是 vcsfind? vcsfind 是一个强大的 UNIX 命令行工具&#x…...
Qt不同窗口类的控件信号和槽绑定
做项目的时候我使用了Qt,不同的界面使用了不同的ui的类进行解耦,但是信号和槽绑定的时候可能是不同界面的控件互相进行通讯连接,然而ui指针对于各个界面类是私有成员,无法直接跳过访问,在网上看了一些参考资料…...
【Godot4.2】Vector2向量插值的应用
求线段的等分点 extends Node2Dvar pos:Vector2 var split_num:int var p1 Vector2(200,200) var p2 Vector2(100,100)func _input(event: InputEvent) -> void:if event is InputEventMouseButton:if event.button_index MOUSE_BUTTON_WHEEL_DOWN:split_num clamp(spl…...
Java线程安全
Java线程安全实现方式及原理详解 一、线程安全的核心概念 线程安全指多线程环境下,程序能正确且一致地处理共享资源的状态,不会因线程调度顺序导致数据不一致或逻辑错误。例如多个线程同时修改共享变量时,需通过同步机制确保操作原子性。 二、主要实现方式及原理 synchro…...
电机控制常见面试问题(九)
文章目录 一、谈谈电机死区时间1.死区时间过短的后果:2.如何判断死区时间不足?3.解决方案 二、请描述对实时操作系统(RTOS)的理解三.解释FOC算法的原理并比较与其他无刷电机控制算法的优劣四.什么是电机堵转,如何避免电机堵转五.…...
Django与模板
我叫补三补四,很高兴见到大家,欢迎一起学习交流和进步 今天来讲一讲视图 Django与模板文件工作流程 模板引擎:主要参与模板渲染的系统。 内容源:输入的数据流。比较常见的有数据库、XML文件和用户请求这样的网络数据。 模板&am…...
UFW 配置 Ubuntu 防火墙并设置防火墙规则
一、什么是 UFW? UFW,全称为 Uncomplicated Firewall,顾名思义,它是一种简单易用的防火墙管理工具。与传统的防火墙配置工具相比,UFW 以其简洁明了的命令行界面而闻名。虽然它主要为普通用户设计,但它也具…...
在Keil 5中如何建立一个STM32项目
大家在使用Keil时大多都是利用样板项目来建立自己的项目,为了了解基本建立项目的知识写下了本篇文章。 项目建立流程 1.建立项目文件夹并明确其作用 —— 2.下载HAL库 —— 3.拷贝相关文件到对应文件夹 —— 4.打开Keil 5新建项目 —— 5.将项目文件夹添加到项目 …...
Linux 系统负载过高的排查思路
技术探讨:Linux系统负载过高的排查思路 在Linux服务器运行过程中,如果系统负载过高,可能会导致性能下降和服务不稳定。以下是针对Linux系统负载过高问题的排查思路和解决方法: 1. 查看系统负载: 使用uptime或top命令查…...
kotlin高级用法总结
Kotlin 是一门功能强大且灵活的编程语言,除了基础语法外,它还提供了许多高级特性,可以帮助你编写更简洁、高效和可维护的代码。以下是 Kotlin 的一些高级用法,涵盖了协程、扩展函数、属性委托、内联类、反射等内容。 协程&#x…...
Windows Wise Care 365 PRO-中文便携版
Windows Wise Care 365 PRO 链接:https://pan.xunlei.com/s/VOL9UE-i-GLXYr-6KhdyghHOA1?pwdajqe# - 禁止后续强制升级提示弹窗,杜绝后台下载升级文件 - 禁止自动创建开机启动项、任务计划,删除相关选项 - 去右侧无用区域:用户…...
SpringBoot 自动配置原理
自动配置是Spring Boot的关键特性之一,它简化了传统Spring应用繁琐的配置,通过智能推断和条件化配置简化了Spring应用的开发。 1. 自动配置的核心思想 目标:根据项目的依赖(如类路径中的 JAR 包)和已有的配置…...
HTMLCSS绘制三角形
1.代码: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>01triangle</title><s…...
WorkTool 技术解析:企业微信自动化办公的合规实现方案
引言:企业微信生态中的自动化需求 随着企业微信用户规模突破4亿(据腾讯2023年财报),其开放生态催生了自动化办公的技术需求。传统RPA(机器人流程自动化)工具在PC端已广泛应用,但移动端自动化仍…...
Linux机器之间排查网络连通问题
网络连通性排查步骤(基于五层模型) 以下按照网络五层架构,从底层到高层逐层排查,并分别列出Ubuntu和CentOS对应的命令。 1. 物理层 排查点:网线、网卡状态、物理连接。 命令(通用):…...
大数据学习(62)- Hadoop-yarn
&&大数据学习&& 🔥系列专栏: 👑哲学语录: 承认自己的无知,乃是开启智慧的大门 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一下博主哦ᾑ…...
Stable Diffusion/DALL-E 3图像生成优化策略
Stable Diffusion的最新版本或社区开发的插件,可以补充这些信息以保持内容的时效性。 云端源想 1. 硬件与部署优化(进阶) 显存压缩技术 使用--medvram或--lowvram启动参数(Stable Diffusion WebUI),通过分…...
21 | 全面测试项目功能
提示: 所有体系课见专栏:Go 项目开发极速入门实战课;欢迎加入 云原生 AI 实战 星球,12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力(聚焦于 Go、云原生、AI Infra);本节课最终…...
Debian系统grub新增启动项
参考链接 给grub添加自定义启动项_linux grub定制 启动项名称自定义-CSDN博客 www.cnblogs.com 1. boot里面的grub.cfg 使用vim打开boot里面的grub.cfg sudo vim /boot/grub/grub.cfg 这时候会看到文件最上方的提示 2. 真正配置grub的文件 从刚才看到的文件提示中&#x…...
C语言中的assert断言,你了解多少呢?
引言 ‘ 介绍了assert 是什么,以及assert的优缺点 一、什么assert是断言 assert.h 头文件定义了宏 assert() ,用于在运行时确保程序符合指定条件,如果不符合,就报错终止运行。这个宏常常被称为“断言”。 int a 10;asse…...
设计模式之工厂模式
工厂模式属于创建型设计模式的一种,其实在我看来它更是在面向对象编程语言的抽象层的更加灵活的应用。工厂模式其实在创建型模式中难度较高,整体的理解上需要一定时间进行消化,在一些Java常见框架中,这种模式也是频繁出现的设计&a…...