GPIO 输出:点亮并闪烁 LED
源码路径:
example/HC32F460JEUA/1.gpio/gpio_output/source/main.c
1. 功能简介
这是单片机界的「Hello World」。
程序做的事非常朴素:把开发板上的三颗 LED(红、绿、蓝)配置成输出,然后在一个 while(1) 死循环里,每隔 500 毫秒把它们的电平翻转一次。
翻转的效果就是:亮 → 灭 → 亮 → 灭…… 看起来就是三颗灯一起「闪烁」,肉眼看大概每秒闪一次(亮 0.5 秒 + 灭 0.5 秒 = 1 秒一个周期)。
学会这个例子,你就掌握了单片机最基础的能力:让一根引脚按你的意愿输出高低电平。之后的蜂鸣器、继电器、驱动 MOS 管,本质都是这一件事。
2. 硬件准备
最省事的做法:直接用 HC32F460JEUA KIT 开发板,板载三颗 LED 已经焊好,什么都不用接,烧录就能看效果。
板载 LED 接线(低电平点亮):
|
|
注意箭头方向:LED 正极(阳极)接 3.3V,负极(阴极)经限流电阻接到引脚。 所以引脚输出低电平时,电流从 3.3V 流过 LED 到引脚,灯亮;输出高电平时两端都是高,没有压差,灯灭。
如果你想外接 LED 自己搭(比如用面包板):
|
|
这种接法就是高电平点亮了(引脚给高,电流流向 GND)。极性和板载相反,写代码时要留意。新手建议先用板载的,别自己折腾接线。
3. 完整代码
|
|
4. 代码分段讲解
4.1 三步配置法
HC32 配任何 GPIO 都是这个固定套路,闭着眼睛都要背下来:
|
|
为什么第一步要清零? 因为 stcPortInit 是定义在栈上的局部变量,C 语言不会帮你自动清零。如果你只填了 enPinMode,剩下的成员(开漏、驱动能力……)就是内存里的随机值。运气好能跑,运气差就出诡异 bug。MEM_ZERO_STRUCT 一句解决。
4.2 三颗灯共用一份配置
注意 PORT_Init() 被调了三次,但用的都是同一个 &stcPortInit。因为三颗 LED 的配置完全一样(都是输出),没必要写三份结构体。这是个很实用的偷懒技巧。
4.3 为什么先 SetBits 拉高
|
|
板载 LED 是低电平点亮。上电后先把引脚拉高,保证三颗灯的初始状态是「灭」,这样后面第一次 Toggle 就是「点亮」,视觉上有个干净的起点。
4.4 主循环:翻转 + 延时
|
|
PORT_Toggle() 是关键。它不用管当前是高还是低,直接反过来。配上 500ms 延时,就是「亮 0.5 秒、灭 0.5 秒」的循环。
Ddl_Delay1ms() 是 ddl 库自带的毫秒级阻塞延时——CPU 在这段时间里啥也不干,纯粹空转数圈。简单例子够用,但真正的项目里不建议长时间用它(CPU 被白白浪费),后面学了定时器就该用定时器来做时间控制。
5. 实验现象
烧录后,开发板上的红、绿、蓝三颗 LED 同时闪烁,节奏是每秒一次(亮半秒、灭半秒)。
因为三颗灯完全同步翻转,看起来会是「三色一起亮、一起灭」。
6. 常见问题
Q1:烧录后灯不亮,或者一直常亮不闪?
- 先确认板子是不是 LQFP100_v2 版本,LED 引脚是不是 PA0/PA1/PA2。用错板子可能引脚对不上。
- 检查是不是烧录失败(程序没进去)。多数下载器会有下载成功提示。
Q2:我改成 PORT_ResetBits 想让灯更亮,结果灯灭了?
- 记住板载 LED 是低电平点亮。
ResetBits(拉低)才是点亮,SetBits(拉高)是熄灭。别被函数名带偏了。
Q3:Ddl_Delay1ms 延时不准,比预期慢/快?
- 这个延时依赖系统时钟频率。如果你没调用时钟初始化、系统跑在默认的内部 RC 时钟上,延时就会偏。本例没调
BSP_CLK_Init(),跑在上电默认时钟,节奏大致对但不精确,做闪灯完全够用。
Q4:三颗灯我只想让一颗闪,怎么改?
- 把主循环里另外两句
LEDx_TOGGLE()注释掉即可。
7. 小结
- GPIO 输出三步走:清零结构体 →
enPinMode = Pin_Mode_Out→PORT_Init。 PORT_SetBits拉高、PORT_ResetBits拉低、PORT_Toggle翻转。- 开发板 LED 低电平点亮,拉低才亮。
Ddl_Delay1ms是简单的阻塞延时,入门够用,项目里少用。
8. 拓展应用
掌握了「控制一根引脚输出」,你已经能做出一堆小东西:
- 呼吸灯:把
Toggle+ 固定延时改成「快速开关 + 调占空比」,就是软件 PWM,能让 LED 由暗到亮渐变。(更专业的做法是用定时器硬件 PWM,见 Timer0 章节) - 交通灯:三颗灯按红→绿→黄的顺序和不同时长点亮,就是一个红绿灯模型。
- 蜂鸣器报警:把 LED 换成有源蜂鸣器,
Toggle就能让它「滴滴」响。 - 继电器控制:引脚接三极管驱动继电器,就能用单片机开关 220V 的电器(注意强电安全)。
- 状态指示灯:项目里最实用——用不同的闪烁频率表示「正常运行 / 出错 / 联网中」等状态。