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后编译下载。

验证方法与通过条件

  1. 编译验证:上述编译命令无报错,生成blink.bin文件。
  2. 硬件验证:烧录后观察板载LED是否以约1Hz频率闪烁(亮灭各约0.5秒)。
  3. 判定标准:LED持续闪烁且周期误差在±30%以内(因延时函数未使用定时器,允许较大偏差),说明GPIO控制与时钟配置正确。

若LED不亮,依次检查:①电源指示灯是否点亮;②烧录是否成功(调试器可读取芯片ID);③P1_0引脚是否与板卡丝印一致;④GPIO1时钟使能位是否正确(查阅具体板卡原理图与参考手册)。

常见问题

  • 编译报错“未定义RCC”:确认包含的CMSIS头文件与目标芯片匹配(M55.h或U55.h)。
  • LED常亮不闪烁:检查延时函数是否被编译器优化掉——将cycles变量声明为volatile uint32_t。
  • 烧录后无反应:确认BOOT引脚配置正确,或改用调试器复位后运行。