1. 为什么你下载了Keil5还是建不了51工程:版本分裂问题
一个很典型的场景:你按照网上的教程,去官网下载了一个MDK-Arm,费了半天劲安装好,兴致勃勃地准备新建一个C51工程,结果发现Device选择列表里翻遍了也没有AT89C52,只有一串ST、NXP、TI的Arm芯片。或者反过来,你装的是Keil C51版,结果打开STM32的例程,编译直接报错,连头文件路径都是红的。
这不是你安装出了差错,而是Keil这套工具本身从命名到架构就是分裂的。搞清楚这个分裂的来历,比任何安装教程都重要。
Keil最早是一家德国公司,做的是8051内核的开发工具,所以叫Keil C51。后来ARM公司收购了Keil,把产品线扩成了两条:一条继续维护C51,服务8051内核以及各种衍生51芯片(STC、N76E003、IAP15、AT89系列等);另一条重新做了一个MDK-ARM,服务Cortex-M系列,也就是我们常说的STM32。到了MDK 5.x这一代,ARM这条线改叫MDK-ARM 5,也就是大家嘴里说的Keil5,它和C51用的都是同一个界面外壳uVision,但默认情况下C51编译器和MDK编译器是两套互相独立的东西,安装包也互相不包含。
所以问题的本质是:Keil5这个称号在圈子里至少指代两个不同的软件。你要让它同时支持C51和STM32,最核心的一步就是让两套独立的工具链共存于同一个IDE外壳下面。这也是这篇文章要解决的第一件、也是最重要的一件事。
网上很多教程会把这件事讲得很玄乎,什么“合并安装”“共存版”“C51插件包”,其实原理上没有那么多坑,你只需要掌握两个关键点:一是把C51的安装目录和MDK的安装目录选成同一个,二是在安装器里通过添加软件支持包的方式把两个编译器都挂到同一个uVision下。只要这两个点对了,后面就是体力活。
2. 安装包到底怎么选:C51版和MDK版的版本对应关系
在动手安装之前,先花一分钟搞清楚版本号,免得下载了一堆没用的包。
MDK-ARM从4.x之后就改叫MDK 5.x,目前官网主推的是MDK 5.36到5.39这一代,界面长得很现代,支持AC5和AC6两套编译器。C51这条线则不然,它一直用的是9.x的版本号,比如说C51V960、C51V961,最新的大版本停留在9.60左右。很多新手看到C51的版本号只有9点几,就以为它比MDK老很多,其实它只是独立版本号,和ARM这条线的5.x没有直接可比性。
下载的时候需要注意两个版本配套的问题。C51版的安装包是独立的,通常文件名类似C51V961.EXE,它自己带着完整的编译器、链接器、和标准库,安装完以后就能编译8051工程。MDK版的安装包则通常叫MDK539.EXE,它自带Arm Compiler 6,如果你还依赖老工程的AC5编译器,那你得去Arm的官网单独下载Arm Compiler 5的安装包,然后在MDK里把它注册进去。
有一些版本之间的组合是经过社区验证比较稳的。我个人的搭配是MDK 5.36 + C51V960,两个都装到D盘同一个Keil_v5目录下,运行几个月下来没有遇到过UI崩溃、编译器不识别的问题。MDK 5.38之后的版本界面打开Packs窗口时网络会比较慢,因为要加载在线包列表,如果能离线安装Pack会舒服很多,这个后面细说。
还有个容易踩的坑:MDK 5.36之后的安装包默认不再包含旧版的AC5编译器,但是很多从STM32F103时代传下来的老工程是用AC5编译的。如果你用的是MDK 5.39,打开老工程很可能看到“compiler armcc not found”之类的错误。处理方式很简单,要么把工程切换到AC6(大部分代码只要微调),要么单独把AC5装回来。考虑到博文主题是环境搭建,我会把这个内容放进后面“安装完成后的三个验证问题”里详细展开。
安装包的存放也建议你留个心眼。C51和MDK两个安装包加起来也就1GB左右,建议把它们放进一个固定目录保管好,判断版本冲突的时候方便重装。最好不要从各种网盘里下载来路不明的绿色版,那些压缩包经人改过,群里也确实有人装完以后C51编译正常,但Debug里看不到任何调试器,就是因为被精简掉了调试驱动。
3. Keil5安装全流程:一个目录打通C51与STM32
3.1 前置设置:关杀毒、规划路径、整理许可残留
安装之前有几步准备,做好了能少折腾半天。
第一件事是关闭杀毒软件,特别是360安全卫士和Windows Defender。Keil的注册机和一些DLL文件特别容易被误杀,装到一半文件被隔离,等你想编译的时候才发现某个“dll文件丢失”,排查起来极其痛苦。不是说让你永久关闭,安装和激活期间临时停掉就行。
第二件事是规划安装路径。我的建议是直接装到D盘的Keil_v5目录下,而不是C盘的Program Files。原因有两个:一是MDK的包管理器和编译器默认安装在有空格路径下的兼容性虽然没问题,但有些第三方工具和脚本对接Keil时会因为路径空格出问题;二是重装系统后,如果你把Keil装到D盘,很多配置文件和已安装的Pack能直接保留一笔巨大的时间成本。这里说的路径规划要结合你的具体盘符情况,但是有一点是原则:C51和MDK的安装路径必须完全相同,因为它们的IDE外壳是共用同一个uVision4/5目录的。
第三件事是清理旧的许可注册信息。如果你电脑上装过旧版Keil,安装新版本前最好先打开注册表编辑器,搜索并删除“Keil”相关键值,再检查C盘用户目录下的TOOLS.INI文件,避免旧版生成的注册信息干扰新版。这个步骤不是必须的,但装了又卸、卸了又装的人建议做一下。
3.2 先装C51还是先装MDK:顺序没有想象中重要
网上的教程对这个顺序各执一词,有说先装MDK再装C51,有说反过来。根据我自己的经验,先装哪个其实无所谓,关键是两次安装的路径要指向同一个目录。
我的习惯是先装C51,因为C51的安装包体型小,装得快,装完以后会自动在开始菜单生成Keil uVision4的快捷方式。然后装MDK,安装过程中它会检测到已有uVision Shell,然后沿路径合并进去。反过来装也完全可以,MDK装完以后系统里有uVision5快捷方式,C51装到同一目录会自动把C51的编译器文件合并进去。
有一个小细节值得注意:安装MDK时,倒数第二步会让你选“Product Family”还是“Support for additional device families”,这个界面默认显示的是“None”,你要把它选成“C51”,这样安装器才会主动检测C51编译器路径,否则虽然也能靠后期手动配置,但多一道手续。如果安装的时候忘了选,也没关系,后面可以手动指定路径,我会在下一节说明。
3.3 安装过程全步骤记录
第一步,双击C51V960.EXE,出现欢迎界面,一路Next,到选择安装路径页面时,修改为D:\Keil_v5,然后继续直到Finish。
第二步,双击MDK539.EXE,同样一路Next,到路径选择页面时,务必改成和刚才一模一样的D:\Keil_v5,可以看到界面上的提示“Installation Path”和“Keil MDK安装目录”。这里千万要注意,别手滑改成了D:\Keil_v5_ARM之类的路径。确认后继续安装,直到出现Pack安装器相关界面。
第三步,安装MDK完毕后会弹出Pack Installer的窗口,这个窗口是MDK 5.x特有的在线包管理器。此时建议跳过在线安装,把窗口直接关掉。在线包列表加载在网络环境不稳定时会卡好几分钟,没必要的等待就不浪费了。等全部装完以后,可以通过IDE里的绿色方块图标随时打开它。
第四步,验证安装。打开D:\Keil_v5,看到下面有ARM、C51、UV4这三个关键目录,就说明两套工具链已经共存成功了。ARM目录对应MDK的编译器与设备支持文件,C51目录对应C51编译器与设备文件,UV4目录则是共用的IDE外壳。这一步很多教程不会讲到,但它是判断安装是否合并成功的核心依据。
3.4 如何手动让uVision识别C51编译器
如果你安装MDK时没有选择支持C51,或者你下载的C51安装包是精简版,可能出现的情况是:uVision能正常打开、也能建工程,但工程的Toolchain下拉菜单里只有Arm Compiler,没有C51 Compiler。
这时手动配置的方法很简单。打开Keil,点击菜单栏的Project -> Manage -> Project Items,进入Folders/Extensions选项卡,看右侧那一堆路径设置。在“Path for Tools”列表里应该能看到C51的安装路径,如果显示空白或者路径不对,点击旁边的“...”按钮,把路径定位到C51的安装目录下,例如D:\Keil_v5\C51。确认后编译器就会被识别。
还有另外一种情况:C51路径没错,但新建C51工程时Device列表里找不到任何51芯片。这不是编译器问题,而是设备数据库没加载。C51在安装时自带了一个包含AT89、STC、N76等常见型号的Device Database,如果你的C51是精简版,可能缺失这个数据库。解决方式是重新完整安装C51版本,或者用下一节的方法手动安装C51设备包。
4. 芯片包(Pack)到底怎么装:STM32与C51两条路线
MDK 5.x和旧版Keil 4最大的区别,就是引入了Pack(软件支持包)的概念。旧版的Keil 4把设备支持文件直接打包在安装包里,所以装完即用。Keil 5则把设备支持包拆成在线包,需要在Pack Installer里下载,或者手动安装离线Pack文件。
这一步是绝大多数新手安装Keil5之后建不了STM32工程的根源:MDK装完了,Pack没装,项目管理器里设备列表是空的,翻不到STM32F103C8,更选不了STM32F407。
4.1 安装STM32的芯片包:以F1和F4为例
STM32的Pack分为两大系列:一是ST官方发布的Keil支持包,命名形式为Keil.STM32F1xx_DFP.2.x.x.pack;二是社区打包的,比如Keil.STM32F4xx_DFP。对于日常开发F103和F407来说,优先安装官网DFP即可。
在线安装的方法:打开Pack Installer,左侧在Search框输入“STM32F1”,会自动搜索到Keil.STM32F1xx_DFP,点击右侧Install按钮。下载速度取决于网络,一般几十兆的文件要几分钟,断网或很慢时容易失败。我的建议是直接到Keil官网的Pack下载页面下载离线包,用浏览器下载的下载管理器支持断点续传,比Pack Installer自带的下载稳定得多。
离线包的安装方式更简单:双击.pack文件,Keil会自动识别并安装到Pack目录。你也可以手动把.pack文件放到D:\Keil_v5\ARM\PACK目录下,刷新Pack Installer就能识别。安装完成后,打开Pack Installer的Devices选项卡,能看到STM32F1系列的具体型号列表,展开以后找到STM32F103C8,说明安装成功。
4.2 C51的“芯片包”和STM32不一样
这里要澄清一个容易混淆的概念:C51没有像STM32那样的统一DFP包机制,它的设备支持文件是在安装时直接写入设备数据库的。你打开C51工程,Device列表里能看到AT89C51、STC89C52RC、N76E003这些芯片,这些信息存在C51目录的TOOLS.INI和设备数据库中,不是后期用Pack安装的。
这就带来一个问题:有些国产51芯片,特别是STC的新型号(比如STC8H、STC15W系列),官方的Keil设备数据库中未必包含。解决方法是去STC官网下载官方烧录软件,在软件设置里选择“添加STC设备到Keil中”,它会自动向Keil的UV4目录写入对应的设备数据库文件和头文件。这是51开发里非常实用的一步,建议装完Keil就把常见型号加全。
4.3 Pack版本与Keil版本不匹配怎么办
在线装Pack还会遇到一个问题:新版本MDK 5.39的Pack Installer对Pack的版本有最低要求,低版本的Pack文件不会出现在库里。而官网下载历史版本Pack的入口又比较隐蔽,经常只有最新版。
遇到这种情况,不要死磕在线Pack Installer,直接去Keil官网找“Previous Versions”链接。比如STM32F1xx_DFP,官网会列出一系列的版本号(2.0.0、2.2.0、2.3.0等),选择和你MDK版本兼容的就近版本即可。这里有个经验:MDK 5.36搭配STM32F1xx_DFP 2.3.0,STM32F4xx_DFP 2.16.0,这一套组合我用着很稳。
5. 注册激活的正确姿势:C51的2K限制和ARM的32K限制
装好软件和芯片包之后,如果不注册,Keil会进入Evaluation Mode(评估模式)。评估模式下,C51编译器限制代码大小在2KB以内,ARM编译器限制在32KB以内。这是什么概念?C51的2KB限制意味着你哪怕写一个最简单的串口收发程序,稍微加几句显示代码就编译不过了。所以这一步一定要做,而且要做对。
有两点先说明:一是Keil是商业软件,正规商业公司使用需要购买正版License;二是个人学习和学生毕设阶段,社区里普遍使用注册机方案,这种方法在现实中大量存在,但不是被官方倡导的。考虑到很多读者就是在学校或者自学阶段,我会把许可激活的操作步骤写清楚,但请务必理解这套工具的授权边界。正版License的价格几百到几千美元不等,如果你只是学习,评估版其实也可以凑合,但就是那个2KB限制太折磨人。
5.1 获取CID与完成激活
激活的入口在菜单栏File -> License Management。在打开的窗口中,首先能看到一个Computer ID(CID)的字符串,它是你这台电脑的硬件指纹。这串ID是唯一的,换电脑、改主板都会变化,所以激活和电脑绑定。
如果你手头有正版的License号(PACK),可以直接把License号粘贴到New License ID Code (LIC)栏,点击Add LIC即可。社区常用的注册机方案,则是在License Management里复制CID,然后打开注册机(通常是一个名为keygen的可执行程序),把它粘贴进去,再在注册机里选择对应的产品型号。
注册机里通常有两个选项:一个是选择CPU类型,一个是选择维护版本号。CPU类型要和你实际安装的Keil版本对应,比如Target为ARM就选ARM,为C51就选C51;如果在C51界面却选了ARM,生成的注册码在C51里无效。当然,更常见的操作是分别在ARM和C51两个界面各生成一个License码,都添加到License Management里,这样可以确保两套编译器都能正常工作。
添加成功后,License Management窗口里会出现对应的License编号,状态栏显示“Valid until ...”或永久字样。这时候关闭窗口,把Keil重启一遍,打开任意C51工程和STM32工程分别编译测试,不再出现2KB或32KB限制报错,就说明激活正常了。
5.2 激活失败的几种排查思路
激活时最容易遇到的一个问题是:注册机生成的License添加后提示“Invalid License”。这里有两种常见原因。第一种是CID复制错误——它是一串字母加数字的组合,复制粘贴时容易少了几个字符,建议直接点击CID框里的“Copy CID”按钮复制,而不是自己手动选中。第二种是注册机版本和Keil版本不匹配,新一代的MDK 5.37以上版本用旧版注册机会生成无效License,需要找对应新版的工具。这两种情况占了十有八九。
另外提一个容易被忽视的坑:License Management窗口里一次只能显示一个Product的License,你添加了ARM之后,可能需要把窗口下部的下拉菜单从“Keil MDK-ARM”切换到“Keil C51”,再点“Add LIC”添加C51的License。很多教程省略了这个切换动作,结果读者只激活了ARM,C51还是2K限制。
5.3 激活了但还是受限?看看是不是路径问题
还有一种隐蔽情况:License明明显示有效,编译时却依旧弹出评估模式提示。这种问题几乎都和安装路径有关。
Keil的License是根据当前电脑名和系统信息生成的,理论上和路径无关。但如果你的系统用户名是纯数字或者含特殊字符,某些版本的Keil在启动时读取注册信息会异常,导致License失效。解决办法是新建一个英文用户名再试试。还有种情况是安装了多个版本的Keil,注册表被覆盖,License信息指向了错误的安装路径,这时候用注册表编辑器清理干净老版本残留再重装是最省心的。
6. 安装完成后必做的三个测试:判断你的环境真的能干活
这样从官网下载安装包到完成激活,装完并不代表万事大吉。测试环境是否真正可用,我给读者一个固定的三步验证法,顺手还能发现一些隐性配置问题。
6.1 测试一:C51工程能否编译且无2K警告
用uVision新建一个C51工程,选一个最常见型号,比如AT89C52,写一个最简单的main函数,里面随便点几个引脚翻转,编译。正常状态下编译结果应该显示0 Error,0 Warning,且Code Size出现在几百字节到1KB之间。如果看到“LIMITED”字样或出现“code size exceeds 2K”的报错,说明C51许可证尚未生效,回去检查第5节的激活步骤。
这时候顺便看一眼Output选项卡里的文件名,确认是C51编译产生的HEX文件。如果是ARM编译器输出的,格式完全不同。另外建议用十六进制编辑器或STC烧录软件打开生成的HEX文件,确认文件头是“:02000004”,那是标准的Intel HEX格式,51烧录器认这个格式。
6.2 测试二:STM32工程能否编译并下载到板子
新建一个STM32F103C8工程,配置好启动文件和系统时钟,写一个GPIO翻转程序,编译。这里对新手来说最容易踩的坑是忘记安装Device Pack,编译时提示找不到stm32f1xx.h或者"No valid target device"。如果出现这个错误,回顾第4.1节的DFP安装方法。
编译通过后再接上ST-Link或J-Link,在Options for Target -> Debug选项卡里选择调试器,点击Settings能读到芯片ID,说明调试器连接正常,然后进行下载测试。下载时如果提示“Cannot access target”或者“RDDI-DAP Error”,大多是驱动没有正确安装。换一根USB线或者换一个USB口也经常能解决,特别是ST-Link对前置USB口供电要求比较高,插在机箱后置USB上更容易稳定。
这里想额外强调一个实践技巧:STM32的下载测试一定要用“Download”按钮,而不是直接点“Start Debug Session”。前者是把程序烧进Flash,后者只是进入调试状态,有时候下载是好的,调试器配置不对,会导致Debug进入后复位异常。这个区别新手很容易混淆。
6.3 测试三:切换Target验证两套工具链共存
在测试完51和STM32两个独立工程之后,再做一个交叉验证:打开同一个uVision窗口,分别打开两个工程,确认Project窗口底部的Target选项卡能正常切换。
具体操作是:新建一个包含两个Target的工程,一个配置C51编译器,一个配置Arm Compiler。对于需要同时维护51产品和STM32产品的人来说,这个小技巧在后期开发效率提升很大。如果没有这个需求,至少要确认在同一个IDE下,新建51工程和新建STM32工程互不影响。如果发现打开C51工程时uVision自动关闭,多发生在C51和MDK安装路径不一致的情况下,必需重新合并安装。
7. 高频报错排查表:把Keil5安装期的坑一次性讲完
你是技术写作专家。请将上述技术博文按照规定整理输出为一个完整章节:综合近几年各个群里问得最多的问题,我整理了下面这张高频报错排查表,基本覆盖了Keil5安装期的绝大部分情况。建议先收藏,出问题时来对照一下,省得再找一遍教程。
| 报错现象 | 根本原因 | 解决思路 |
|---|---|---|
| 新建工程时Device列表空 | 未安装对应Device Pack | 手动安装DFP离线包,或在Pack Installer中在线搜索 |
| 编译提示No valid target device | Pack装了但IDE没识别 | 关闭Keil,双击.pack重装一次,再打开工程 |
| 编译提示2K/32K限制 | License未激活或激活了错误的编译器 | 检查License Management中是否分别添加了C51和ARM两个License |
| 下载提示Cannot access target | 调试器驱动未安装 | 安装ST-Link/J-Link官方驱动,换USB口,检查连接线 |
| 下载提示Flash Download failed | Flash算法缺失或芯片型号选错 | 在Flash Download选项卡中,确保编程算法列表含对应型号Flash |
| C51工程编译却提示armcc错误 | 新建工程时选择了默认的ADSC工具链 | 新建工程时确认在Toolchain里选了C51 Compiler,不要选Arm Compiler |
| 打开C51工程uVision崩溃 | C51与MDK安装路径不一致 | 卸载后重新安装到同一个目录 |
| XTAL选项卡为灰色不可修改 | 某些芯片包省略了用户可编辑的XTAL | 这是正常现象,外部晶振频率由芯片定义控制,不用管它 |
| 找不到STC系列型号 | STC的设备数据库未写入Keil | 用STC官方烧录软件添加设备到Keil |
表格里有一条值得补充说明,就是“编译提示armcc错误”这条几乎每周都有人问。这里的场景是:你在Device列表里选了一个51芯片,但新建工程时默认的Toolchain下拉菜单却选成了Arm Compiler。Keil 5在新建工程时,会根据Device类型自动判断工具链,但如果你是从别的工程复制过来的工程文件,工具链可能没跟着改,这时候手动修改Target选项里的CC编译器选择即可。
另外关于“XTAL选项卡为灰色”这个问题,很多人第一次看到这个灰色状态会很心慌。其实对于C51工程,Target选项卡里有一栏是XTAL,即晶振频率,默认12.0,是可以编辑的。如果你发现它变灰,基本只有一个原因:你在C51工程里误选了Arm的Device,或者你的C51安装不完整导致设备描述文件未被加载。当你选回正确的C51芯片型号后,XTAL自然恢复可编辑态。对于STM32工程,因为没有XTAL这个选项的概念,就没这个烦恼。
8. 安装完成后的下一步:几个值得做的个人定制
环境搭好了,工作才刚刚开始。最后分享几个我在装完Keil之后会立刻做的事,它们不算必须,但真的能提高日常开发体验。
第一件事是把常用的ARM编译器版本固定下来。Keil 5.36及以上默认使用AC6,也就是armclang,它的编译错误提示风格和AC5差很多。如果你平时是拿STM32做项目,且代码里有大量旧式语法,建议在Options for Target -> Arm Compiler里明确选择一个版本,不要用默认的“Version 6”或者“Version 5”自动切换。否则同一段代码,换个版本编译结果不同,排查问题的时候会非常头晕。
第二件事是设置Keil的环境变量。很多人知道在系统环境变量里加ARMCC路径,但很少有人提,如果不加,第三方工具比如脚本批量编译、CI流程就会找不到编译器。常规操作如下:新建系统变量ARMCC,值设为D:\Keil_v5\ARM\ARMCC,再把D:\Keil_v5\ARM\ARMCC\bin加入Path。这样后续你用命令行调用armcc或者打包脚本编译工程,都能直接识别。
第三件事是配置好Keil的默认编码。Keil的默认编码是ANSI,但很多人复制中文注释进来会变成乱码。你可以在Edit -> Configuration -> Editor选项卡里把Encoding改成UTF-8或GB2312,看项目团队的需求。这个设置每次装完必调,能省下无数“注释乱码”的破事。
第四件事是给C51安装STC设备库。上文的第4.2节提过,我再强调一次:用STC官方烧录软件执行一次“添加STC设备到Keil中”,这一步会让你的Device列表里多出几十个常用型号,包括STC8H、STC15W408AS这些近期项目里高频出现的芯片。很多51开发新手装完Keil却找不到自己买的STC型号,九成就是没做这一步。
第五件事是把你常用的芯片包和离线安装包备份好。MDK 5.x的Pack文件都很大,几十上百兆,放在网盘里,以后换电脑重装时不用再受在线Pack Instller的窝囊气。我自己是维护了一个Keil工具合集目录,里面有C51安装包、MDK安装包、常用DFP离线包、调试器驱动和注册工具,换电脑时整个拷过去,半天内就能恢复到可用状态。
说实话,Keil5的安装本身只是个开头,但这一步没弄顺,后面的点灯、串口、ADC、电机控制全是绊脚石。我希望上面这套流程能让你一次装成功,把时间省下来去写代码、调板子,而不是耗在环境搭建上。从我个人几台电脑的实操经验来看,只要安装路径一致、Pack到位、License两边都激活,这套C51和STM32共存的Keil5环境基本就是一次配置,长期稳定。