1. Hello World LED Blink
任务目标
在M55/U55开发板上驱动板载LED以1Hz频率闪烁(亮500ms、灭500ms),以此验证:①开发环境(编译器、烧录工具)已正确安装;②GPIO输出控制逻辑可用。本案例不涉及RTOS或外设中断,仅使用CMSIS核心寄存器操作实现最小GPIO控制闭环。
硬件与依赖
- 开发板:Arm M55/U55(本例以M55为例,U55引脚定义不同时仅需修改PIN宏)
- 板载LED:连接至P1_0引脚(高电平点亮)
- 工具链:Arm Compiler 6 或 GCC arm-none-eabi
- SDK依赖:仅需CMSIS-Core(提供寄存器地址定义),无需额外驱动库
关键完整代码
#include "M55.h" // 包含CMSIS设备头文件,定义GPIO寄存器结构
// 引脚与时钟定义(根据具体板卡修改)
#define LED_PORT GPIO1
#define LED_PIN (1U << 0) // P1_0
#define GPIO1_CLK_EN (1U << 1) // 假设GPIO1时钟门控位于AHB1ENR的bit1
// 简单延时函数(基于系统主频48MHz,经校准)
static void delay_ms(uint32_t ms) {
uint32_t cycles = ms * 48000 / 4; // 粗略校准:4周期/循环
while (cycles--) {
__NOP();
}
}
int main(void) {
// 1. 使能GPIO1时钟
RCC->AHB1ENR |= GPIO1_CLK_EN;
// 2. 配置P1_0为推挽输出
LED_PORT->MODER &= ~(3U << (0 * 2)); // 清零模式位
LED_PORT->MODER |= (1U << (0 * 2)); // 设为输出(01)
LED_PORT->OTYPER &= ~LED_PIN; // 推挽输出
LED_PORT->OSPEEDR |= (3U << (0 * 2)); // 高速
// 3. 主循环:LED闪烁
while (1) {
LED_PORT->ODR |= LED_PIN; // 点亮
delay_ms(500);
LED_PORT->ODR &= ~LED_PIN; // 熄灭
delay_ms(500);
}
}
编译与烧录
# 以GCC工具链为例(实际路径按安装位置调整)
arm-none-eabi-gcc -c -mcpu=cortex-m55 -mthumb main.c -o main.o
arm-none-eabi-ld -T link.ld main.o -o blink.elf
arm-none-eabi-objcopy -O binary blink.elf blink.bin
# 通过CMSIS-DAP调试器烧录(使用pyOCD或Keil MDK)
pyocd flash -t m55 blink.bin
链接脚本(link.ld)需将FLASH定位在0x30000000(M55内部Flash起始地址),RAM定位在0x30020000。若使用Keil MDK,可直接在IDE中创建空工程并添加上述main.c,在Device选项卡选择ARMCM55后编译下载。
验证方法与通过条件
- 编译验证:上述编译命令无报错,生成blink.bin文件。
- 硬件验证:烧录后观察板载LED是否以约1Hz频率闪烁(亮灭各约0.5秒)。
- 判定标准:LED持续闪烁且周期误差在±30%以内(因延时函数未使用定时器,允许较大偏差),说明GPIO控制与时钟配置正确。
若LED不亮,依次检查:①电源指示灯是否点亮;②烧录是否成功(调试器可读取芯片ID);③P1_0引脚是否与板卡丝印一致;④GPIO1时钟使能位是否正确(查阅具体板卡原理图与参考手册)。
常见问题
- 编译报错“未定义RCC”:确认包含的CMSIS头文件与目标芯片匹配(M55.h或U55.h)。
- LED常亮不闪烁:检查延时函数是否被编译器优化掉——将cycles变量声明为volatile uint32_t。
- 烧录后无反应:确认BOOT引脚配置正确,或改用调试器复位后运行。