☰
Keil5找不到ARM Compiler 5.06?教你正确安装与配置AC5编译器
2026/9/28 1:53:44 网站建设 项目流程

如果你手头有一份老项目,原来在 MDK 里用 ARM Compiler 5.06 编得好好的,换台电脑装好 Keil5 后却发现 Target 选项卡里根本没有“ARM Compiler 5.06”这个选项,不要先怀疑工程坏了。这个问题的根源,十有八九出在 Keil5 新版默认不帮你装旧编译器组件上。

我最近连续帮几个朋友处理了同样的问题:有人在 MDK 5.41 安装时不知道要勾选 ARM Compiler 组件,有人装完 Keil5 后才去找 5.06,结果下载了安装包却装错了目录,还有人在工程里怎么都切不到 AC5。ARM Compiler 5.06 虽说是老一代编译器,但大量存量工程、第三方库和教学例程都绑死在它身上,短期内根本换不掉。这篇东西就把我从下载、安装到工程配置踩过的坑完整捋一遍,顺便把和它强相关的芯片包、XTAL 变灰、烧录失败这些连环问题一起说清楚。

1. 编译器不是“装个 Keil”就有的:先弄懂 AC5 与 AC6 的并存逻辑

1.1 为什么新版 Keil 默认不再带 AC5

很多刚接触 Keil5 的人会把“装了 MDK”等价于“有了全部编译器”,这是误解。MDK 5.x 的完整工具链一直包含两个编译器分支:老牌的 ARM Compiler 5(AC5,底层是 armcc)和新版 ARM Compiler 6(AC6,底层是 armclang)。早期的 MDK 5.x 默认同时安装两者,但从某个大版本开始,官方把 AC5 从默认安装组件里拿了出来,改成了可选组件或独立安装包。

这个改动本身是为了推 AC6。AC6 基于 LLVM/Clang,对现代 C 标准的支持、优化能力和代码体积都更符合新芯片和新软件包的要求。可问题在于,老工程不会因为新编译器发布就自动变兼容。尤其是一些教学例程、旧 SDK、第三方封装库,大量使用 AC5 特有的关键字和语法,比如__packed、__irq、__forceinline、__asm等等,拿到 AC6 下基本就是一片红。

所以新版 MDK 在安装时,默认只保证 AC6 可用,AC5 需要你主动去勾选或单独装。如果你装的是从网上找的绿色版、精简版,或者装机时一路 Next 没细看组件列表,最后找不到 AC5 完全是意料之中。

1.2 你的工程是必须 AC5 还是可以迁到 AC6

遇到找不到 AC5 时,先别着急补装,冷静判断一下工程到底能不能用 AC6。判断方法很简单:打开工程的 Options → Target,看 ARM Compiler 下拉框里当前选的是什么。如果工程原来是 AC5 编译的,切到 AC6 后直接编译,报错数量通常会多到吓人。

一个更省事的办法是看工程文件。用文本编辑器打开.uvprojx,搜索pCCUsed字段。如果里面写着ARMCC,说明工程是 AC5 创建的;如果写着ARMCLANG,说明是 AC6。千万别小看这一步,我见过有人把一个 AC5 老工程硬切到 AC6,最后光是修补启动文件和内联汇编就花了两天。

如果你的项目是这几类情况,强烈建议保留 AC5:

  • 工程基于旧版 CMSIS 包,启动文件或系统文件不是 AC6 风格。
  • 引用了第三方闭源库,库文件只发布了 AC5 编译产物。
  • 代码里大量使用 AC5 私有关键字,测试覆盖不足,不敢为了编译器做大面积改造。

新项目则反过来,能上 AC6 就上 AC6,毕竟 AC5 早已停止功能更新,新芯片的软件包也在逐步去 AC5 化。

1.3 先判断当前 Keil 到底有没有装 AC5

补装之前,先做两个检查,避免白折腾。

第一,打开任意一个 ARM 工程(比如建一个空的 STM32 工程),进入 Project → Options for Target → Target,看 ARM Compiler 下拉框。如果只有Use default compiler version 6或Version 6.x,没有出现 Version 5.06,说明当前 MDK 环境里没有可用的 AC5。

第二,直接看安装目录。MDK 如果装在C:\Keil_v5,那么 AC5 的安装路径通常是C:\Keil_v5\ARM\ARMCC。打开这个目录,如果能看到bin文件夹,并且bin下有armcc.exe,说明 AC5 文件其实存在,只是 Keil 没有在特定工程里显示出来。这种情况多半是工程选项被锁死,或者安装目录和 Keil 的注册路径不一致。

