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的调试器好用,单步、断点、变量监视都很顺手。
安装步骤我就不啰嗦了,说几个关键点:
- 版本选择:建议用MDK 5.38或更新版本,太老的版本对CMS32支持不好
- 安装路径:不要有中文和空格,否则编译会出莫名其妙的问题
- 器件包:安装完成后,需要手动添加CMS32的器件包(.pack文件)
- 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秒的频率闪烁。如果不闪,别慌,按这个顺序排查:
- 检查电源指示灯是否亮
- 检查SWD调试器是否连接正常
- 检查工程配置中的器件型号是否选对
- 检查LED对应的GPIO引脚是否正确(PB0)
- 检查LED是低电平点亮还是高电平点亮
本章知识体系
下面这张图把咱们第一章的内容串起来了,方便大家理解整个知识脉络:
这张图把咱们第一章的内容分成了四个模块,最终汇聚到LED闪烁这个实践目标上。后面的课程,咱们会沿着这个路径一步步深入。
好了,第一章的内容就到这里。环境搭好了,LED闪起来了,咱们就可以正式开始ADC和定时器的学习了。记住,开发环境是地基,地基不稳,后面盖的楼再高也得塌。所以大家一定要把这一步走扎实了。