资讯动态

Keil5新建工程全流程:从芯片Pack到编译烧录避坑指南

发布时间:2026/10/20 16:28:32 来源:尧图企业网站定制
刚接触嵌入式开发那会儿我最怕的就是“Keil5新建工程”这一步。为啥因为照着别人的教程一步步点总会冒出芯片列表空白、编译报错、烧录不到板子这类幺蛾子而且网上教程各说各话有的说勾这个有的说勾那个越看越乱。这篇博文不绕弯子把我从环境准备到工程创建、文件配置、编译烧录的完整流程重新理一遍把我踩过的坑和总结出的稳妥做法都写清楚。适合刚拿到开发板、想跑通第一个点灯程序的朋友也适合要把老工程迁移到Keil5的读者。按着这篇文章操作你会少走很多弯路。1. 新建工程前先把Keil5的环境底子打好很多人新装好Keil5之后急着点New Project结果弹出选择芯片的窗口列表里什么都没有。这个现象我见太多了新手第一反应是软件装坏了重装两三遍问题依旧。其实真正的原因要从Keil5和Keil4的差别说起。1.1 Keil5为什么选不到芯片软件包模式变了Keil4的时代芯片支持信息是直接写死在软件安装目录里的装完就能选各种型号。从Keil5开始官方把芯片支持拆成了一堆独立的软件包也就是Pack包。Keil5只是提供了一个IDE外壳目标芯片的型号描述、寄存器定义头文件、启动文件模板、Flash烧写算法全都要靠对应的Pack包来提供。所以说白了Keil5里新建工程选不到芯片十有八九就是缺少对应的Pack。你需要先搞清楚自己用的芯片是哪家厂商、哪个系列再去Pack Installer里把对应的包装上。1.2 Pack Installer在线安装与离线包导入打开Keil5工具栏上有一个蓝色的Pack Installer按钮点进去之后有Loaded、Updates等几个页签。在Updates页签里能看到你目前已安装的包和可更新的包Pack Installer会自动从官网拉取包列表。在线安装的操作很简单在Pack Installer左侧搜索框输入芯片的关键词比如输入芯片型号的一部分。在Device列表里找到你的芯片右侧会显示所属的Pack包名称和版本。点击Pack旁边的Install按钮等待进度条跑完。安装成功后Pack栏会变成绿色勾选状态。不过在线安装有一个很现实的问题网络不稳的时候下载到一半失败然后反复重试都卡在同一个地方。这种情况下我建议直接走离线导入在官网的Pack下载页面找到对应芯片厂商的Pack文件文件名后缀是.pack。下载完成后打开Pack Installer在菜单栏找File选择Import from Local Directory...。定位到你下载好的.pack文件选中后点击确定它会自动开始安装。安装完在Loaded页签能看到它。这里有个小经验离线安装时最好把依赖的包一起下下来。有些Pack包依赖于CMSIS这类基础包如果只装了一个后面编译仍可能报缺少组件。我在给一块某Cortex-M内核的板子装环境时就遇到过还得额外装一个Device Family Pack的情形两个包都装上才真正完整。1.3 编译器版本AC5与AC6的确认环境底子的另一半是编译器。Keil5在较新的版本里默认使用ARM Compiler 6也就是AC6但网上大量老教程、老例程是基于AC5写的。这两个编译器对C代码的语法检查严格度不一样AC6更贴近新标准很多在AC5下只是警告的问题比如隐式函数声明、类型不匹配到AC6直接变成错误导致同一个工程在不同编译器下编译结果完全不同。所以新建工程时我会先去Options for Target对话框里的Target页签看一眼右下角那里有个ARM Compiler下拉框。如果你手里的示例代码是比较老的库函数风格建议选择指定版本的AC5编译如果你用的是新版本官方库直接保持默认或者选最新版本就好。这个问题在工程建好之后再切换也来得及不过提前确认能省掉不少莫名其妙的报错。2. 从零开始创建Keil5工程的完整操作清单环境准备好之后就可以开始真正的新建工程操作了。我把整个流程拆成几个步骤每一步都说明为什么这么做。2.1 新建项目文件与选择目标芯片打开Keil5在主菜单里点击Project下拉菜单里选择New uVision Project...。这里会弹出一个保存对话框让你选择工程存放目录并输入工程名。关于路径我一定要啰嗦一句工程名和路径不要出现中文、空格和特殊符号。Keil5虽然比Keil4能容忍中文路径但后面接仿真器、配置工具链的时候中文路径依然可能引发奇怪的问题比如编译生成的中间文件找不到、烧录器连接失败。我习惯在某个盘的根目录下建立一个总的开发文件夹里面再按项目细分比如DevProject文件夹工程名用英文缩写加下划线命名这样后续整个放在U盘里带走也能正常用。保存好工程名之后会弹出芯片选择窗口。在搜索框输入你手上芯片的关键字下方列表会过滤出匹配的器件。双击选中或者选中后点OK。这一步看似简单却非常关键因为芯片型号决定了后面加载的启动文件、链接脚本和烧写算法。我曾经有一次赶时间随便选了一个相近型号结果程序跑起来后定时器中断频率和预期差很多排查半天才发现是启动文件里的堆栈配置和时钟初始化不同。选完芯片Keil会再弹出一个Manage Run-Time Environment窗口里面列了一堆可勾选的组件比如CMSIS CORE、Device的Startup文件。很多新手在这里被吓到不知道怎么勾。我的建议是先点Cancel直接进入工程界面然后用后面讲的手动方式管理启动文件。等你对Keil5的软件包机制熟了再回来用它也不迟。2.2 目录规划先把工程结构立起来新建工程之后工程目录下默认只有工程本身生成的几个文件比如.uvprojx、.uvguix。我强烈建议在写代码之前先把目录结构规划好不然代码多了Main文件夹里塞满几十个.c文件谁看谁头大。我的常用结构是这样的文件夹或分组用途Project存放.uvprojx工程文件也就是Keil工程本体User放main.c、中断处理、应用主逻辑Hardware板载外设驱动LED、按键、传感器这类Driver厂商官方库或者HAL驱动源码Core启动文件、系统初始化相关文件Doc芯片数据手册、勘误表等参考文档在Keil界面里对应的操作是在Project窗口里右键点击Target 1选择Manage Project Items...在Project Targets里可以给目标重命名在Groups里新建分组把默认的Source Group 1改成User再依次新建Hardware、Driver、Startup等分组。分组的名字和硬盘上的文件夹不一定完全对应只要你自己理得清就行但建议保持一致避免找文件费劲。2.3 启动文件与CMSIS工程骨架不能少一个空工程是编译不出什么东西的因为还缺骨架。这个骨架就是启动文件。启动文件是一段汇编代码芯片上电后第一条指令就是它它负责初始化堆栈指针、设置中断向量表、把C运行环境准备好最后调用main函数。没有启动文件程序根本不知道从哪里开始执行。添加启动文件的途径有两种。一种是在刚才那个Manage Run-Time Environment窗口里勾选CMSIS下的CORE和Device下的StartupKeil会自动帮你把启动文件加入工程这个方案干净利落。另一种是手动添加先到芯片厂商的开发包或者旧工程里找到对应的启动文件通常是.s后缀或者.S后缀再用右键分组选择Add Existing Files...把它加入Startup分组。手动方案的好处是你能明确知道放进来的是什么文件出了问题容易排查。除了启动文件CMSIS的CORE组件也建议加上。它提供了一些核心头文件比如通用寄存器定义、NVIC中断相关接口很多库函数都依赖它们。如果缺少这部分编译时会出现找不到某种标准头文件的情况。2.4 魔法棒里的第一轮设置Output与Listing工程基本结构建好后先别急着写代码点一下工具栏上的魔法棒图标也就是Options for Target把输出设置配好。这里的设置直接关系到你编译出来的文件在哪、是什么格式。在Output页签里能看到Create HEX File的选项。如果之后的烧录程序要用外部工具比如某些一键烧录上位机那就必须勾选它Keil编译时才会额外生成HEX文件。如果直接用Keil自带的烧录功能下载二进制文件不勾选也问题不大我个人是习惯勾上的以防万一。Output页签下面还有Select Folder for Objects...按钮可以指定编译中间文件存放目录。我一般会在工程目录下建一个Obj子文件夹把编译产物统一放过去这样工程根目录不会堆满.axf、.o文件。Listing页签同理用来存放汇编列表文件和map文件。map文件特别重要你看内存超没超、哪些函数占了多少Flash空间都靠它。Keil默认生成的map文件在工程目录下但指定到一个固定的Listing文件夹里管理起来更顺手。3. 文件组织与路径配置编译能否通过的关键骨架搭好、输出配置完成之后接下来就是往工程里填充源码文件。这一步会直接决定你的编译能不能一次通过。3.1 添加源文件到对应分组我的习惯是先建一个main.c保证工程能编译出一个空程序这时候再逐步添加其他模块每次增减后都重新编译一次这样出了问题很容易定位。在Keil里右键点击User分组选择Add New Item to Group...然后选择C File。给文件取名为main勾选在对应目录创建然后Keil会在你指定的目录下生成main.c并自动加入工程分组。你只需要在窗口里写一个最简化框架int main(void) { while (1) { } }先编译一次确认环境基本跑通。这一步不能省因为如果连空工程都编译不过问题大概率出在环境或工程配置上而不是你的代码。接下来再添加其他驱动代码右键Hardware分组Add Existing Files...把你已经写好的LED驱动、按键驱动等源码文件加进来。注意这里只是加入工程引用不会复制文件到工程目录所以添加之前源文件必须已经保存在合适的位置。3.2 C/C选项卡宏定义和Include Paths源码文件加进来后编译器依然可能报错因为你的.h头文件没告诉编译器去哪找。这一步是所有新手最容易卡住的地方。点击魔法棒找到C/C选项卡。这个界面里有两个极其重要的区域第一个是Preprocessor Symbols里的Define输入框。这里填的是全局宏定义很多库需要它来决定编译哪个版本的代码。比如标准外设库通常要求定义USE_STDPERIPH_DRIVER告诉库文件要不要把驱动接口编译进去有些还要求定义芯片容量等级比如大容量产品要定义对应的HD宏。具体哪个宏必须填你要看所用库的头文件说明一般在readme里会写。第二个是Include Paths点右边的...按钮弹出路径配置对话框。这里面加的是编译器搜索头文件的目录。很多新手把路径填到具体文件那一级比如填到inc这个目录但头文件放在inc下面更深的子目录里结果编译还是报找不到头文件。原则很简单把你的头文件放在哪个目录Include Paths就添加包含头文件的目录。如果有多个目录就逐个添加每一条之间用分号隔开你点了...按钮后它会自己管理这个分号。3.3 头文件路径配置的常见失误头文件路径配置里最常见的坑是绝对路径和相对路径的混用。当你把整个工程文件夹拷贝到另一台电脑或者发给别人时硬盘分区、用户名都变了绝对路径会直接失效编译报出一堆找不到头文件的错误。我自己的做法是尽量把工程文件放在一个干净且固定的目录层级然后在Include Paths里添加相对路径。所谓相对路径是相对于工程的.uvprojx文件所在目录。假设工程文件在Project文件夹里头文件在Hardware/inc那么添加路径时写..\Hardware\inc而不是写D:\某盘\某目录\Hardware\inc。Keil5在添加路径时有选项可以选择保存成相对路径你手动填写的时候注意一下就能避免这个问题。另外还有一个容易被忽视的点如果你把某个源文件加入工程后又移动了该文件在硬盘上的位置Keil不会自动更新编译时就会报文件缺失。这种情况在Git仓库里切换分支、同事拉取新版本代码后很容易出现。解决方法是右键分组里的条目选择Remove然后重新Add Existing Files把新位置的文件加回来。4. 编译、烧录与调试让程序真正跑起来工程能编译通过只是第一步。要让程序在板子上跑起来还得把烧录和调试配置弄对。很多人卡在“编译零错误但下载失败”的阶段多半是这部分的问题。4.1 烧录器选择与Debug模式设置先看Debug选项卡。这里有两套模式左边是Use Simulator也就是纯软件模拟不接任何硬件右边是使用仿真调试器通常下拉框里会列出Keil支持的调试器比如ST-Link、J-Link、CMSIS-DAP这类。如果你只是想让程序在板子上跑起来那就要选右侧的硬件调试器选项并且在下拉框里选择你手里实际使用的仿真器品牌。选好之后点旁边的Settings按钮进入详细设置。Settings里最核心的是Debug页签这里有两个关键参数Port选SW或者JTAG。现在绝大多数开发板都用SWD接口只接SWDIO、SWCLK、GND三根线就能调试。JTAG占用的引脚更多用得少了。我一般直接用SW模式。Max Clock如果是新板子或者飞线连接的板子建议把速率降低一点比如1MHz以内。高速率在某些不稳定连接下会导致连接失败降速后反而稳定。点一下Settings旁边的Power按钮可以让仿真器给目标板供电但不是所有仿真器都支持这个功能。连接成功的话SW Device里能看到识别出来的芯片IDCODE。4.2 Flash Download与算法文件在Utilities选项卡里勾选Use Debug Driver然后点右边的Settings进入Flash Download功能页。这个界面是烧录的核心。Flash Download页面里能看到一个空的Programming Algorithm列表。你必须点击Add按钮从列表里选择你的芯片对应的Flash算法。这个算法文件就是上文说过的由Pack包提供的东西。它负责告诉烧录器目标芯片的Flash起始地址在哪里、容量多大、擦除和写入的指令序列是什么。如果你在Add列表里找不到任何算法那就是Pack包没装完整回到Pack Installer去把Device Pack重新安装或更新。如果你选错了算法烧录时通常会报Flash Download failed或者Erase Failed之类的错误。算法文件添加之后记得确认一下起始地址。最常用的情况比如芯片内部Flash从0x08000000开始算法会默认填好一般不需要改。如果项目用到了外扩存储或者做了BootLoader分区才需要重新设置下载地址和算法范围。这一块新手阶段先按默认踩不到太多坑。烧录失败还有一个常见原因是Reset and Run选项没勾。如果你希望程序下载完后自动复位并运行在Flash Download页勾选Reset and Run即可。没勾的话下完程序板子不会立刻跑需要手动按一下复位按键很多新手误以为程序没烧进去。4.3 在线调试与printf打印烧录跑通之后你会很快需要调试手段。除了传统的串口打印Keil还自带一个逻辑器的思路就是Debug (printf) Viewer窗口。启用它需要一点额外配置。首先在Debug选项卡里确认你选的是硬件调试器不是Simulator。然后在Settings里的Trace页签将Core Clock设为芯片主频比如72MHz或你实际配置的频率这样显示的时间信息才准确。烧录并进入调试模式后通过View菜单打开Debug (printf) Viewer窗口。接着在代码里重定向fputc函数让printf底层输出走串口或者仿真器的ITM通道int fputc(int ch, FILE *f) { // 把ch发送到串口一字节或者写入ITM return ch; }这里实现方式取决于你的硬件连法。如果是普通串口那就是往串口数据寄存器写字节如果用的是SWO引脚和ITM通道就往相关寄存器写。配置好之后再调用printf打印信息信息就会出现在Debug窗口里不需要额外接串口线。这种调试方式在验证算法、打印状态机流转时非常方便配合断点看变量比盲调效率高得多。5. 实测中最容易踩的坑典型报错与完整排查链路前面把完整的配置流程讲清楚了但实际使用中总会遇到各种报错。我把这些年积累下来、出现频率最高的几类问题和排查顺序整理一下按这个链路查能少烧很多脑细胞。5.1 芯片列表空白Pack没装齐问题现象有两种一种是新建工程时选芯片的窗口搜索不到任何器件另一种是工程建到一半某个驱动组件缺失编译报缺少系统头文件之类的错误。排查链路先打开Pack Installer在Loaded页签看看有没有该芯片厂商的包。如果没有去Updates页签在线安装或者走离线包导入。装完回来刷新工程问题一般就解决了。特别提醒有些Pack包有版本依赖装了一个旧芯片包后发现编译还是缺某些部件这时着重看Pack Installer里有没有黄色感叹号的依赖项提示把提示的依赖包也装上。5.2 找不到头文件从根源一步步查报错形式通常是fatal error: xxx.h: No such file or directory这种问题看起来简单但很多人上来就乱加路径结果越加越乱。我的排查顺序是先用文件资源管理器确认这个头文件到底存在不存在。很多时候是文件压根没拷贝到工程目录里那路径配啥都没用。确认头文件所在目录是否已经添加进Include Paths。检查宏定义有些头文件的内容是被宏包住的定义不对里面引用的其他头文件不会参与编译。检查报错源文件本身是否真的在工程分组里。有些文件看起来在工程分组里但实际引用位置和磁盘路径对不上编译器只会报头文件缺失。按这个顺序查基本不会漏。5.3 编译通过但链接报错SystemInit这类隐藏依赖有时候编译零错误但最后链接阶段报错最常见的是找不到__main、SystemInit这类符号。原因在于启动文件里默认调用了一个叫SystemInit的函数用来做时钟初始化如果这个函数没有被任何源文件提供链接器就会罢工。排查链路确认芯片厂商的Cortex微控制器软件接口标准库里的system_xxx.c文件有没有加入工程。如果没有从驱动包里找到它添加进去如果加入后还有报错打开启动文件看看它引用的SystemInit名称是否和system_xxx.c里定义的函数名完全一致。不同芯片的启动文件引用的符号略有差异名称不匹配也会链接失败。5.4 烧录失败与芯片“锁死”处理流程烧录时的报错五花八门但核心就几类下载时提示No Target Connected或者Target not found连接不上芯片。下载中途提示Flash Timeout擦除或写入超时。下载提示Error Occured有时是Debug Port问题有时是Flash算法问题。排查链路第一检查接线SWDIO、SWCLK、GND是最基本的外加目标板供电。第二降低仿真器速率降低到最低档再试。第三检查Flash算法。第四如果前面都不行考虑芯片可能被读保护或写保护了这种情况常见于程序里启用了读保护功能或者之前调试时意外锁死了Flash。对锁死的情况我用过的有效办法是在Debug Settings里把连接模式改成under Reset模式也就是让仿真器复位芯片后再连接同时把速率降到最低然后执行全片擦除把保护位擦掉后再重新下载正常程序。注意有些芯片需要先把复位引脚接出来才能用这种模式开发板上一般都有复位按键对应的引脚。5.5 移植他人工程时的额外检查拿到别人的工程时最烦的还不是报错而是报错之后不知道从哪里改起。我的固定流程是先核对芯片型号看看对方用的是哪颗芯片和你的板子是否相同。型号不同启动文件、Flash算法都要改。打开Options for Target核对编译器版本。如果对方的工程是用AC5写的而你电脑上Keil5默认AC6先切成AC5再编译。检查Include Paths里的路径是否是绝对路径如果是你的机器上不一定存在要把路径改成你本机的实际路径或者相对路径。检查宏定义特别是芯片容量相关的宏否则库函数可能编出错误的外设地址。这一套检查完绝大多数移植工程都能顺利编译起来。最后再分享一个小技巧当你把一套工程的配置、目录结构、启动文件都调顺之后不要急着删掉它把它完整拷贝一份改名成“工程模板”。下次新建工程时直接在这个模板上改芯片型号和源文件就能省掉大量重复配置。我现在的不少项目就是这么起步的效率比每次从头建工程高很多。这也算是我用Keil5这么多年最值得养成的一个习惯。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