news 2026/6/1 17:05:17

Arduino贪吃蛇实战:从状态机到I2C LCD的嵌入式开发全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Arduino贪吃蛇实战:从状态机到I2C LCD的嵌入式开发全解析

1. 项目概述与核心思路

用一块小小的Arduino Uno开发板和一块16x2的LCD显示屏,就能复刻出我们童年记忆里的贪吃蛇游戏,这听起来是不是有点酷?作为一个玩了十几年嵌入式开发的老鸟,我始终觉得,把复杂的系统逻辑塞进资源极其有限的微控制器里,并且还要和物理世界进行实时、可靠的交互,是检验一个开发者功力的绝佳方式。贪吃蛇这个项目,麻雀虽小,五脏俱全,它完美地融合了状态机管理、实时输入处理、图形化显示以及内存优化这几个嵌入式开发的核心课题。

这个项目的核心目标很明确:在Arduino Uno这块仅有2KB SRAM和32KB Flash的8位AVR微控制器上,实现一个可玩性良好的贪吃蛇游戏。整个系统的骨架由几个关键部分搭建:Arduino Uno作为大脑,负责执行游戏逻辑;16x2 LCD(通过I2C模块驱动)作为眼睛,用来显示游戏画面;两个轻触开关作为双手,接收玩家的转向指令。代码层面,我们需要解决几个核心问题:如何在点阵化的LCD上绘制蛇身和食物?如何让蛇根据玩家的操作流畅地移动和转向?如何检测碰撞(撞墙或撞到自己)并判定游戏结束?以及,如何确保简陋的物理按键输入不会因为抖动而产生误操作?

我选择这个方案进行分享,是因为它避开了复杂的图形库和操作系统,直击嵌入式裸机编程的本质。通过这个项目,你不仅能收获一个可以实际把玩的硬件作品,更能深入理解事件驱动编程、有限状态机(FSM)设计、以及底层硬件通信协议(如I2C)的实际应用。无论你是刚接触Arduino的新手,还是想深化对微控制器编程理解的爱好者,跟着走完这一趟,肯定会有实实在在的收获。

2. 硬件选型与电路连接解析

2.1 核心硬件清单与选型理由

工欲善其事,必先利其器。我们先来清点一下需要的所有硬件,并聊聊为什么选它们。

  1. Arduino Uno R3(或兼容板):这是项目的控制核心。选择Uno是因为它普及度极高,社区资源丰富,其ATmega328P芯片的性能对于这个游戏绰绰有余。任何基于ATmega328P的兼容板(如DFRobot的UNO R3)都可以完美替代。注意:如果你用的是非常早期的Uno(基于ATmega8或ATmega168),Flash空间可能紧张,但本项目代码经优化后,在328P上运行空间充裕。

  2. 16x2字符型LCD显示屏:这是我们的显示设备。16x2表示每行可以显示16个字符,共2行。字符型LCD内部有固化的字库,我们无法直接控制每一个像素点来画图,这恰恰是本次项目的第一个技术挑战——我们需要用字符“拼”出图形。市面上常见的型号是HD44780或兼容其驱动协议的屏幕。

  3. I2C LCD适配器模块:这是一个至关重要的“转接板”。原生LCD通常需要连接6-10根线(数据线、控制线、背光线)到Arduino,会占用大量宝贵的I/O口。I2C模块将并行通信转换为串行的I2C通信,只需要连接4根线(VCC, GND, SDA, SCL),极大地简化了布线,也释放了I/O资源。模块上通常有一个可调电位器,用于调节屏幕对比度。

  4. 面包板与杜邦线:用于快速、无焊接地搭建电路原型。建议准备公对公和公对母杜邦线若干,方便连接。

  5. 轻触开关(按键) x 2:用于控制蛇的转向。我推荐使用标准的6x6mm四脚轻触开关。选择两个是因为我们只需要左右转向(具体逻辑后文详述),这种开关手感清晰,寿命长。

  6. 10kΩ电阻 x 2:这是为按键准备的上拉电阻。在嵌入式电路中,未按下的按键引脚处于“悬空”状态,电平不确定,极易引入噪声。通过一个电阻将该引脚连接到VCC(5V),可以确保其在未按下时稳定在高电平(逻辑1),按下时才被拉低到GND(逻辑0),这种设计称为“上拉”,是数字输入电路的标配。

