2. LED闪烁
任务说明
本案例基于中微CMS32系列车规级MCU,实现LED以1Hz频率闪烁(即每500ms翻转一次电平,亮灭周期共1s)。核心目标是掌握延时函数的编写方法以及GPIO输出翻转操作。开发板LED接在PB0引脚,低电平点亮。
硬件连接
- LED正极经限流电阻接VCC(3.3V)
- LED负极接MCU的PB0引脚
- 当PB0输出低电平时LED点亮,输出高电平时LED熄灭
软件实现
代码包含三个核心部分:系统时钟初始化、GPIO初始化、延时函数。延时函数采用简单的循环递减方式实现,通过调整循环次数获得约500ms延时。主循环中不断翻转PB0电平,实现LED闪烁。
#include "CMS32L051.h"
/* 延时函数:约延时500ms(系统时钟24MHz时) */
void Delay500ms(void)
{
unsigned int i, j;
for (i = 0; i < 500; i++)
{
for (j = 0; j < 24000; j++)
{
__NOP();
}
}
}
/* GPIO初始化:PB0配置为推挽输出 */
void GPIO_Init(void)
{
/* 使能GPIOB时钟 */
SYSREG->CLK_EN1 |= SYSREG_CLK_EN1_GPIOB_EN;
/* PB0配置为输出模式 */
GPIOB->DIR &= ~(1 << 0); // 方向寄存器:0=输出
GPIOB->OD &= ~(1 << 0); // 开漏控制:0=推挽
GPIOB->PU &= ~(1 << 0); // 关闭上拉
GPIOB->PD &= ~(1 << 0); // 关闭下拉
GPIOB->DRV |= (1 << 0); // 驱动能力:强驱动
}
/* 系统时钟初始化:使用内部高速振荡器,24MHz */
void SystemClock_Init(void)
{
/* 使能内部高速RC振荡器 */
SYSREG->CLK_EN0 |= SYSREG_CLK_EN0_HRC_EN;
/* 等待振荡器稳定 */
while (!(SYSREG->CLK_ST & SYSREG_CLK_ST_HRC_ST));
/* 选择HRC作为系统时钟源,分频系数1 */
SYSREG->CLK_SEL = 0x00;
SYSREG->CLK_DIV = 0x00;
}
int main(void)
{
SystemClock_Init();
GPIO_Init();
while (1)
{
GPIOB->DO ^= (1 << 0); // 翻转PB0输出电平
Delay500ms(); // 延时500ms
}
}
代码说明
延时函数采用双层循环结构,外层循环500次,内层循环24000次,每次内层循环执行一条空指令。在24MHz系统时钟下,每次内层循环约需4个时钟周期(约0.167μs),内层总耗时约4ms,外层500次循环总计约500ms。实际延时精度受编译器优化等级影响,若差异较大可调整内层循环次数。
GPIO翻转使用异或操作GPIOB->DO ^= (1 << 0),每次执行将PB0当前电平取反,无需先读后写,避免中间态干扰。
编译与烧录
- 在Keil MDK中创建工程,选择CMS32L051芯片型号
- 将上述代码保存为main.c并添加到工程
- 工程配置中勾选"Use MicroLIB"以减小代码体积
- 编译生成HEX文件
- 使用CMSIS-DAP调试器通过SWD接口烧录到MCU
验证方法
烧录完成后观察开发板上的LED灯。判定标准:LED以约1Hz频率闪烁,即每秒亮灭各一次,周期稳定无明显停顿。若LED常亮或常灭,检查PB0接线是否正确;若闪烁频率明显偏差,调整Delay500ms函数中内层循环的j上限值。
验证判定标准
- LED以约1Hz频率闪烁,即1秒内完成一次完整的亮灭循环
- 亮灯时间和灭灯时间基本相等(各约500ms)
- 闪烁节奏稳定,无卡顿或频率漂移