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

零基础STM32单片机编程入门(九)IIC总线详解及EEPROM实战含源码视频

文章目录

    • 一.概要
    • 二.IIC总线基本概念
      • 1.总体特征
      • 2.通讯流程
    • 三.EEPROM介绍
      • 1.M24C08基本介绍
      • 2.向M24C08写一个字节时序图
      • 3.从M24C08读一个字节时序图
    • 四.GPIO模拟IIC驱动M24C08读写
    • 五.CubeMX工程源代码下载
    • 六.讲解视频链接地址
    • 七.小结

一.概要

IIC(Inter-Integrated Circuit)总线是一种由NXP(原PHILIPS)公司开发的两线式串行总线,用于连接微控制器及其外围设备。多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。

二.IIC总线基本概念

I2C 总线,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。
在这里插入图片描述

1.总体特征

在这里插入图片描述

2.通讯流程

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

三.EEPROM介绍

EEPROM( Electrically Erasable Programmable Read Only Memory )全称是电可擦除可编程只读存储器,是非易失存储器,可以访问到每个字节,容量比较小。目前的EEPROM一般是IIC接口或者SPI接口的。

1.M24C08基本介绍

M24C08是ST公司(意法半导体公司)的串行接口的EEPROM存储芯片,它的容量是8K bit。
在这里插入图片描述

芯片功能描述:
M24C08系列支持I2C,总线数据传送协议I2C,总线协议规定任何将数据传送到总线的器件作为发送器。任何从总线接收数据的器件为接收器;数据传送是由产生串行时钟和所有起始停止信号的主器件控制的。主器件和从器件都可以作为发送器或接收器,但由主器件控制传送数据(发送或接收)的模式。

芯片特性介绍:

1.两线串行接口(SDA、SCL)

2.有用于硬件数据保护的写保护引脚

3.自定时写入周期(5毫秒),因为内部有页缓冲区,向M24C08写入数据之后,还需要等待M24C08将缓冲区数据写入到内部EEPROM区域

4.数据保存可达100年

5.100万次擦写周期

6.高数据传送速率为400KHz、低速100KHZ和IIC总线兼容

7.16字节页写缓冲区
这个缓冲区大小与芯片具体型号有关: 8字节页(1K、2K)、16字节页(4K、8K、16K)

在这里插入图片描述

M24C08的E2(3脚)一般接地,E1,E0是容量大点的EEPROM才有,这样M24C08这个器件,写操作时候的地址就是0xA0,读操作时候的地址是0xA1。

2.向M24C08写一个字节时序图

写操作过程中只有ACK是M24C08发出的,其他信号都是单片机发出的。

在这里插入图片描述

3.从M24C08读一个字节时序图

读操作过程中ACK跟返回的数据是M24C08发出的,其他信号都是单片机发出的。

在这里插入图片描述

四.GPIO模拟IIC驱动M24C08读写

硬件准备:

STLINK接STM32F103C8T6小系统板,STLINK接电脑USB口,
STM32F103C8T6小系统板跟EEPROM模块连接:
板子G----模块GND
板子3.3–模块VCC
板子PB10—模块SCL
板子PB11—模块SDA

在这里插入图片描述
打开STM32CubeMX软件,新建工程
在这里插入图片描述
Part Number处输入STM32F103C8,再双击就创建新的工程
在这里插入图片描述
配置下载口引脚
在这里插入图片描述
配置外部晶振引脚
在这里插入图片描述
配置系统主频
在这里插入图片描述
配置工程文件名,保存路径,KEIL5工程输出方式
在这里插入图片描述
生成工程
在这里插入图片描述
用Keil5打开工程
在这里插入图片描述
添加代码
在这里插入图片描述
在这里插入图片描述
主要代码