重要提示:购买I2C模块时,务必注意其I2C地址。最常见的是0x27,但也有0x3F等。项目代码中默认使用0x27,如果你的屏幕不亮,第一件事就是用I2C扫描程序确认地址。

2.2 电路连接详解与原理图

连接电路是硬件项目的第一步,也是排查后续软件问题的基石。请务必对照下图和文字描述,仔细连接每一根线。

整体连接思路如下

  • 电源先行:首先为所有模块建立稳定的5V和GND通路。将Arduino的5VGND引脚连接到面包板的电源轨。
  • I2C LCD连接:这是最简洁的部分。将I2C模块的VCCGND分别接面包板电源轨的5VGNDSDA接Arduino的A4引脚(在Uno上,A4同时也是I2C的SDA线),SCL接Arduino的A5引脚(I2C的SCL线)。
  • 按键电路搭建:这是输入部分的关键。两个按键采用相同的接法。以左侧按键为例:按键一脚接Arduino的数字引脚6,同时通过一个10kΩ上拉电阻连接到5V;按键对角脚(或同排另一脚)连接到GND。这样,未按下时,引脚6被电阻拉高到5V(读为HIGH);按下时,引脚6直接连通GND,被拉低到0V(读为LOW)。右侧按键同理,连接到数字引脚7

下面是一个清晰的接线表格,你可以逐一核对:

元件/模块引脚/端口连接到 Arduino Uno 引脚说明
I2C LCD 模块VCC5V电源正极
GNDGND电源地
SDAA4I2C 数据线
SCLA5I2C 时钟线
左侧按键一脚数字引脚 6 (D6)信号输入
同一脚通过10kΩ电阻接 5V上拉电阻
对角脚GND按下时接地
右侧按键一脚数字引脚 7 (D7)信号输入
同一脚通过10kΩ电阻接 5V上拉电阻
对角脚GND按下时接地

实操心得:连接上拉电阻时,一个常见的错误是将电阻接在了按键和Arduino引脚之间。正确接法是:电阻一端接5V,另一端同时接按键引脚和Arduino输入引脚。这样电流路径才是:5V -> 电阻 -> (引脚/按键)。用万用表测量,不按按键时D6/D7电压应为接近5V,按下时应接近0V。

3. 软件环境配置与核心库剖析

3.1 开发环境与库安装

软件部分我们使用Arduino官方的IDE。确保你安装的是较新版本(1.8.x或2.x均可)。接下来是关键一步:安装驱动LCD的库。

在Arduino IDE中,点击工具->管理库...,打开库管理器。在搜索框中输入“LiquidCrystal I2C”,你会找到多个相关库。这里有一个关键选择:请寻找由“Frank de Brabander”维护的版本。这个库历史悠久,稳定可靠,且被广泛使用。安装它。

安装完成后,你可以在代码中通过#include <LiquidCrystal_I2C.h>来调用它。这个库封装了通过I2C协议与HD44780液晶控制器通信的所有底层细节,让我们可以用几句简单的命令(如lcd.print()lcd.setCursor())来控制屏幕。

3.2 核心代码逻辑深度解析

提供的源代码是一个完整的、可直接运行的贪吃蛇游戏。我们不要只停留在“复制-粘贴-运行”,而要深入理解每一段代码背后的设计思想。下面我将代码拆解成几个核心模块进行解读。

3.2.1 显示系统的“魔法”:自定义字符与图形化如何在字符LCD上显示一条蛇和一个苹果?答案是自定义字符(Custom Character)。HD44780控制器允许用户自定义8个5x8像素的字符。我们的代码巧妙地利用了这一点。

byte block[3] = { B01110, B01110, B01110 }; // 蛇身方块 byte apple[3] = { B00100, B01010, B00100 }; // 苹果