我个人建议在命令行也做一次验证。按Win+R,在 cmd 里进入C:\Keil_v5\ARM\ARMCC\bin,执行:

armcc --vsn

如果输出ARM Compiler: 5.06 update 7 (build 960),说明 AC5 本体是好的。这时候如果 Keil 的 Target 下拉框里还是没有,优先考虑重装编译器到正确路径,而不是手动改工程文件。

2. 手工补装 AC5.06 Update 7(Build 960):下载与安装路径

2.1 从官方渠道找对安装包

网上搜“ARM Compiler 5.06 下载”,前几页会混着各种镜像站和打包站,很多文件来历不明,下载完还可能被 Windows Defender 直接拦掉。稳妥的路径是去 Arm 官方开发者站点或 Keil 官网,搜ARM Compiler 5.06 for Keil MDK,找到 5.06 update 7 对应的安装包,也就是版本号里带build 960的那个。

下载时注意系统位数,官方一般提供 Windows 版本,文件名可能长得像ARMCompiler_5.06u7_Keil_Windows_x86_x64.exe。官方下载通常需要登录 Arm 账号,没账号就注册一个,这是最靠谱的门路。第三方下载站给的所谓“中文破解版”“绿色版编译器”之类的,千万不要碰。

这里多提醒一句:AC5.06 update 7 是 AC5 系列最后一个更新版本,后续不会再出 5.06 update 8、update 9 这样的包了。所以见到 build 960 这个版本直接下,不存在“版本太老”或“还有更新版”的问题。

2.2 安装到 Keil 同一套目录的细节

AC5 安装包本质上是一个独立的工具链安装程序,安装过程中最关键的一步是目标目录的选择。很多人在这一步踩坑,把编译器装到了C:\Keil_v5\ARM\ARMCC\ARMCC,或者干脆默认装到了C:\Arm\...,结果 Keil 完全认不出来。

正确做法是:安装时选到 Keil MDK 根目录,例如C:\Keil_v5。安装向导会自动识别或创建ARM\ARMCC子目录,并把 armcc、armasm、armlink 等工具链放进去。如果你原来的 MDK 装在D:\Keil_v5,那就选D:\Keil_v5,保证和 uVision 的安装路径保持一致。

安装过程会提示是否把编译器加入 PATH。我的建议是不要勾选。AC5 的 armcc 包含了多个版本的 bin 目录,加进系统 PATH 容易和系统里其他 ARM 工具链冲突,比如和 GCC ARM 工具链的arm-none-eabi-gcc抢环境变量。Keil 自己通过内部配置定位编译器,不需要 PATH。

另外,安装前最好关掉杀毒软件或至少把安装目录加入白名单。AC5 的老版本 armcc 有时会被杀毒软件误判为可疑文件,装到一半被隔离,导致后续armcc --vsn直接提示找不到文件。这种情况很隐蔽,我遇到过一次,最后是在杀毒软件隔离区里把 armcc.exe 恢复出来的。

2.3 安装完怎么验证,下拉框里没出现怎么办

安装完成后,重新打开 Keil uVision5。如果当前已经打开着工程,建议把 Keil 完全退出再重开,让 IDE 重新扫描工具链。进入工程的 Options → Target,在 ARM Compiler 下拉框里,应该能看到一行类似Version 5.06 update 7 (build 960)的选项。

如果还是没有,按顺序排查三件事:

  1. 检查C:\Keil_v5\ARM\ARMCC\bin下是否存在armcc.exe,不存在说明安装目录选错。
  2. 打开C:\Keil_v5\TOOLS.INI,搜索ARMCC字段,确认其中的路径是否和实际安装目录一致。不一致时,最省事的办法是卸载 AC5 后重新安装,手动改这个文件对我来说成功率不高。
  3. 新建一个空的 STM32 工程再进 Target 看一遍。有些老工程的.uvprojx里记录了编译器路径,打开时会强制加载旧的编译器配置,新建工程反而能正常显示。

验证通过后,还剩一个让人容易忽略的问题:License。AC5 的使用受 Keil 的 License 体系约束。如果你的 Keil 只有 AC6 授权而没激活 AC5 的编译器组件,Target 下拉框可能能选 AC5,但编译时会弹出版本限制或直接终止。这个不用慌,在正版授权范围内,重新执行 License 更新即可解决。

3. 在工程里切到 ARM Compiler 5.06 并处理第一波编译报错

3.1 Target 选项卡里的编译器切换

AC5 装好之后,剩下的事就是把工程切过去。打开工程,进入 Options for Target → Target,找到 ARM Compiler 下拉框,把Use default compiler version 6改成具体的Version 5.06 update 7 (build 960)。

