1. 课程导学与开发环境搭建

各位同学,欢迎来到《CMS32 CAN通信与Bootloader开发实战》的第一章。我是这门课的主讲,做了十几年嵌入式固件开发,踩过的坑比走过的路还多。今天咱们先把地基打牢——聊聊CMS32芯片是什么、CAN协议怎么玩、Bootloader到底干嘛用,最后把开发环境搭起来,跑个点灯程序。

说实话,很多工程师学CAN通信和Bootloader,上来就啃协议栈和代码,结果越学越懵。我个人的习惯是:先搞清楚“这东西为什么存在”,再动手。所以这一章,咱们不急着写代码,先把概念理清楚。

本章核心目标:

  • 了解CMS32芯片的定位与资源
  • 理解CAN协议的基本原理
  • 建立Bootloader的宏观认知
  • 完成开发环境搭建并运行第一个程序

1.1 CMS32芯片简介

CMS32是国民技术推出的一款基于ARM Cortex-M0+内核的32位微控制器。你想想看,在工业控制、汽车电子、物联网终端这些领域,它算是性价比很高的选择。

我最早接触CMS32是在一个车载网关项目上。当时客户要求成本压到最低,但CAN接口、低功耗、宽温范围一个都不能少。选来选去,CMS32正好满足——它内置了CAN控制器,省掉了外挂CAN芯片的成本和PCB面积。

来看一下CMS32的主要资源:

资源项 参数
内核 ARM Cortex-M0+,最高48MHz
Flash 64KB ~ 128KB
SRAM 8KB ~ 16KB
CAN接口 1路CAN 2.0B,支持标准帧和扩展帧
其他外设 UART、SPI、I2C、ADC、定时器
工作温度 -40°C ~ +105°C

嗯,这里要注意:CMS32的CAN控制器是集成在芯片内部的,但物理层还需要外接一个CAN收发器,比如TJA1050或者SN65HVD230。别问我为什么知道——我第一次画板子就忘了加收发器,调试了一整天发现CAN总线一点反应都没有。

1.2 CAN协议基础

CAN(Controller Area Network)是德国博世公司在80年代为汽车电子设计的串行通信协议。说白了,它就是为了解决车上那么多ECU(电子控制单元)之间怎么可靠地传数据。

为什么CAN能成为工业通信的常青树?我个人总结三点:

  • 多主通信:任何节点都可以主动发消息,不需要主机轮询
  • 实时性强:基于优先级的总线仲裁,高优先级报文不等待
  • 可靠性高:差分信号传输,抗干扰能力强;还有CRC校验、错误帧检测

CAN协议里有两个核心概念你必须搞懂:

  • 标准帧(CAN 2.0A):11位标识符,数据段最多8字节
  • 扩展帧(CAN 2.0B):29位标识符,数据段最多8字节

我在项目中遇到过一个问题:两个设备用CAN通信,一个只支持标准帧,另一个默认发扩展帧,结果两边死活对不上话。后来查了半天才发现是帧格式不匹配。所以做CAN通信,第一件事就是确认帧格式。

CAN的物理层用的是差分信号——CAN_H和CAN_L两根线。显性电平(逻辑0)和隐性电平(逻辑1)通过电压差来区分。这也是CAN抗干扰能力强的根本原因。

小提示:CAN总线的终端电阻很重要。标准CAN总线两端各需要120Ω电阻,用来消除信号反射。没有终端电阻,总线在高速通信时会出现波形畸变。我见过有人偷懒不焊终端电阻,结果通信距离超过1米就开始丢包。

1.3 Bootloader概念

Bootloader,直译就是“引导加载程序”。它是一段在系统上电后最先执行的代码,负责初始化硬件、检查固件版本、决定是跳转到应用程序还是进入固件升级模式。

你想想看,产品已经卖出去了,发现固件有bug或者需要增加新功能,难道要把设备拆回来重新烧录?Bootloader就是为了解决这个问题——通过CAN、UART、USB等接口远程升级固件。