int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();//8M外部晶振,系统主频72M/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();/* USER CODE BEGIN 2 */EE_IIC_Init();//管脚初始化EE_EE_IIC_SendByteToSlave(0xA0,0x00,0x55);//0地址写入0x55HAL_Delay(10);//等待10msEE_IIC_ReadByteFromSlave(0xA0,0x00,&EEDATA);//从0地址读取内容存储到变量/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}#include "main.h"
#define	EE_ADDR 0xa0		
#define EE_SCL_PIN  GPIO_PIN_10   //模拟IIC的SCL信号  1.修改引脚即可修改IIC接口
#define EE_SDA_PIN  GPIO_PIN_11   //模拟IIC的SDA信号void EE_SDA_IN(void) 	//配置成输入  {  GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = GPIO_PIN_11;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
} 
void EE_SDA_OUT(void)//配置成输出
{GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = GPIO_PIN_11;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);}void EE_SCK_OUT(void) //配置成输出
{GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = GPIO_PIN_10;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}#define EE_IIC_SCL(val)         HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10,val)                   //SCL      2.修改引脚即可修改IIC接口        
#define EE_IIC_SDA(val)         HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11,val)                    //SDA	unsigned char EE_READ_SDA(void)
{
return HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11);
}	/******************************************************************************
*函  数:void EE_IIC_Delay(void)
*功 能:IIC延时
*参  数:无
*返回值:无
*备  注: 移植时只需要将EE_IIC_Delay()换成自己的延时即可
*******************************************************************************/	
void EE_IIC_Delay(uint8_t us)
{for(int i = 0; i < 20; i++)    {__asm("NOP");//core bus 160M  情况下大概IIC速率 400K}}
/******************************************************************************
*函  数:void IIC_Init(void)
*功 能:IIC初始化
*参  数:无
*返回值:无
*备  注:无
*******************************************************************************/void EE_IIC_Init(void)
{			__HAL_RCC_GPIOB_CLK_ENABLE();EE_SCK_OUT();EE_SDA_OUT();EE_IIC_SCL(1);EE_IIC_SDA(1);}void EE_IIC_Start(void)
{EE_SDA_OUT(); //sda线输出 EE_IIC_SDA(1);	EE_IIC_SCL(1);EE_IIC_Delay(4);EE_IIC_SDA(0); //START:when CLK is high,DATA change form high to low EE_IIC_Delay(4);EE_IIC_SCL(0); //钳住I2C总线,准备发送或接收数据 
}void EE_IIC_Stop(void)
{EE_SDA_OUT(); //sda线输出EE_IIC_SCL(0);EE_IIC_SDA(0); //STOP:when CLK is high DATA change form low to highEE_IIC_Delay(4);EE_IIC_SCL(1); EE_IIC_SDA(1); //发送I2C总线结束信号EE_IIC_Delay(4);							   	
}uint8_t EE_IIC_WaitAck(void)
{uint8_t ucErrTime=0;EE_SDA_IN(); //SDA设置为输入  (从机给一个低电平做为应答) EE_IIC_SDA(1);EE_IIC_Delay(1);	   EE_IIC_SCL(1);EE_IIC_Delay(1);;	 while(EE_READ_SDA()){ucErrTime++;if(ucErrTime>250){EE_IIC_Stop();return 1;}}EE_IIC_SCL(0); //时钟输出0 	   return 0;  
} void EE_IIC_Ack(void)
{EE_IIC_SCL(0);EE_SDA_OUT();EE_IIC_SDA(0);EE_IIC_Delay(1);EE_IIC_SCL(1);EE_IIC_Delay(2);EE_IIC_SCL(0);
}void EE_IIC_NAck(void)
{EE_IIC_SCL(0);EE_SDA_OUT();EE_IIC_SDA(1);EE_IIC_Delay(1);EE_IIC_SCL(1);EE_IIC_Delay(1);EE_IIC_SCL(0);
}					 				     void EE_IIC_SendByte(uint8_t data)
{                        uint8_t t;   EE_SDA_OUT(); 	    EE_IIC_SCL(0); //拉低时钟开始数据传输for(t=0;t<8;t++){              EE_IIC_SDA((data&0x80)>>7);EE_IIC_Delay(1);			EE_IIC_SCL(1);data<<=1;EE_IIC_Delay(1);EE_IIC_SCL(0);	   }EE_IIC_Delay(1);
} 	 uint8_t EE_IIC_ReadByte(uint8_t ack)
{uint8_t i,receive=0;EE_SDA_IN(); //SDA设置为输入模式 等待接收从机返回数据for(i=0;i<8;i++ ){EE_IIC_SCL(0); EE_IIC_Delay(1);EE_IIC_SCL(1);receive<<=1;if(EE_READ_SDA())receive++; //从机发送的电平EE_IIC_Delay(1); }					 if(ack)EE_IIC_Ack(); //发送ACK elseEE_IIC_NAck(); //发送nACK  return receive;
}uint8_t EE_IIC_ReadByteFromSlave(uint8_t I2C_Addr,uint8_t reg,uint8_t *buf)
{EE_IIC_Start();	EE_IIC_SendByte(I2C_Addr);	 //发送从机地址if(EE_IIC_WaitAck()) //如果从机未应答则数据发送失败{EE_IIC_Stop();return 1;}EE_IIC_SendByte(reg); //发送寄存器地址EE_IIC_WaitAck();	  EE_IIC_Start();EE_IIC_SendByte(I2C_Addr+1); //进入接收模式			   EE_IIC_WaitAck();*buf=EE_IIC_ReadByte(0);	   EE_IIC_Stop(); //产生一个停止条件return 0;
}uint8_t EE_EE_IIC_SendByteToSlave(uint8_t I2C_Addr,uint8_t reg,uint8_t data)
{EE_IIC_Start();EE_IIC_SendByte(I2C_Addr); //发送从机地址if(EE_IIC_WaitAck()){EE_IIC_Stop();return 1; //从机地址写入失败}EE_IIC_SendByte(reg); //发送寄存器地址EE_IIC_WaitAck();	  EE_IIC_SendByte(data); if(EE_IIC_WaitAck()){EE_IIC_Stop(); return 1; //数据写入失败}EE_IIC_Stop(); //产生一个停止条件return 0;
}

五.CubeMX工程源代码下载

链接:https://pan.baidu.com/s/1MMYww6IgUNa3wPaN-pWqdw
提取码:d39f
如果链接失效,可以联系博主给最新链接

程序下载下来之后解压就行

六.讲解视频链接地址

IIC总线讲解

七.小结

学会使用模拟IIC,能适应各种平台,不管是STM32的单片机,还是其他牌子的单片机,都能很快实现对EEPROM等IIC总线的设备进行数据读写。

相关文章:

零基础STM32单片机编程入门(九)IIC总线详解及EEPROM实战含源码视频

文章目录 一.概要二.IIC总线基本概念1.总体特征2.通讯流程 三.EEPROM介绍1.M24C08基本介绍2.向M24C08写一个字节时序图3.从M24C08读一个字节时序图 四.GPIO模拟IIC驱动M24C08读写五.CubeMX工程源代码下载六.讲解视频链接地址七.小结 一.概要 IIC(Inter&#xff0d;Integrated …...

数据库的操作

【一】库的增删改查 【0】导入数据文件 source D:\bjpowernode.sql 【1】创建数据库 语法&#xff1a; create database [if not exists] 数据库名 [character set 编码字符集]; create databases db1; # 设置库的默认编码 create databases db1 charsetgbk; 【2】查看数据…...

常见的认证方式

认证机制是一种用户确定用户身份或者权限的安全措施&#xff0c;比如用来验证某个用户是否有权限访问一个资源&#xff0c;如果认证通过&#xff0c;用户就可以成功访问&#xff0c;反之则会访问失败 常见的认证方式有四种&#xff0c;分别是 Basic、Digest、OAuth 和 Bearer …...

DolphinScheduler部署安装or基础介绍(一)

DolphinScheduler概述 Apache DolphinScheduler是一个分布式、易扩展的可视化DAG工作流任务调度平台。致力于解决数据处理流程中错综复杂的依赖关系&#xff0c;使调度系统在数据处理流程中开箱即用 DolphinScheduler核心架构 DolphinScheduler的主要角色如下&#xff1a; Ma…...

Failed building wheel for pyaudio Running setup.py clean for pyaudio

从错误信息来看&#xff0c;问题出在 pyaudio 包的构建过程中。具体来说&#xff0c;缺少 portaudio.h 头文件&#xff0c;这通常是因为系统上没有安装 portaudio 库。 以下是解决此问题的步骤&#xff1a; 安装系统依赖&#xff1a; 在大多数基于 Debian 的系统&#xff08;如…...

【ARMv8/v9 GIC- 700 系列 1 -- Programmers model for GIC-700】

请阅读【ARM GICv3/v4 实战学习 】 文章目录 GIC-700 Programmers model寄存器实现和访问模式接口宽度和数据格式访问类型安全寄存器访问地址映射和页面GIC-700 Register map pagesSummaryGIC-700 Programmers model GIC-700是ARM的一种通用中断控制器,它遵循GICv3和GICv4架构…...

exel带单位求和,统计元素个数

如果exel表格中&#xff0c;如果数据有单位&#xff0c;无法直接用 自动求和 直接求和。如下图所示&#xff0c;求和结果为0&#xff0c;显然不是我们想要的。 用下面的公式求和&#xff0c;单位不是“个”的时候记得替换单位。统计范围不是“C1:C7”也记得换一下啊&#xff01…...

JavaScript里方括号[]的使用

我们知道可用方括号来表示数组或者JSON对象的属性值&#xff0c;其实在特定场合&#xff0c;方括号还有妙用的。 比如我有数据源是一组JSON&#xff0c;其中有一个属性是时间字符串&#xff0c;我想对时间的小时、星期、日、月分别进行处理。每条JSON都各自生成一条新的JSON&am…...

俯卧撑计数器(Python)

通过 MediaPipe 检测人体姿态&#xff0c;计算俯卧撑角度和计数&#xff0c;并在图像上进行可视化展示 需要有cv2库和mediapipe库 mediapipe库&#xff1a; MediaPipe是Google开源的机器学习框架&#xff0c;用于构建实时音频、视频和多媒体处理应用程序。它提供了一组预训练的…...

UVA12342 Tax Calculator 题解

题目传送门 题目大意 题目描述 某国所得税计算十分复杂。该国政府指定你制作一个自动计算所得税的程序。以下是该国计算所得税的规则&#xff1a; 所得税免征额为 180000 180000 180000 元。应纳税额中不超过 300000 300000 300000 元的所得额&#xff0c;按 10 % 10\% …...

WebKit中Websockets的全面支持:实现高效实时通信

WebKit中Websockets的全面支持&#xff1a;实现高效实时通信 Websockets是一种网络通信协议&#xff0c;它允许在单个TCP连接上进行全双工通信&#xff0c;从而实现服务器与客户端之间的实时数据交换。WebKit作为许多流行浏览器的底层引擎&#xff0c;对Websockets提供了全面的…...

微信小程序的智慧物流平台-计算机毕业设计源码49796

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3研究方法 1.4开发技术 1.4.1 微信开发者工具 1.4.2 Node.JS框架 1.4.3 MySQL数据库 1.5论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 用户登录流程 2.2.2 数据删除流程 2.3 系统功能分…...

旅游 | 西岳华山

得到了再失去&#xff0c; 总比从来没有得到更伤人。 ——胡赛尼《追风筝的人》 目录 旅游 | 西岳华山00 | 旅游导图01 | 旅游路线1.1 北上西下&#xff08;徒步&#xff09;1.2 北上西下&#xff08;索道&#xff09;1.3 西上北下&#xff08;索道&#xff09;1.4 西上西下&am…...

如何优化Java中的内存占用?

如何优化Java中的内存占用&#xff1f; 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 1. 理解Java内存管理机制 Java的内存管理主要由JVM负责&#xff0c;开发人员在编写代码时需要注意如何有效地…...

2024这三家上海闵行装修公司,值得一看

在繁华的上海闵行区&#xff0c;随着居民对生活品质追求的提升&#xff0c;越来越多人开始重视居住环境的打造。然而&#xff0c;面对众多装修公司的选择&#xff0c;不少消费者往往感到迷茫和困惑。今天&#xff0c;我们就来揭晓闵行区口碑与实力兼备的三家装修公司。 1、首先…...

K8S学习教程(三):在PetaExpress KubeSphere 容器部署 Wiki 系统 wiki.js 并启用中文全文检索

背景 wiki.js 是非常优秀的开源 Wiki 系统&#xff0c;尽管在与 xwiki 功能相比 &#xff0c;还不算完善&#xff0c;但也在不断进步。 常用的功能还是比较实用的&#xff0c;如&#xff1a;Wiki 写 作、分享、权限管理功能还是非常实用的&#xff0c;UI 设计非常的漂亮&#x…...

服务器该如何抵御CC攻击

CC攻击也是分布式拒绝服务攻击的一种类型&#xff0c;同时CC攻击也属于网络流量攻击&#xff0c;但是CC攻击主要是用来攻击网站页面的&#xff0c;向着目标网络服务器发送一些请求&#xff0c;以此来消耗目标网络服务器的资源&#xff0c;导致目标服务器无法响应正常请求&#…...

关于centos7自带的nginx1.20.1开启https后,XP系统的IE6和IE8无法显示网页的问题

CentOS7自带的nginx-1.20.1是支持HTTP/2和TLS1.3的。 软件包名称&#xff1a;nginx-1.20.1-10.el7.x86_64 CentOS7默认开启了HTTP/2&#xff0c;但没有开启TLS1.3&#xff0c;以及IE6和IE8的https访问。 开启方法&#xff1a; ssl_ciphers HIGH:!aNULL:!MD5;改为ssl_ciphers…...

Zotero软件翻译插件Translate for Zotero的API接入方法--百度垂直领域翻译

首先注册通用文本翻译API的token:百度翻译开放平台 (baidu.com)&#xff08;可以免费认证 升级为高级版&#xff09; 之后点击管理控制台&#xff0c;选择总览右侧最下方可以看到个人的id和密码 点击文档与支持&#xff0c; 在这里可以选择领域。 支持传入值描述支持语言方向…...

python实现接口自动化

代码实现自动化相关理论 代码编写脚本和工具实现脚本区别是啥? 代码&#xff1a; 优点&#xff1a;代码灵活方便缺点&#xff1a;学习成本高 工具&#xff1a; 优点&#xff1a;易上手缺点&#xff1a;灵活度低&#xff0c;有局限性。 总结&#xff1a; 功能脚本&#xff1a;工…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙

Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...