装 Keil 这件事,说简单也简单,一路下一步就装完了;说麻烦也是真麻烦,尤其是你手上既有 STM32 项目,又要维护老一代 51 单片机的代码,两套工具链要塞进同一台电脑、同一个 IDE 外壳里,装反了顺序、选错了目录,后面编译和下载的报错能让你对着屏幕怀疑人生。我这些年给同事和学弟装过不下二十次开发环境,从早期的 Keil 4 一路到现在的 MDK 5.4x,踩过的坑基本都集中在三件事上:安装顺序、器件包、编译器与授权版本。这篇就把 Keil(MDK)STM32 和 51 版本的详细安装从头到尾讲透,包括目录怎么规划、TOOLS.INI 怎么改、STM32 器件包怎么装、调试时结构体变量为什么不显示、51 工程为什么链接不过、各类报错怎么定位。
不管你是刚拿到一块开发板、想点亮第一个 LED 的新手,还是准备给团队统一开发环境的老手,都能照着这套流程走一遍。文章里的每一步我都会说清楚"为什么这么做",因为环境这东西,照着点能装上,但只有理解了原理,出了问题才知道往哪个方向查。
1. 装之前先把两套工具链的关系捋清楚
1.1 MDK-ARM 和 C51 其实是两个"引擎"共用一套"外壳"
很多人第一次接触 Keil 会懵:为什么下载页面上一会儿是 MDK,一会儿是 C51,装完看起来又长得一模一样?这里必须先讲清楚结构。你双击打开的那个 µVision(进程名 UV4.exe),本质上只是一个图形界面外壳,真正干活的编译器是分开的:MDK-ARM 用的是 Arm 的编译器(老版本叫 armcc,新版本叫 armclang),面向 Cortex-M 内核的 STM32;C51 用的是面向 8051 内核的 C51 编译器,面向 AT89C51、STC89C52 这一类芯片。两套编译器各自有独立的器件数据库、启动代码、头文件目录和库文件,互相并不认识对方。
这带来一个很实际的后果:µVision 这个外壳是共用的,它每次启动都会去读一个叫 TOOLS.INI 的配置文件,从里面找到[ARM]和[C51]两个段落,才知道该去哪里调用对应的编译器。所以你装两套工具链的本质,不是装两个独立软件,而是让同一个外壳能同时认识两个引擎。理解了这一点,后面的顺序问题、共存问题、装反了怎么救,全部可以自己推导出来,而不是死记某个教程里的步骤。
顺带说一句,很多人以为"装哪个版本无所谓,反正都是 Keil",这是最大的误区。MDK 和 C51 的安装包是两条独立的产品线,版本号也各自演进,C51 长期停在 v9.60 附近,MDK 则一路涨到 5.4x。它们的安装程序都会往同一个根目录写文件、都会更新 TOOLS.INI、都会尝试注册 uVision 的关联,所以冲突就发生在"谁最后写配置"这件事上。
1.2 版本号里藏着的坑:AC5 和 AC6 的分水岭
选 MDK 版本的时候,有一个分界线必须知道:从 MDK 5.37 开始,安装包里不再自带 Arm Compiler 5(也就是 AC5 / armcc),默认只带 AC6(armclang)。这个变化对写新工程的人毫无影响,但对维护老工程的人就是灾难——很多十年前的 STM32 工程、网上下载的例程、公司留下的祖传代码,都是在 AC5 下编译的,你拿 5.4x 一打开,满屏的编译错误,就会以为是自己装错了。
这些报错里最常见的是error: unknown type name '__int64'、#include <stdio.h>找不到、内联汇编语法不兼容,或者干脆在链接阶段报一堆符号重定义。根因几乎都不是你装错了,而是编译器换了一代。两种处理方式:一是单独去下载安装 Arm Compiler 5,装完之后在工程的 Options for Target → Target 页把编译器版本手动切回 AC5;二是花时间把老工程迁到 AC6。前者五分钟搞定,后者可能要花两天,所以做项目的时候优先选前者。
反过来,如果你要跟别人对工程、要在多个人的电脑上编译同一份代码,版本不一致也会带来麻烦。我的习惯是在团队里固定一个大版本号,比如统一用 5.36 或者统一用 5.40,写进项目的 README 里。至于下载渠道,建议走官方站点拿正式安装包,不要随手拿来源不明的压缩包,环境工具这种东西一旦被改过,后面排查问题会成倍地难。
1.3 安装前的三件准备工作
第一件,规划好目录。这是整个安装流程里最省事也最容易忽略的一步。我推荐的结构是把两套工具链放在同一个根目录下,各占一个子目录:
C:\Keil_v5\ ├─ UV4\ # µVision 外壳,包含 UV4.exe、TOOLS.INI ├─ ARM\ # MDK-ARM 的编译器、器件包、库 └─ C51\ # C51 的编译器、头文件、库这种"一个根目录装两套"的结构,好处是所有配置集中在一处,备份和迁移都方便,重装系统后拷贝回来就能用。
第二件,确认安装路径里没有中文、没有空格。这一点是老生常谈,但每年还是有人栽。原因是编译器和链接器在调用外部工具(比如 fromelf、armlink)时会走命令行参数,路径里有中文或空格,某些环节的参数拼接会出问题,表现就是编译到一半忽然报"cannot open file"或者干脆卡死。同时也要看一眼你的 Windows 用户名是不是中文,因为%APPDATA%路径会跟着用户名走,器件包缓存默认就放在那里。如果用户名是中文,建议把包缓存目录改到纯英文路径下。
第三件,临时关掉杀毒软件和系统防护的实时监控。安装程序会往注册表和系统目录写东西、会装驱动(调试器的 USB 驱动),实时防护有时会把这类行为拦下来,表现是"安装程序运行到一半无响应"或者"驱动装上了但设备管理器里带感叹号"。装完再打开就行,不用长期关闭。
提示:安装过程中尽量用管理员权限运行安装包,尤其是最后一步装调试器驱动的时候。如果弹 UAC 提示,一律选"是",否则驱动可能装不完整。
2. 安装顺序怎么选:先 C51 再 MDK,还是反过来
2.1 推荐的合并安装法:一个根目录装两套
结论先给:先装 C51,再装 MDK,两个安装程序指向同一个根目录。这是目前最稳的顺序。
理由要从前面的原理推。C51 安装程序自带一个较低版本的 µVision 外壳,MDK 自带的 µVision 版本更高。如果你先装 MDK,再装 C51,C51 的安装程序不会"识趣地跳过"外壳文件,它会把自己那份 UV4 和相关文件覆盖上去,同时重写 TOOLS.INI,结果就是 MDK 的部分配置被冲掉。反过来,先装 C51 打底,再让版本更高的 MDK 覆盖外壳,MDK 安装程序在检测到目录里已有 Keil 安装时,会保留原有的[C51]段落并补上[ARM]段落,一步到位。
具体操作上,装 C51 时在选择目录那一步填C:\Keil_v5(而不是默认的C:\Keil),装 MDK 时也填同一个C:\Keil_v5。MDK 的安装向导如果弹窗提示该目录已有内容,选择继续/合并即可,不要另起一个新目录。
这里有个细节值得强调:安装程序写得越"智能",覆盖行为越不可预测。所以装之前把C:\Keil_v5\TOOLS.INI复制一份存到别处,是你花十秒钟能做的最划算的保险。装完后如果发现某个编译器不见了,把备份文件对比一下,五分钟就能修好,不用重装。
2.2 TOOLS.INI 才是共存的真正开关
装完之后,打开C:\Keil_v5\TOOLS.INI,你应该能看到类似下面这样的内容:
[UV2] ORGANIZATION="your_org" NAME="your_name" EMAIL="your_mail" BOOK0=UV4\RELEASE_NOTES.HTM("uVision Release Notes",GEN) [C51] PATH="C:\Keil_v5\C51\" VERSION=V9.60 BOOK0="C51\HLP\C51.PDF"("C51 User's Guide",GEN) [ARM] PATH="C:\Keil_v5\ARM\" VERSION=V5.36 PATH1="C:\Keil_v5\ARM\ARMCC\" BOOK0="ARM\Hlp\armcc.pdf"("Compiler User Guide",GEN)两个段落都在,说明共存成功。如果只有[ARM]没有[C51],那 51 项目就新建不了,器件列表里也不会出现 8051 芯片。这时候不用重装,直接把[C51]段落按上面格式补进去、路径指向实际的 C51 目录即可。
需要留意的是,有的情况下 µVision 会优先读用户目录下的一份 TOOLS.INI,而不是安装目录里的那份。如果你改完配置文件发现没生效,去%APPDATA%\Keil\下看看有没有同名文件,两处内容保持一致最省心。这也是为什么很多人照着教程改了配置却"没反应",十有八九是改错了文件。
还有一个细节:PATH1这个字段指向 Arm 编译器目录,切换 AC5/AC6 的时候,某些老版本配置会依赖它。如果遇到"编译器版本列表里只有一项"的情况,检查一下这个字段是不是丢了。
2.3 装反了怎么救:不重装系统的补救流程
如果你已经先装了 MDK、后装了 C51,现在打开 µVision 发现 STM32 的芯片选不出来了,或者原本能编译的 ARM 工程报"compiler not found",别慌,按下面顺序处理。
第一步,确认目录结构还在不在。看看C:\Keil_v5\ARM和C:\Keil_v5\C51是不是都存在。多数情况下文件都还在,只是配置丢了。
第二步,打开 TOOLS.INI,检查是不是少了[ARM]段落。缺了就补回来,格式参考上一节。补完保存,重启 µVision。
第三步,如果补完配置后 µVision 启动就崩,或者菜单里缺项,那就是外壳文件被低版本覆盖了。这时候重新运行一遍 MDK 安装程序,选"Repair"或直接覆盖安装到同一目录,让它把 UV4 和配套 DLL 刷回高版本,装完再检查一遍 TOOLS.INI 是否两段齐全。
第四步,器件包通常不受顺序影响,因为它们装在ARM\PACK目录下,跟外壳版本无关。重新装完外壳后,器件列表会自动恢复。
整个过程我实测下来最快十分钟,比重装省事太多。核心思路就一句话:文件可以覆盖,配置可以重写,只要别删目录,就没有救不回来的情况。
3. STM32 侧:器件包与工程配置
3.1 器件包(DFP)安装的三种姿势
MDK 5 之后,"芯片支持"这件事从安装包里剥离出来,变成了独立的器件包(Device Family Pack,简称 DFP)。你装完 MDK 只是装了一个空壳 IDE,里面既没有 STM32F103 的寄存器定义,也没有启动文件,新建工程时器件列表里可能只有寥寥几个 Arm 自己的型号。所以装完 MDK 第一件事就是装包,主要有三种方式。
第一种,在线安装。打开 µVision,点工具栏上那个像小芯片盒子的图标,或者菜单 Pack Installer。左侧展开 Devices,找 STMicroelectronics → STM32F1 Series,右侧会列出可用的包,点 Install 等它下载完就行。这种方式最省心,但依赖网络,公司内网环境经常连不上。
第二种,离线安装 pack 文件。在能上网的机器上把Keil.STM32F1xx_DFP.x.x.x.pack之类的文件下载下来,双击即可安装,安装程序会自动识别 MDK 安装路径。这也是团队统一部署时最推荐的方式,把几个常用包放在共享目录里,谁的电脑缺了就双击一下。
第三种,从开发板厂商的例程包里提取。很多国产开发板会把 pack 文件和例程一起打包,好处是版本对得上,坏处是版本可能比较老。我一般只在第一种、第二种都走不通的时候才用。
常装的几个包:Keil.STM32F1xx_DFP(F103 系列)、Keil.STM32F4xx_DFP(F407 系列)、Keil.STM32H7xx_DFP(H7 系列)。要注意的是,装了包之后 µVision 并不会自动刷新列表,得重启一次才会出现在新建工程的器件树里。
3.2 新建工程时的关键选项
新建工程(Project → New µVision Project)之后,第一件事是选器件。这一步非常关键,因为选中的器件决定了默认的启动文件、Flash 算法、寄存器定义头文件。以最常见的 STM32F103C8T6 为例,要选到 STM32F103C8 这个具体型号,别随手选个 F103ZE,两者 Flash 大小和内存都不一样,选错了后面下载和运行都会出诡异问题。
选完器件会弹出一个"Manage Run-Time Environment"的对话框,里面有 CMSIS 的 Core 和 Device Startup 两部分。如果你想用标准外设库或者 HAL 库自己搭工程,可以在这里只勾 CMSIS Core 和 Device Startup,它会自动帮你把启动文件(startup_stm32f10x_md.s)加进来。如果你想省事,也可以全部跳过,自己手动添加库文件。
接下来是 Options for Target 里的几个必看项。Target 页里,Xtal 填你板子上的晶振频率(常见 8MHz 或 12MHz),这个值影响调试时的时序显示;编译器版本在这里切换 AC5/AC6。Output 页里,勾上 Create HEX File,方便用串口工具或者离线烧录器下载;Debug Information 必须勾上,否则调试时变量看不了——这一点后面还会细说。C/C++ 页里,Define 一行填USE_STDPERIPH_DRIVER, STM32F10X_MD这类宏,具体填什么取决于你用的库和芯片容量等级,MD 表示中容量(64K~128K Flash)。
注意:宏定义里的容量等级不是随便写的。STM32F10X_LD/MD/HD/XL 分别对应小、中、大、超大容量。写错了最典型的表现是编译能过但链接报错,或者中断向量表对不上导致一进中断就跑飞。
3.3 调试器与 Flash 下载算法配置
工程能编译通过,不代表能下载进芯片。下载这一步涉及两件事:调试器连接和 Flash 算法。以最常见的 ST-Link 为例,在 Options for Target → Debug 页选择 ST-Link Debugger,然后点右边的 Settings,在 Debug 标签页确认能读到 SW Device 那一栏有芯片 ID。如果这里是空的,说明硬件连接有问题,先把线序、供电、SWD 速率排查一遍。
切到 Flash Download 标签页,这里是重灾区。你需要确认两件事:一是 Programming Algorithm 列表里有没有对应芯片的算法;二是勾没勾 Reset and Run。算法这一栏,STM32F103C8 对应的是STM32F10x Med-density Flash(容量 128K 以下),STM32F103ZE 对应STM32F10x High-density Flash,STM32F407 对应STM32F4xx Flash。如果没有,点 Add 手动添加。
Reset and Run 这个勾选,建议下载阶段一定勾上。不勾的话,下载完程序停在复位状态不跑,新手经常以为"下载成功了但没反应",其实只是没运行而已。等调试阶段再取消勾选,方便下载完立刻停在 main 函数入口。
还有一个很容易被忽略的点:有些开发板把 SWD 的两个引脚(PA13、PA14)复用成了普通 GPIO。这时候下载器就找不到芯片了,表现为"找不到设备"。解决办法是拿复位键配合:按住复位、点下载、看到下载开始的瞬间松开复位。这个手法在调试跑飞的板子时几乎是必备技能。
3.4 调试时看不到结构体变量怎么解
这是搜索量很高的一类问题:Debug 模式下,Watch 窗口里加了个结构体变量,结果显示成{...}或者干脆展开不了,只能看到一个地址。原因通常有三个,按出现频率排序。
第一个,优化等级太高。编译器的 -O2/-O3 会把不活跃的变量优化掉或者放进寄存器,调试信息里就没有它的完整布局。解决方法是在 C/C++ 页把 Optimization 设成 Level 0,重新编译。这是最常见的原因,十次里有七次是它。
第二个,没勾 Debug Information。前面提过,Output 页里的这个勾选决定要不要往可执行文件里写调试信息,没勾的话连变量名都查不到。
第三个,变量本身是局部的且生命周期已过。你在某个函数里定义的局部变量,出了那个函数作用域,内存早就被复用了。想看它的值,要么把它提升为全局变量,要么加volatile关键字,要么在它所在函数里打断点看。
如果上面三条都排除了还是不行,可以在 Watch 窗口里手动输入*(uint32_t*)&变量名这种强制类型转换的写法,绕过 IDE 的自动解析,直接看内存。另外,升级一下 MDK 版本有时也能解决——某些老版本对 C99 复合类型的解析确实有 bug。
4. 51 侧:C51 工程配置与容易踩的坑
4.1 器件选择与 STC 芯片的兼容处理
C51 新建工程的流程和 STM32 类似,Project → New µVision Project,选器件的时候问题来了:官方器件库里主要是 Atmel(AT89C51、AT89C52 等)、Nuvoton、Infineon 这些老牌厂商,而国内教学和项目里用得最多的 STC 系列,早期并不在官方库里。这时候两种处理方式。
第一种,按兼容型号选。STC89C52 和 AT89C52 在指令集上是兼容的,直接选 AT89C52 就能编译,寄存器定义、头文件基本通用。这是最快的办法,缺点是编译时的器件特性(比如片内 EEPROM、扩展 SFR)用不了。
第二种,用 STC 官方提供的器件库安装工具,把 STC 的器件描述文件导入 Keil。导入之后器件列表里就会出现 STC 系列,新建工程时选具体型号,头文件也会自动带上。
选完器件会问"要不要复制 STARTUP.A51 到工程目录",这里建议选"是"。STARTUP.A51 是启动代码,负责初始化堆、清零内存、设置堆栈指针,是 51 程序能正常跑起来的前提。新手最容易犯的错就是手动把这个文件删了,然后程序莫名其妙跑飞。
4.2 存储模式、Startup.A51 与链接器
51 架构和 STM32 最大的不同在于存储空间分了好几块:data(片内直接寻址 RAM)、idata(片内间接寻址 RAM)、xdata(片外 RAM)、code(程序存储区)。C51 编译器必须知道你的变量该放哪儿,这个信息由"存储模式"决定。
在 Options for Target → Target 页里,Memory Model 有三个选项:Small、Compact、Large。Small 模式下所有变量默认放 data 区,访问速度最快,但 data 区通常只有 128 字节,很容易不够用;Large 模式默认放 xdata,容量大但访问慢;Compact 默认放 pdata,是前两者的折中,用得最少。我的一般做法是:小项目用 Small,变量多了就切 Large,然后对性能敏感的关键变量用data关键字单独指定。
链接器这边,老版本用 BL51,新版本有 LX51。如果你用了比较新的 C51 版本,在 Options → Device 页能看到链接器选择。LX51 支持更大的程序空间和更灵活的段管理,但在教学项目里差别不大,保持默认即可。
启动文件 STARTUP.A51 里有一项 IDATALEN,指定要清零的内部 RAM 长度。如果你的程序用到了较大的片内 RAM 却没改这个值,就会出现"部分变量初值莫名其妙"的问题。这个坑很隐蔽,表现是复位后某些全局变量带着上次运行的值,查半天查不出来。
4.3 代码大小限制与优化取舍
C51 的评估版对代码大小有限制,超过之后链接会失败,报错信息一般是提示程序过大。这时候有三条路:优化代码、切到正版授权、换芯片。优化方面,C51 的编译优化等级从 0 到 9,可以逐级往上试。等级越高,代码越紧凑,但也可能出现时序微妙变化,中断服务函数里的代码不建议开太高等级。
还有一个省空间的技巧是关掉不必要的库函数链接,比如printf这类带浮点格式化的函数,一个就吃掉几百字节。51 上基本没人直接用printf,都是用自定义的串口发送函数。
至于代码大小,每次编译完 µVision 的 Build Output 窗口都会打印一行Program Size: data=xx.x xdata=xx code=xxxx,这个值就是你的实际占用,养成每次编译瞄一眼的习惯,比等到链接失败再改要主动得多。
5. 授权与版本管理:合规前提下把事情做顺
5.1 评估版的能力边界
Keil 的 MDK 和 C51 都提供功能受限的免费版本(评估版 / Lite 版),用来学习和验证完全够用。MDK-Lite 的限制是程序代码大小,超过之后无法编译通过;C51 的评估版也有类似限制,能跑的代码规模更小。这两个版本的功能是全的,编辑器、调试器、器件包都不缺,只是加了体积上限。
对初学者来说,先拿评估版把流程跑通、把 GPIO 点灯、串口收发、定时器中断这些基础实验做完,是完全没问题的。做课程设计、做个小鱼缸控制器、写个温湿度采集程序,基本都在限制范围内。等你真的要上大项目了,或者公司项目要交付了,再考虑采购正版授权,这是最合理的节奏。
5.2 用正版授权和统一版本号
到了团队协作的层面,有两件事必须做。第一件是授权合规。正版授权分单机版和浮动版,浮动版适合团队,装在服务器上,几个人共享席位,管理起来比分发十几个序列号省心得多。采购的时候注意版本对应关系,MDK 的授权和 C51 的授权是分开的,别以为买了一个就两个都能用。
第二件是版本统一。前面说过,同一个工程在不同 MDK 版本下的表现可能不一样,尤其是编译器从 AC5 换到 AC6 之后。所以团队里应该约定:项目 README 里写清楚用哪个 MDK 版本、哪个编译器、器件包版本号,新人的电脑按这个清单配。这一条看着琐碎,但能省掉大量"在我这能编译,在你那报错"的沟通成本。
还有一个小习惯值得养成:把器件包的版本固定下来。Pack 也是会更新的,有时候更新之后老工程会冒出新的警告。团队项目里可以用离线 pack 文件统一安装,避免各人装到的版本不一样。
6. 高频报错速查与排查实录
6.1 编译与链接阶段
找不到头文件,报错形如cannot open source input file "stm32f10x.h"。三个方向查:一是器件包没装或者装错系列;二是 C/C++ 页里的 Include Paths 没配;三是工程用了库函数但库里没有这个文件。我遇到的大多数情况是第一条,尤其是刚装完 MDK 就直接打开别人工程的人。
符号未定义,报L6218E: Undefined symbol。这几乎永远是源文件没加进工程,或者加了但没参与编译(比如文件被 exclude 了)。右键工程树里的文件看有没有灰掉,或者在 Project 窗口里检查文件图标上有没有禁用标记。
重复定义,报multiply defined。常见于同时引了标准外设库和 HAL 库,或者启动文件加了两次。检查工程树里是不是有两个 startup 开头的文件。
类型不认识,报unknown type name '__int64'之类。这就是前面说的 AC5/AC6 问题,切编译器版本即可。
6.2 下载与调试阶段
No Cortex-M Device found,或者Flash Download failed - Target DLL has been cancelled。这是下载环节最高频的报错,排查顺序是:先看供电,再看 SWD 四根线(VCC、GND、SWCLK、SWDIO)有没有接错,再看 SWD 速率是不是设得太高(降到 1MHz 试试),最后看是不是引脚被程序复用掉了(按住复位下载法)。我自己的经验是,超过一半的情况是线序反了或者开发板没上电。
找不到下载算法,报No Algorithm found for: 08000000H。说明 Flash Download 页里的算法列表是空的,手动 Add 一个对应容量的算法就好。选错容量等级会导致下载到一半失败,表现是擦除成功但编程报错。
下载成功但程序不跑。第一反应检查 Reset and Run 有没有勾;第二检查 BOOT 引脚跳线是不是在 Flash 启动模式;第三检查晶振有没有起振,程序里如果配了外部晶振但板子上没焊或者频率不对,会卡在时钟初始化。
调试时一打断点就跑飞。多半是中断优先级或者看门狗的问题,也可能是调试时暂停导致通信超时触发了硬件看门狗。调试这类问题的办法是先把看门狗关掉,再逐段排查。
6.3 常见问题速查表
| 现象 | 最可能的原因 | 快速验证方式 |
|---|---|---|
| 器件列表里没有 STM32 | 器件包未安装或版本不匹配 | 打开 Pack Installer 查看已装包 |
| 51 工程无法新建 | TOOLS.INI 缺[C51]段 | 直接打开 TOOLS.INI 检查段落 |
| 编译报找不到芯片头文件 | Include 路径未配置 | Options → C/C++ → Include Paths |
| 下载提示找不到设备 | 接线、供电或 SWD 速率 | 降低速率到 1MHz 重试 |
| 下载算法为空 | Flash 算法未添加 | Debug → Settings → Flash Download |
| 调试看不到结构体 | 优化等级过高或未开调试信息 | 优化设 0,勾 Debug Information |
| 编译成功链接失败 | 代码超评估版限制 | 看 Build Output 的 Program Size |
| 装完后 uVision 打不开 | 外壳被低版本覆盖 | 重跑高版本安装程序选 Repair |
7. 让下一次重装只需要十分钟的几个习惯
7.1 工程目录与模板固化
环境装好之后,花半小时做一件事,能让你后面省很多时间:建一个空白但配置完整的工程模板。里面把器件型号、宏定义、Include 路径、调试器、Flash 算法、优化等级全部配好,编译一次确认无误,然后整个文件夹复制一份重命名为"模板"存档。以后新项目直接复制模板改名,打开就能写代码,不用每次从头配。
模板里建议顺手加一个.gitignore文件,把编译产物排除掉。µVision 会生成Objects、Listings、DebugConfig这些目录,还有.uvguix.用户名这类个人界面配置,都不该进版本库。只提交.uvprojx、源文件、头文件和必要的工程配置,仓库体积能小一大截,冲突也会少很多。
另外,工程路径里保持纯英文,也别放桌面。我见过太多人把工程放在中文路径或者 OneDrive 同步目录下,然后遇到路径过长、同步锁文件导致编译报错的问题。统一放在D:\Projects\项目名\这种短路径下最省事。
7.2 环境备份清单
真要换电脑或者重装系统的时候,需要备份的东西其实不多,列个清单:
C:\Keil_v5\TOOLS.INI,这是核心,两套工具链的共存全靠它;C:\Keil_v5\ARM\PACK\,器件包目录,重装后不用重新下载,直接拷贝回去;- 自己写的外设驱动库、常用头文件、工具脚本;
- 工程的
.uvprojx和源码,这个一般都在版本库里,不用额外操心; - 如果改过 µVision 的字体、快捷键、配色,
%APPDATA%\Keil\下的配置文件也一起带上。
这些东西加起来通常不到 2GB,拷到移动硬盘里放着,新机器上先装好软件、再把 PACK 目录和 TOOLS.INI 覆盖回去,开箱就能用,前后十分钟。
我自己踩过的最难受的一次坑,是给实验室的机器重装环境时图快,只装了一个 MDK 就交付了,结果做 51 实验的同学第二天全在那台机器上折腾器件列表。后来我就固定了一套流程:先装 C51,再装 MDK,装完立刻打开 µVision 确认两边的器件树都能展开,最后把 TOOLS.INI 备份到共享盘。这个流程看起来啰嗦,但它把最容易出问题的环节前置了,比后面返工要划算得多。另外一个细节是,版本尽量别追新,尤其别在一个项目中期升级编译器大版本,收益不确定,风险却是实打实的。