如果工程里原来是手动指定了某个老版本 AC5 路径,比如Version 5.05,这里切成 5.06 后可能有一堆路径变量需要重新捋一遍。但大部分情况是直接切。

切完之后不要急着点 OK 就以为万事大吉,先点一下OK回到编辑界面,再重新打开 Options,确认下拉框确实停在了 5.06。这个动作很傻,却能排除很多“看起来选了但实际没生效”的怪问题。

3.2 CMSIS 头文件与启动文件缺失

切换到 AC5 后,第一次编译最常见的报错有两类。

第一类是找不到 CMSIS 头文件,比如:

fatal error: core_cm4.h: No such file or directory

这个问题的根源不是 AC5 没装好,而是工程对应的 Device Family Pack(芯片支持包)没装。Keil5 的 MCU 支持从旧版的“集成到安装包里”改成了通过 Pack 分发。工程要用到哪个厂商的芯片,就得先装对应的 Pack,里面才有设备头文件、启动文件、Flash 算法等资源。解决方法是打开 Pack Installer,搜索 STM32F1xx_DFP、STM32F4xx_DFP 等对应的包名,安装后重新编译。

第二类是链接时找不到系统初始化函数,典型报错:

Error: L6218E: Undefined symbol SystemInit Error: L6218E: Undefined symbol __main

这类问题通常是因为启动文件缺失或启动文件不匹配。AC5 工程一般使用startup_stm32f10x_hd.s这类 Keil 格式的启动文件,切换到 AC5 后如果软包里只有 AC6/GCC 格式的启动文件,链接阶段就会缺符号。解决办法是到工程模板或芯片 Pack 的Device/Source/ARM目录下,把对应的 AC5 启动文件添加到工程里。如果你是从旧工程复制的启动文件,注意确认它不是被编辑器转成了其他格式。

3.3 AC5 遗留代码在 AC6 下常见的编译差异

如果你是因为项目必须要用 AC5 才退回这个编译器,那你一定有切到 AC6 后编译失败的惨痛经验。这里把最典型的差异列一下,方便对照。

差异点AC5 常用写法AC6 常用写法
内联汇编__asm { ... }asm(...)/__asm(...),语义有差异
数据对齐__packed__attribute__((packed))
中断关键字__irq__attribute__((interrupt(...)))
强制内联__forceinline__attribute__((always_inline))
字节序定义编译器预定义__BIG_ENDIANClang 默认不定义,需从硬件库处理
语言标准默认 C90/C99默认 C99/C11,且对未声明函数更敏感
编译警告风格相对宽松警告多且部分默认视为错误

AC5 遗留代码最常见的重灾区就是内联汇编。老工程里经常能看到一个函数从启动到寄存器操作全用__asm内联汇编完成,这类代码在 AC6 下必须重写成独立汇编文件或者用__attribute__((naked))配合__asm实现。如果你只是为了维持老代码稳定运行,干脆放弃 AC6 是最合理的。

3.4 代码块和宏定义的“临时兼容”写法

有些事情躲不过,工程既要过 AC5 编译,又希望以后能平滑切到 AC6,可以在代码里加预编译宏做兼容。这套路由逻辑写起来并不难:

#if defined(__CC_ARM) // AC5 专用逻辑 __packed typedef struct { uint8_t a; uint32_t b; } packed_struct_t; #elif defined(__clang__) // AC6 专用逻辑 typedef struct __attribute__((packed)) { uint8_t a; uint32_t b; } packed_struct_t; #else #error "Unsupported compiler!" #endif

__CC_ARM是 AC5 编译器预定义的宏,AC6 使用的是__clang__,两者在同一个 Keil 环境里完全可以靠这个区分。要注意,AC6 兼容模式下不一定只是换关键字那么简单,比如对齐规则、位域布局、内联汇编语法都有差异。所以这种兼容写法只适合小步快跑,不适合大规模套用。

我在实际项目里更推荐“新代码按 AC6 风格写,旧代码继续用 AC5 编”的阶段式做法。不是非要把一个老项目一次性迁到 AC6,而是先用 AC5 把当前版本稳定交付,再用空余时间逐步替换风险代码,测试通过后再换编译器。这样对业务影响最小,也不会因为编译器升级带来不可控的回归问题。

4. AC5 装好之后仍可能踩的连环坑:芯片包、XTAL 变灰与烧录失败

4.1 Keil 找不到 STM32 芯片包,先查 Pack Installer

AC5 本身只是个编译器,它不直接包含 STM32 的寄存器定义和启动文件。你新建 STM32 工程时发现找不到stm32f10x.h,或者编译器报“No such file or directory”,十有八九是芯片包问题。