这里定义了两个图案的顶部3行数据(每个字节的5个有效位代表一行中的5个像素点,1亮0灭)。block是一个实心小方块,apple则是一个菱形图案。在graphic_generate_characters()函数中,代码动态组合了“空白”、“方块”、“苹果”这三种元素在字符的上下两部分,生成了8个自定义字符,涵盖了所有可能的上下组合情况(如上空白下苹果、上苹果下方块等)。这本质上是一种软件层面的图形帧缓冲(Framebuffer)压缩技术,将16x2的字符显示区域,映射成了一个更精细的16x4的逻辑像素网格(因为每个字符高度是8点,我们用了上下各3行,中间空2行作为间隔),从而实现了基础的图形渲染。

3.2.2 游戏世界的建模:数据结构设计游戏中的所有实体都需要用数据来表示。

struct Pos { uint8_t x=0, y=0; }; // 坐标结构体 struct Pos snakePosHistory[GRAPHIC_HEIGHT*GRAPHIC_WIDTH]; // 蛇身坐标历史 size_t snakeLength = 0; // 蛇当前长度 struct Pos applePos; // 苹果坐标

snakePosHistory数组是一个环形队列(这里用顺序存储模拟)的思想。数组的第一个元素(索引0)永远代表蛇头,最新的位置。当蛇移动时,新的头部位置存入[0],旧的[0][snakeLength-1]依次向后移动一位,最后一个元素(蛇尾)被丢弃。如果吃到了苹果,蛇长snakeLength加1,尾部就不丢弃,从而实现生长。这种设计避免了在内存中频繁移动大量数据,效率很高。

3.2.3 控制与交互的灵魂:按键消抖(Debounce)物理按键在闭合和断开的瞬间,由于机械触点的弹性,会产生一系列快速的、不稳定的电平跳变,称为“抖动”。如果不处理,一次按键可能会被误读为多次按下。

#define DEBOUNCE_DURATION 20 // 消抖时间20毫秒 bool debounce_activate_edge(unsigned long* debounceStart) { if(*debounceStart == ULONG_MAX) return false; else if(*debounceStart == 0) { *debounceStart = millis(); } else if(millis()-*debounceStart > DEBOUNCE_DURATION) { *debounceStart = ULONG_MAX; return true; } return false; }

代码实现了边沿检测消抖。当首次检测到按键按下(电平变低)时,记录当前时间戳。在接下来的DEBOUNCE_DURATION(20ms)内,即使检测到电平变化也视为抖动,不予响应。只有当按键低电平稳定持续超过20ms后,函数才返回true,表示一次有效的按键事件被确认。ULONG_MAX用作一个状态标志,表示该按键已触发并等待释放,防止在长按期间重复触发。这是嵌入式开发中处理数字输入的黄金标准做法

3.2.4 游戏逻辑的心脏:状态机与主循环整个游戏由一个有限状态机(FSM)驱动,状态包括:GAME_MENU(菜单/开始界面)、GAME_PLAY(游戏中)、GAME_LOSE(失败)、GAME_WIN(胜利)。

