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

各位同学好,我是你们这门课的老周。做嵌入式开发十几年了,从8位机一路做到32位ARM内核,踩过的坑比走过的路还多。今天咱们开始第一讲——先把家伙事儿备齐,把环境搭好。

说实话,很多初学者一上来就急着写代码,结果编译报错半天找不到原因,最后发现是工具链没配好。我建议咱们还是稳一点,先把基础打牢。

1.1 CMS32单片机简介

CMS32系列是中微半导体基于ARM Cortex-M0内核推出的32位通用MCU。你想想看,Cortex-M0的优势在哪?功耗低、性价比高、开发门槛低。说白了,就是花8位机的钱,买32位机的性能。

咱们课程用的是CMS32M53xx系列,具体型号看你们手上的板子。这个系列有几个关键参数:

参数项 典型值 说明
内核 ARM Cortex-M0 32位RISC,主频最高48MHz
Flash 64KB 程序存储,支持ISP/IAP
SRAM 8KB 数据存储,够用但别浪费
ADC 12位,最多16通道 这是咱们课程重点之一
定时器 多路16位 PWM、捕获、比较都支持
工作电压 2.0V ~ 5.5V 工业级宽电压

我在项目里用过不少国产MCU,CMS32的稳定性算是第一梯队的。特别是它的ADC模块,采样精度和抗干扰能力都不错,后面咱们会专门花几章来讲。

1.2 开发板介绍

咱们课程配套的开发板,核心就是CMS32M53xx。板子上集成了哪些外设?我给大家列一下:

  • LED指示灯:2个,一个电源指示,一个用户可编程
  • 按键:2个独立按键,一个复位,一个用户按键
  • 电位器:1个,用于ADC输入演示
  • USB转串口:CH340方案,方便调试
  • SWD调试接口:4线制,支持在线调试

嗯,这里要注意——板子上的LED是低电平点亮还是高电平点亮?我见过不少新手因为这个搞反了,死活点不亮。咱们这块板子,LED是低电平点亮,也就是GPIO输出0时灯亮,输出1时灯灭。记好了,后面写代码要用到。

小提示:拿到新开发板,第一件事不是上电,而是用万用表量一下电源对地有没有短路。我吃过这个亏,有一次板子焊反了二极管,一上电就冒烟了。

1.3 Keil MDK安装与配置

开发环境我选的是Keil MDK,为什么?因为CMS32官方提供的标准外设库就是基于Keil的,省得咱们自己折腾。而且Keil的调试器好用,单步、断点、变量监视都很顺手。

安装步骤我就不啰嗦了,说几个关键点:

  1. 版本选择:建议用MDK 5.38或更新版本,太老的版本对CMS32支持不好
  2. 安装路径:不要有中文和空格,否则编译会出莫名其妙的问题
  3. 器件包:安装完成后,需要手动添加CMS32的器件包(.pack文件)
  4. License:评估版有32KB代码限制,咱们课程工程不大,够用

我记得第一次装Keil的时候,忘了装器件包,结果打开工程全是红叉。折腾了半天才发现是器件没选对。所以大家装完记得检查一下:Project → Manage → Pack Installer,看看CMS32的包有没有打勾。

1.4 CMS32标准外设库导入

中微官方提供了标准外设库,说白了就是一堆封装好的函数,让你不用直接操作寄存器。咱们课程会基于这个库来开发,但后面我也会教大家怎么直接操作寄存器——毕竟有些场景下,库函数效率不够。

标准外设库的结构是这样的:

CMS32_StdPeriph_Lib/
├── CMS32F0xx_StdPeriph_Driver/
│   ├── inc/          // 头文件
│   └── src/          // 源文件
├── CMS32F0xx_Startup/
│   └── startup_CMS32F0xx.s  // 启动文件
├── Project/
│   └── Template/     // 工程模板
└── Doc/              // 用户手册

导入到Keil的步骤:

  • 新建一个空工程,选择对应的CMS32型号
  • 把启动文件(.s文件)添加到工程
  • 把标准外设库的inc和src文件夹添加到工程
  • 在C/C++编译器选项中,添加头文件路径
  • 定义宏:USE_STDPERIPH_DRIVER
注意:头文件路径一定要用相对路径,不要用绝对路径。否则换台电脑编译就报错。我曾经把工程拷给同事,结果他那边全是找不到头文件的错误,就是因为路径写死了。

1.5 第一个LED闪烁工程

好了,环境搭好了,咱们来写第一个程序——让LED闪烁。这是嵌入式界的"Hello World",虽然简单,但能验证整个开发链路是否通畅。

先看代码:

#include "CMS32F0xx.h"

void Delay(uint32_t count)
{
    while(count--);
}

int main(void)
{
    // 使能GPIOB时钟
    RCC_EnableAPB2PeriphClock(RCC_APB2_PERIPH_GPIOB, ENABLE);
    
    // 配置PB0为推挽输出,速度50MHz
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStruct);
    
    // 初始状态:LED灭(高电平)
    GPIO_SetBits(GPIOB, GPIO_Pin_0);
    
    while(1)
    {
        GPIO_ResetBits(GPIOB, GPIO_Pin_0);  // 低电平,LED亮
        Delay(500000);
        GPIO_SetBits(GPIOB, GPIO_Pin_0);    // 高电平,LED灭
        Delay(500000);
    }
}

代码很简单,但有几个地方我要强调一下:

  • 时钟使能:任何外设使用前,必须先打开它的时钟。这是新手最容易忘的。
  • GPIO模式:推挽输出(GPIO_Mode_Out_PP)是最常用的,能输出高低电平。
  • 延时函数:这里用的是软件延时,不精确但简单。后面学了定时器,咱们会用硬件定时器来做精确延时。

编译通过后,用SWD调试器下载到板子上。如果一切正常,LED应该以大约1秒的频率闪烁。如果不闪,别慌,按这个顺序排查:

  1. 检查电源指示灯是否亮
  2. 检查SWD调试器是否连接正常
  3. 检查工程配置中的器件型号是否选对
  4. 检查LED对应的GPIO引脚是否正确(PB0)
  5. 检查LED是低电平点亮还是高电平点亮
经验之谈:调试的时候,我习惯先用逻辑分析仪抓一下GPIO引脚的波形。如果没有逻辑分析仪,用万用表量电压也行——LED灭的时候引脚应该是高电平,亮的时候是低电平。这样能快速判断是硬件问题还是软件问题。

本章知识体系

下面这张图把咱们第一章的内容串起来了,方便大家理解整个知识脉络:

第一章:课程导学与开发环境搭建 CMS32单片机开发 CMS32单片机简介 开发板介绍 Keil MDK安装配置 标准外设库导入 第一个LED闪烁工程 核心目标:搭建完整开发环境,验证MCU最小系统正常工作

这张图把咱们第一章的内容分成了四个模块,最终汇聚到LED闪烁这个实践目标上。后面的课程,咱们会沿着这个路径一步步深入。

好了,第一章的内容就到这里。环境搭好了,LED闪起来了,咱们就可以正式开始ADC和定时器的学习了。记住,开发环境是地基,地基不稳,后面盖的楼再高也得塌。所以大家一定要把这一步走扎实了。