Keil5 的 Pack 体系里,STM32F1 对应的是Keil::STM32F1xx_DFP,STM32F4 对应Keil::STM32F4xx_DFP,在 Pack Installer 的 Search 框里输入对应型号能快速筛选。点 Install 后,Pack 会自动下载到 Keil 的本地仓库。如果在线下载老失败,去 Keil 官网下载对应.pack离线包,双击后会弹出一个安装进度,装完打开工程再编译。

如果你还装了 Keil C51,只是为了在同一台电脑上既写 8051 又写 STM32,注意别用 C51 工程去打开 ARM 工程。C51 和 MDK 的 uVision 界面相同,但工具链完全不同,编译器下拉框里显示的可能是 C51 编译器,而不是 AC5/AC6。这个错位特别容易在“两个版本共用同一个桌面快捷方式”的情况下发生。

另外,新建 STM32 工程时,Select Device这一步的快慢和 Pack 安装是否完整直接相关。Pack 没装好,器件列表里你的型号是灰的或者根本不显示。进入 Pack Installer 时左侧会出现“Outdated”提示,说明有要更新的包。更新后新工程再创建就正常了。

4.2 Target 选项卡的 XTAL 变灰,和编译器关系不大

AC5 装好后,很多人顺手打开 Options → Target,想修改晶振频率,结果发现 XTAL 这一栏是灰色的,怎么也点不进去。这个现象跟编译器版本无关,更多是器件选择和软件包策略导致的。

在新版 Keil 里,XTAL 字段的作用被削弱了。很多新版芯片 Pack 开始把时钟配置交给软件代码,尤其是 STM32 的 HAL 库工程,SystemInit 函数里会根据外部晶振频率做 PLL 倍频计算。IDE 里这个 XTAL 只是给调试器和某些外设模拟参考用,不是芯片实际主频的直接来源。因此当你在 Device 里选定了特定型号,并且工程启用了“System Viewer”或 RTE 相关配置后,Keil 会把这个输入框置灰,避免你再手工填写一个和代码里不相符的值。

遇到变灰,先确认几件事:

  1. Device 选项卡里是否选了 MCU 型号。如果没选型号,Target 页很多参数本来就没法编辑。
  2. 有没有勾选“Use on-chip ROM/RAM”等选项,某些组合会把硬件参数锁定。
  3. 如果你确实要改外部晶振频率,正确的位置不是 IDE 输入框,而是工程里的SystemInit()函数或stm32f10x.h里的HSE_VALUE宏。

所以这个 XTAL 变灰不用太纠结,它在很多工程里已经沦为一个摆设。真正的频率配置写在代码里,改完一定要重新编译烧录。

4.3 FLASH Download 失败:顺手排查调试器配置

切到 AC5 后编译通过,结果下载程序时左下角报Cannot access Memory或FLASH Download failed,这种情况经常被误认为是编译器问题,其实是调试器和 Flash 算法配置不对。

先按这个顺序排查:

  • 打开 Options → Debug,确认选择的调试器是 ST-Link、J-Link 还是 ULINK,右侧的 Download Options 里勾选Verify Code Download和Reset and Run。
  • 点旁边的 Settings,确认能识别到设备。如果 SW Device 一栏空白,说明连接不稳定,尝试降低 JTAG/SW 速度到 1MHz,或者把接口改成 SW。
  • 进入 Utilities → Settings,查看 Flash Download 列表里是否有对应芯片的编程算法。STM32F103C8 需要的是STM32F10x Med-density Flash 64K这类算法。如果列表里是空的,选中板子上的目标芯片重新添加。

有一个很隐蔽的坑:升级 Keil 版本或重装 AC5 后,某些调试器的 DLL 会被新版本覆盖,导致老调试器联系不上。这时候进 Debug → Settings,看 DLL 版本是否还能被识别。如果不行,需要重新安装对应调试器的驱动。

4.4 芯片包安装失败的常见原因

芯片包在线安装失败也是高频问题。最常见的原因是网络连接不稳定,Pack 文件下载一半就断。解决办法是换离线包。下载离线包时要注意 MDK 版本兼容性,老版本 Keil 可能不识别最新 Pack,选择比当前 MDK 版本主线低一档的 Pack 更稳妥。

安装.pack文件时,如果双击没反应,或者提示“Invalid Pack”,先检查文件是否放到了中文目录下。Keil 对中文路径支持不好,把.pack文件移动到C:\Keil_v5\ARM\PACK同级目录,再双击安装。安装过程要以管理员身份运行 uVision,否则 Pack 管理组件无法写入安装目录。