void loop() { // 1. 扫描按键输入(带消抖) if(digitalRead(BUTTON_LEFT)==HIGH) { if(debounce_activate_edge(&debounceCounterButtonLeft) && !thisFrameControlUpdated) { // 处理左键按下事件... } } // 2. 定时更新游戏逻辑 if(millis()-lastGameUpdateTick > gameUpdateInterval) { game_calculate_logic(); // 计算移动、碰撞、吃苹果 game_calculate_display(); // 更新屏幕显示 lastGameUpdateTick = millis(); thisFrameControlUpdated = false; // 重置本帧控制更新标志 } }

loop()函数是Arduino程序的心脏,它不断循环执行。其工作流非常经典:

  1. 输入采样:检查两个按键,经过消抖处理后,更新蛇的方向或开始游戏。thisFrameControlUpdated标志确保在一帧游戏更新周期内只响应一次转向输入,防止过于灵敏。
  2. 定时更新:根据gameUpdateInterval(初始1000ms,随长度增加而减少)定时调用游戏逻辑和显示更新。这是游戏“心跳”的来源,所有移动、碰撞检测都在game_calculate_logic()中完成。
  3. 转向逻辑:代码中一个精妙的设计是,两个按键并非直接对应“左转”和“右转”。它们被定义为“转向键”,其功能是相对于蛇当前前进方向,进行逆时针(左键)或顺时针(右键)90度旋转。这用switch语句实现,使得无论蛇朝哪个方向走,按键操作都符合直觉。

4. 完整项目实现与代码逐行精讲

4.1 工程建立与代码集成

打开Arduino IDE,新建一个项目。将提供的完整代码复制粘贴到新建的.ino文件中。在上传之前,我们必须根据你的硬件情况,检查并修改两个关键配置。

  1. I2C地址确认:在代码开头,找到LiquidCrystal_I2C lcd(0x27, 16, 2);这一行。如果你的I2C模块地址不是0x27,请修改为正确的地址(例如0x3F)。如果你不确定地址,可以先用Arduino IDE自带的示例文件->示例->Wire->i2c_scanner来扫描。

  2. 引脚定义检查:确认#define BUTTON_LEFT 6#define BUTTON_RIGHT 7与你实际连接的Arduino数字引脚一致。

4.2 核心函数流程剖析

让我们深入几个最核心的函数,看看游戏是如何“活”起来的。

game_calculate_logic()– 游戏世界的物理法则这个函数在每一次游戏“心跳”(定时器触发)时被调用,是游戏逻辑的核心。

void game_calculate_logic() { // 1. 移动蛇身:从尾部向前遍历,每个部位移动到前一个部位的位置 for(size_t i=snakeLength; i>=1; i--){ snakePosHistory[i] = snakePosHistory[i-1]; } // 2. 计算新的头部位置(基于当前方向) snakePosHistory[0] = snakePosHistory[1]; // 先复制颈部位置 switch(snakeDirection){ case SNAKE_LEFT: snakePosHistory[0].x--; break; ... // 其他方向 } // 3. 碰撞检测:墙壁 if(snakePosHistory[0].x<0 || snakePosHistory[0].x>=GRAPHIC_WIDTH || ...){ gameState = GAME_LOSE; return; } // 4. 碰撞检测:自身 for(size_t i=1; i<snakeLength; i++){ if(头部坐标 == 身体某部分坐标){ gameState = GAME_LOSE; return; } } // 5. 吃苹果检测 if(头部坐标 == 苹果坐标){ snakeLength++; // 长度增加 gameUpdateInterval = gameUpdateInterval * 9 / 10; // 速度加快10% if(蛇长达到最大值) gameState = GAME_WIN; else game_new_apple_pos(); // 在新位置生成苹果 } }

这个函数的执行顺序至关重要。它先移动身体,再计算头部,然后进行碰撞检测。这里有一个经典陷阱:如果先检测碰撞再移动,逻辑会变得复杂。现在的顺序是符合“先移动,再判断新位置是否合法”的自然逻辑。

game_calculate_display()– 将数据世界可视化逻辑计算完毕后,这个函数负责将内存中的坐标数据“绘制”到屏幕上。

void game_calculate_display() { graphic_clear(); // 清空图形缓冲区 if(gameState == GAME_PLAY) { // 1. 将蛇身每个坐标点添加到图形缓冲区,标记为“方块”元素 for(size_t i=0; i<snakeLength; i++) graphic_add_item(snakePosHistory[i].x, snakePosHistory[i].y, GRAPHIC_ITEM_A); // 2. 将苹果坐标添加到缓冲区,标记为“苹果”元素 graphic_add_item(applePos.x, applePos.y, GRAPHIC_ITEM_B); // 3. 将缓冲区内容刷新到LCD graphic_flush(); } else if (gameState == GAME_LOSE) { // 显示游戏结束画面 lcd.clear(); lcd.setCursor(0,0); lcd.print(" You lose!"); lcd.print("Length: "); lcd.print(snakeLength); } // ... 其他状态 }

graphic_add_item函数是连接逻辑坐标和物理显示的关键。它根据坐标(x,y),计算出该点位于哪个字符的哪个半部分(上半部还是下半部),以及在该字符的位图中的具体位置,然后将对应的图案标记(GRAPHIC_ITEM_AB)写入一个叫作graphicRam的二维数组中。graphic_flush()函数则遍历这个数组,根据每个字符位置上下两部分应该显示什么图案,查找或生成对应的自定义字符编码,并调用lcd.write()将其输出到屏幕的正确位置。这个过程是软件渲染管线的极简体现。

4.3 编译、上传与首次运行

确认代码无误后,在Arduino IDE中选择正确的板卡类型(Arduino Uno)和端口,点击上传按钮。上传成功后,Arduino会自动复位运行。

首次上电,LCD屏幕应该会亮起背光,并显示“Snake Game”标题。此时按下任意一个按键(左或右),游戏就会初始化并开始。你会看到一条由4个方块组成的蛇出现在屏幕左侧,一个苹果图案随机出现在其他地方。使用两个按键控制蛇的转向(左键逆时针转,右键顺时针转),去吃掉苹果。每吃一个,蛇身增长一节,移动速度也会略微加快。

5. 调试、优化与深度扩展

5.1 常见问题排查指南(FAQ)

即使完全按照步骤操作,你也可能会遇到一些问题。别担心,这是学习过程的一部分。下表列出了最常见的问题及其解决方法:

现象可能原因排查步骤与解决方案
LCD屏幕无任何显示1. 电源未接通或接反。
2. I2C地址错误。
3. 对比度调节不当。
1. 用万用表检查VCC和GND间电压是否为5V。
2. 运行I2C扫描程序确认模块地址,并修改代码中的lcd(0x27,...)
3. 调节I2C模块上的电位器,缓慢旋转直到字符显现。
屏幕显示乱码或黑色方块1. 初始化顺序或通信错误。
2. 对比度极端不合适。
1. 确保lcd.init()lcd.backlight()setup()中成功执行。尝试在setup()开头加一小段delay(500),给LCD上电复位留出时间。
2. 仔细调节对比度电位器。
按键无反应或反应混乱1. 上拉电阻未接或接错。
2. 引脚定义错误。
3. 按键内部接触不良。
1.重点检查:用万用表测量按键未按下时,Arduino引脚(如D6)对GND的电压,应为~5V。如果是0V或飘忽不定,说明上拉电阻未起作用。
2. 核对代码#define与实物连接是否一致。
3. 更换一个按键试试。
蛇移动卡顿或不流畅1.gameUpdateInterval初始值太大。
2.loop()中有阻塞操作(如长时间的delay)。
3. 图形刷新逻辑过于耗时。
1. 尝试减小gameUpdateInterval的初始值(如改为800或500)。
2. 确保代码中没有除消抖delay(1)外的不必要延迟。
3. 本项目图形刷新已经优化,通常不是主因。
吃苹果后游戏异常或复位1. 蛇长数组snakePosHistory溢出。
2. 随机数生成苹果位置时陷入死循环。
1. 数组大小是GRAPHIC_HEIGHT*GRAPHIC_WIDTH(64),理论上蛇长不可能超过它。但如果逻辑错误导致snakeLength超过64,就会溢出。添加保护性判断:if(snakeLength < sizeof(...)) snakeLength++;
2.game_new_apple_pos()中的do...while循环在蛇身很长时可能效率低,但不会死循环,因为总有空位。

调试利器——串口监视器:当你遇到逻辑问题时,善用Serial.begin(9600)Serial.println()在关键位置打印变量值(如蛇头坐标、游戏状态、按键读数),这是洞察单片机内部运行状态最直接的方法。

5.2 性能优化与代码改进建议

当前的代码已经可以稳定运行,但作为一个学习项目,我们还可以从几个方面思考如何让它变得更好:

  1. 使用constPROGMEM节省RAMblockapple这两个字节数组目前存储在SRAM中。我们可以将其声明为const byte block[] PROGMEM = {...};,并将其存储在Flash(程序存储器)中,使用pgm_read_byte()函数来读取。对于ATmega328P只有2KB SRAM的芯片,养成这个习惯对大型项目很有帮助。

  2. 更优雅的转向控制:当前的转向逻辑是“一帧内只允许一次转向”,这防止了快速连按导致蛇头直接掉头撞死自己(这是贪吃蛇的经典规则)。但代码实现上可以更简洁。可以考虑用一个变量pendingDirection来存储按键输入请求的方向,然后在game_calculate_logic()移动蛇头之前,检查新方向是否与当前方向相反(即180度掉头),如果是则忽略,否则更新snakeDirection = pendingDirection。这样逻辑更清晰。

  3. 增加游戏功能

    • 计分系统:在屏幕第二行实时显示当前长度(分数)。
    • 难度选择:在GAME_MENU状态,通过按键选择不同的初始速度。
    • 音效:增加一个无源蜂鸣器,在吃苹果、撞墙时发出不同频率的提示音。
    • 最高分记录:利用ATmega328P内部的EEPROM,保存历史最高分,断电不丢失。
  4. 改用状态机库:如果游戏状态(菜单、游戏、结束)变得更加复杂,手动管理gameState和一堆switch语句会变得混乱。可以考虑使用简单的状态机库(如FiniteStateMachine),让状态转换和每个状态下的行为定义更加模块化。

5.3 项目扩展思路

这个基础框架的潜力远不止一个贪吃蛇。你可以把它看作一个基于Arduino和字符LCD的微型游戏引擎原型。掌握了它的精髓后,可以尝试:

  1. 开发新游戏:比如打砖块(Pong)、简单的飞行射击游戏。你需要设计新的游戏对象(球拍、球、子弹、敌机)、碰撞检测逻辑和得分规则。
  2. 升级显示设备:将字符LCD换成图形LCD(如128x64的OLED)或TFT屏幕。虽然驱动更复杂,但你将获得真正的像素级控制能力,游戏画面会得到质的飞跃。
  3. 改变输入方式:用摇杆(Joystick)替代按键,操作会更流畅;或者加入加速度计,制作一个通过倾斜来控制蛇方向的体感游戏。
  4. 联网与对战:增加一个蓝牙模块(如HC-05)或Wi-Fi模块(如ESP-01S),让两块Arduino之间可以传输蛇的位置数据,实现双人对战或协作模式。

这个项目的价值,不仅在于最终那个闪烁的小蛇,更在于你从电路连接、库安装、代码调试到功能扩展的完整实践过程中,对嵌入式系统开发建立起的直观而深刻的理解。每一次解决问题的过程,都是对你硬件思维和软件调试能力的一次锤炼。希望你在复现这个项目时,能享受到这种从无到有、让代码在物理世界中“活”过来的乐趣。如果在制作过程中有任何新的发现或有趣的改动,也欢迎分享出来,社区的交流往往能碰撞出更棒的火花。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/1 17:03:11

基于Adafruit Circuit Playground的LED星座电路:从并联原理到导电缝纫线实践

1. 项目概述&#xff1a;从创意到电路&#xff0c;打造你的星座之光在电子制作和互动艺术领域&#xff0c;将抽象的创意转化为看得见、摸得着的物理装置&#xff0c;总是一件令人兴奋的事情。这次&#xff0c;我想分享一个结合了基础电子学、微控制器编程和一点艺术设计的项目&…

作者头像 李华
网站建设 2026/6/1 17:00:59

Notus-7B-v1-openmind性能基准测试:全面对比主流7B参数模型

Notus-7B-v1-openmind性能基准测试&#xff1a;全面对比主流7B参数模型 【免费下载链接】notus-7b-v1-openmind 项目地址: https://ai.gitcode.com/hf_mirrors/jeffding/notus-7b-v1-openmind Notus-7B-v1-openmind 是一款基于Zephyr-7B-β优化的7B参数对话模型&#x…

作者头像 李华
网站建设 2026/6/1 16:59:03

从零搭建H桥驱动电路:直流电机正反转控制原理与Proteus仿真实践

1. 项目概述与核心价值在机器人底盘、智能小车或者任何一个需要让轮子正反转的自动化项目里&#xff0c;控制直流电机的方向是一个绕不开的基础问题。很多初学者会直接想到用继电器或者两个电源来回切换&#xff0c;但这些方案要么体积大、速度慢&#xff0c;要么成本高、不实用…

作者头像 李华
网站建设 2026/6/1 16:57:42

如何三步永久保存你的微信聊天记忆:免费开源工具WeChatMsg终极指南

如何三步永久保存你的微信聊天记忆&#xff1a;免费开源工具WeChatMsg终极指南 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trend…

作者头像 李华
网站建设 2026/6/1 16:55:57

GIT修改用户名

在GIT中修改用户名可按以下步骤操作&#xff1a; 查看当前git的用户名&#xff0c;使用命令git config --list或git config user.name。修改git用户名&#xff0c;使用命令git config --global user.name "xxx&#xff08;新的用户名&#xff09;"&#xff0c;将其中…

作者头像 李华