4、开发环境搭建:Keil MDK安装与配置、STM32CubeMX初始化代码生成、J-Link调试器配置

好,咱们开始搭建开发环境。这一步其实挺关键的,环境没搭好,后面写再多代码也跑不起来。我见过不少新手在这上面栽跟头,折腾一整天结果发现是软件版本不匹配。所以咱们一步步来,稳一点。

4.1 Keil MDK 安装与配置

Keil MDK,说白了就是ARM内核单片机最常用的IDE。我个人习惯用MDK 5.38版本,太新的版本有时候兼容性反而不好。你想想看,咱们做OBD数据采集,稳定才是第一位的。

4.1.1 安装步骤

  1. 下载安装包:去Keil官网下载MDK-ARM。注意选对版本,别下成C51了,那个是给51单片机用的。
  2. 运行安装程序:双击exe,一路Next。安装路径我建议别用中文,有些插件对中文路径支持不好。
  3. 激活License:安装完后打开Keil,点击File → License Management。把你的License ID Code填进去。嗯,这里要注意,如果你用的是评估版,代码大小限制在32KB以内,咱们OBD项目肯定不够用。
  4. 安装器件包:点击Pack Installer,找到STM32F1系列(咱们用的是STM32F103C8T6)。勾上对应的DFP包,它会自动下载安装。
⚠️ 注意: 我曾经遇到过Pack安装失败的情况,多半是网络问题。这时候可以手动下载.pack文件,然后双击安装。别问我怎么知道的,折腾了一下午才找到原因。

4.1.2 工程配置要点

新建工程时,有几点我建议你特别注意:

  • 选择芯片型号:STM32F103C8,别选成C6或者CB,外设资源不一样。
  • 管理Run-Time Environment:这里勾选CMSIS核心和Device相关组件。我个人习惯只勾必要的,勾太多反而容易出冲突。
  • Output选项卡:勾上"Create HEX File",这样编译后能直接生成hex文件用于烧录。
  • C/C++选项卡:在Define里加上USE_STDPERIPH_DRIVER,这是标准外设库的宏定义。
💡 小技巧: 优化等级我一般选-O2,平衡代码大小和运行速度。做OBD数据采集时,实时性要求没那么苛刻,-O2足够了。

4.2 STM32CubeMX 初始化代码生成

STM32CubeMX这个工具,说白了就是图形化配置单片机外设。以前我们写代码都是对着数据手册一个个寄存器去配,现在方便多了。但我建议你还是要理解它生成的代码在干什么,别当黑盒子用。

4.2.1 配置流程

  1. 新建工程:打开CubeMX,选择"New Project",在Part Number里搜STM32F103C8Tx。
  2. 配置时钟:咱们用外部8MHz晶振,通过PLL倍频到72MHz。在Clock Configuration里把HCLK拉到72MHz,系统会自动帮你算好分频系数。
  3. 配置外设
    • CAN:选PB8(CAN_RX)、PB9(CAN_TX),波特率设500kbps。这是OBD通信的标准速率。
    • USART:选PA9(TX)、PA10(RX),波特率115200,用于和上位机通信。
    • GPIO:留几个IO口做状态指示,比如PC13接LED。
  4. 生成代码:Project Manager里设置工程名和路径,Toolchain选MDK-ARM。然后点GENERATE CODE。

🔑 关键点: 生成代码后,CubeMX会创建一个.ioc文件。这个文件千万别删,以后要改配置直接双击它就能重新打开。我见过有人把.ioc文件丢了,结果改配置得从头再来。

4.2.2 代码结构分析

生成后的工程目录大概长这样:

Project/
├── Core/
│   ├── Inc/          // 头文件
│   ├── Src/          // 源文件
│   │   ├── main.c
│   │   ├── can.c
│   │   ├── usart.c
│   │   └── gpio.c
│   └── Startup/      // 启动文件
├── Drivers/
│   ├── CMSIS/
│   └── STM32F1xx_HAL_Driver/
└── Project.ioc       // 配置文件

你想想看,main.c里有个MX_XXX_Init()函数,这些就是CubeMX帮你生成的初始化代码。我建议你不要手动修改这些函数,要改配置就回CubeMX改,重新生成。否则下次生成时你手动改的代码会被覆盖掉。

⚠️ 注意: 用户代码要写在/* USER CODE BEGIN *//* USER CODE END */之间。这是CubeMX预留的保护区,重新生成代码时不会被覆盖。我曾经吃过这个亏,在保护区外写了半天的代码,一重新生成全没了。

4.3 J-Link 调试器配置

J-Link调试器,做嵌入式开发的老司机应该都不陌生。它支持SWD和JTAG两种接口,咱们用SWD就行,只需要4根线:SWDIO、SWCLK、VCC、GND。

4.3.1 硬件连接

J-Link引脚 STM32F103C8T6引脚 说明
1 (VCC) 3.3V 目标板供电
3 (SWDIO) PA13 (SWDIO) 数据线
5 (SWCLK) PA14 (SWCLK) 时钟线
7 (GND) GND 共地

连接时注意,SWDIO和SWCLK上最好各加一个10k上拉电阻到3.3V。嗯,这个不是必须的,但加了之后信号更稳定。我在项目里遇到过调试器偶尔连不上的情况,加上拉电阻后就再也没出过问题。

4.3.2 Keil中配置J-Link

  1. 点击Project → Options for Target → Debug选项卡。
  2. 在右侧下拉框选择"J-LINK / J-TRACE Cortex"。
  3. 点击Settings,进入调试器配置:
    • Port选SW(不是JTAG)。
    • Max Clock选4MHz,别选太高,线长了容易出错。
    • 确认能检测到Device ID,如果显示"NO Device",检查硬件连接。
  4. 切换到Flash Download选项卡,勾上"Reset and Run"。这样烧录完程序会自动复位运行,省得你手动按复位键。
💡 小技巧: 如果J-Link连不上,先检查驱动。去SEGGER官网下载J-Link驱动包,安装后设备管理器里应该能看到"J-Link driver"。我遇到过Win10系统下驱动签名问题,关掉驱动强制签名就能解决。

4.3.3 调试技巧

调试时我习惯用这几个功能:

  • 断点调试:在代码行号旁边点一下,出现红色圆点就是断点。运行到断点处会停下来,可以查看变量值。
  • Watch窗口:在View → Watch里打开,可以添加变量实时观察。做OBD数据解析时,我经常用这个看CAN报文数据。
  • Call Stack窗口:看函数调用栈,程序跑飞时特别有用。能帮你定位到是哪个函数出了问题。

🔑 关键点: 调试时如果发现程序跑不到断点,先检查是不是优化等级太高了。把优化等级改成-O0再试试。我刚开始做项目时,被-O2优化坑过好几次,变量值怎么看都不对,后来才发现是被优化掉了。

好了,开发环境就搭到这儿。你按这个流程走一遍,应该不会出大问题。下一章咱们开始写OBD数据采集的核心代码,到时候会用到今天配置的这些外设。

公众号:蓝海资料掘金营,微信deep3321