还有一个小技巧:Pack Installer 右下角的“Import”按钮可以手动引入.pack文件,不需要双击。遇到双击没反应时,从 Pack Installer 里点 Import 选文件,成功率更高。

5. 工程迁移时 AC5 特有的细节,以及我的建议

5.1 从旧工程复制过来后的 Include 路径整理

很多老工程的移植问题不是编译器本身,而是路径。旧工程在别人电脑上编译正常,拷贝到你电脑上用 AC5 一编译,报一堆找不到头文件,这是最磨人的。

打开 Options → C/C++,看 Include Paths 一栏。如果里面写的是绝对路径,比如D:\user\project\inc,换电脑后大概率失效。正确做法是把所有头文件路径改成相对路径,以.uvprojx文件所在目录为基准,用.\和..\表达。比如:

.\HARDWARE\LED .\SYSTEM\delay ..\..\Core\Inc

在 Keil 的 Include Paths 编辑框里,一行一个路径。设置完不要直接编译,先点一下文件树里的工程名称,再点 Options,这样 Keil 会重新加载工程配置。相对路径有歧义时,可以在工程目录下搜索头文件做对照,确保每个缺失的头文件都能找到物理位置。

5.2 AC5/AC6 编译差异速查表

真要长期维护 AC5 工程,建议团队内部至少有一份兼容性速查表。我把最常用的差异整理如下,可以直接复制到项目文档里。

场景AC5AC6
编译器命令行armccarmclang
预定义宏__CC_ARM__clang__/__ARMCC_VERSION
位段访问默认支持不同结构体中位段布局需验证
零长度数组需要扩展语法C99 直接支持
结构体对齐__packed/#pragma pack__attribute__((packed))
栈溢出检查有__use_no_semihosting等控制处理方式不同,依赖链接脚本
中断向量表习惯用__VECTOR_TABLE链接脚本新 CMSIS 版本有单独处理
__main初始化自动执行语义基本一致,但部分汇编启动文件不兼容
半主机模式使用__use_no_semihosting避免AC6 下用--specs=nano.specs等

这张表不是用来挂着看的。工程里写新代码时,尽量别用 AC5 特有的关键字;写模块接口时,结构体对齐和位域这类最容易出问题的部分,一律用typedef封装。这样等哪天必须切 AC6,改动面能压到最小。

5.3 要不要退回老版本编译器?我的实际取舍

我见过很多开发者为了省事,直接把 MDK 降级到老版本,只为了那块默认自带 AC5 的安装包。我不太推荐这种操作。老版本 MDK 对新的芯片 Pack 支持差,调试器驱动也旧,一旦遇到现在新出的芯片型号,可能连器件列表里都是空的。

更合理的方案是:保持 MDK 新版本,单独装一个 AC5.06 update 7,新旧编译器共存。工程需要 AC5 的继续用 AC5,新项目用 AC6。Keil 本身支持这种双编译器模式,这也是官方推荐的过渡路径。

但有一点必须注意:AC5 已经是停止维护的状态,新芯片的软件包和新的 CMSIS 版本对 AC5 的支持只会越来越弱。如果你的产品还处于量产维护期,锁死 AC5 没问题;如果还在新功能开发期,我建议立刻把“向 AC6 迁移”提上计划。迁移工作晚做不如早做,代码量越大,迁移越痛苦。

5.4 日常维护 AC5 工程的小习惯

最后分享几个维护 AC5 工程时让我少踩坑的习惯。

第一,锁编译器版本。工程交付时,在 Options → Target 里不要勾选“Use default compiler version”,而是明确选择Version 5.06 update 7 (build 960)。这样无论别人用什么版本 Keil 打开,编译器版本都是固定的,不会因为“默认编译器”换了导致行为漂移。

第二,保留一份离线工具链包。安装包、芯片 Pack、AC5 安装包都存到公司内部网盘或本地 NAS 里。Keil 在线下载不一定每次都快,尤其是现场调试时没有外网,手里有离线包能解决很多突发问题。

第三,启动文件和头文件版本要和芯片 Pack 配套。AC5 工程一旦换了芯片 Pack 版本,编译结果可能出现各种奇奇怪怪的寄存器结构体变化。维护时不要随手升级 Pack,先看发布说明,确认没有破坏性变更再动。

第四,多利用Build Output窗口里的 Warning 信息。AC5 的警告虽然啰嗦,但很多都指向实际问题,比如隐式函数声明、变量未初始化。不要因为能编过就忽略,这些警告以后切 AC6 时全是致命错误。早发现早处理,比最后集中爆发省力得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询