一个典型的Bootloader工作流程是这样的:

  1. 系统上电,CPU从复位向量跳转到Bootloader入口
  2. Bootloader初始化时钟、外设(比如CAN控制器)
  3. 检查升级标志(比如某个GPIO电平、Flash中的标志位)
  4. 如果需要升级,进入固件接收和烧写流程
  5. 如果不需要升级,跳转到应用程序入口

这里有个关键点:Bootloader和应用程序在Flash中是分区域存放的。Bootloader通常放在Flash的低地址区,应用程序放在高地址区。跳转的时候要修改中断向量表偏移,否则中断会跑飞。

警告:Bootloader开发中最容易翻车的就是中断向量表配置。我曾经在一个项目里,Bootloader跳转到APP后,所有中断都不响应——因为忘了把VTOR寄存器指向APP的中断向量表。这个问题查了整整两天。

1.4 开发板介绍

本课程使用的开发板是基于CMS32芯片设计的,板载资源如下:

  • CMS32主控芯片
  • CAN收发器(TJA1050)
  • USB转串口(用于调试和烧录)
  • LED指示灯(2个)
  • 按键(2个)
  • CAN接口端子

板子的CAN接口已经接好了终端电阻,默认是120Ω。如果你要级联多块板子,记得把中间节点的终端电阻去掉。

1.5 IDE安装与配置

我们使用的IDE是ARM Keil MDK,版本建议5.38及以上。安装步骤不复杂,但有几个坑我帮你提前踩了:

  1. 从Keil官网下载MDK安装包,注意选择ARM版本
  2. 安装时路径不要带中文和空格
  3. 安装完成后,打开Pack Installer,安装CMS32的器件支持包
  4. 如果Pack Installer下载慢,可以去国民技术官网手动下载并导入

配置工程时,有几点要注意:

  • 选择正确的芯片型号(CMS32L051或具体型号)
  • 时钟配置:外部晶振8MHz,PLL倍频到48MHz
  • Debug工具选择CMSIS-DAP或J-Link

小提示:Keil的工程配置里,Target标签页的“ARM Compiler”建议选V6版本,编译效率更高。但如果你用V6编译报错,可以切回V5试试——有些老代码对V6支持不好。

1.6 第一个点灯程序

好了,理论说完了,咱们动手写个点灯程序。这是嵌入式开发的“Hello World”,也是验证开发环境是否搭好的标准方法。

代码很简单,就是让板子上的LED以500ms的间隔闪烁:

#include "CMS32L051.h"

// 延时函数,简单粗暴
void delay(volatile uint32_t count) {
    while(count--);
}

int main(void) {
    // 使能GPIOB时钟
    SYS->AHBEN |= (1 << 1);
    
    // 配置PB0为推挽输出
    GPIOB->MODER &= ~(0x3 << (0 * 2));
    GPIOB->MODER |= (0x1 << (0 * 2));
    
    while(1) {
        GPIOB->BSRR = (1 << 0);   // PB0输出高电平,LED亮
        delay(500000);
        GPIOB->BRR = (1 << 0);    // PB0输出低电平,LED灭
        delay(500000);
    }
}

编译通过后,用调试器下载到板子。如果LED开始闪烁,恭喜你——开发环境搭建成功!

嗯,这里有个小细节:延时函数的计数值500000是基于48MHz主频估算的,实际延时可能不是精确的500ms。精确延时要用定时器,咱们后面章节会讲。

本章知识结构

为了让你对本章内容有个整体把握,我画了一张知识结构图:

第1章 知识结构图 课程导学与环境搭建 CMS32芯片简介 CAN协议基础 Bootloader概念 开发板与IDE Cortex-M0+内核 标准帧/扩展帧 固件升级流程 Keil MDK配置 点灯验证 本章为后续29章打下基础 CAN通信和Bootloader开发都依赖这些基础知识

这张图把本章的知识点串起来了。中心是课程导学与环境搭建,四个分支分别对应芯片、协议、Bootloader和开发工具,每个分支下面还有具体的子知识点。你可以把它当作本章的导航地图。

好了,第一章的内容就到这里。开发环境搭好了,点灯程序跑起来了,接下来咱们就可以正式进入CAN通信的世界了。