CIU32 GPIO — GPIO 翻转输出

CIU32 CIU32F003_STDLib V1.0.3 GPIO 翻转输出示例教学

GPIO — GPIO 翻转输出(GPIO_Toggle)

固件库: CIU32F003_STDLib V1.0.3 芯片: CIU32F003(Cortex-M0) 源文件: CIU32/CIU32F003_STDLib_V1.0.3/Projects/GPIO/GPIO_Toggle/Source/main.c


一、功能简介

本示例演示如何把 GPIO 引脚配置为输出模式,并在主循环里周期性地翻转引脚电平。 示例每 300 毫秒翻转一次 LED 对应的引脚,LED 随之闪烁。 这是 MCU 世界里最经典的“点灯”程序,目的是让你掌握外设开发的通用套路: 开时钟 → 配引脚 → 在循环里操作。

二、硬件准备

  • 一块 CIU32F003 开发板(如 HB1025B 核心板)
  • 板载 LED(本示例连接 PB1,即 LED_GPIO_PORT = GPIOB,LED_PIN = GPIO_PIN_1)
  • 一根 USB 线用于供电与下载程序
  • 无需额外外接元件

提示:如果你的板子 LED 接在不同引脚,只需修改 common.h 里的 LED_GPIO_PORT / LED_PIN 即可。

三、完整代码

3.1 主流程 main.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "main.h"

int main(void)
{
    /* 配置系统时钟:使能内部高速时钟 RCH(48MHz),并设为系统时钟源 */
    system_clock_config();

    /* Systick 初始化:为后面的 std_delayms 提供毫秒级延时 */
    std_delay_init();

    /* GPIO 初始化:把 LED 引脚配置为推挽输出 */
    gpio_init();

    while (1)
    {
        /* 翻转 LED 引脚电平(亮 <-> 灭) */
        std_gpio_toggle_pin(LED_GPIO_PORT, LED_PIN);

        /* 延时 300 毫秒,肉眼可见闪烁 */
        std_delayms(300);
    }
}

3.2 关键初始化 common.c(节选)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/* LED 引脚定义,位于 common.h */
#define LED_GPIO_PORT   GPIOB
#define LED_PIN         GPIO_PIN_1

/* 系统时钟配置:RCH 48MHz 作为系统时钟 */
void system_clock_config(void)
{
    std_flash_set_latency(FLASH_LATENCY_1CLK);          /* Flash 读等待 1 个时钟 */
    std_rcc_rch_enable();                               /* 使能内部高速时钟 RCH */
    while (std_rcc_get_rch_ready() != RCC_CSR1_RCHRDY); /* 等待 RCH 稳定 */
    std_rcc_set_sysclk_source(RCC_SYSCLK_SRC_RCH);      /* 系统时钟源选择 RCH */
    while (std_rcc_get_sysclk_source() != RCC_SYSCLK_SRC_STATUS_RCH);
    std_rcc_set_ahbdiv(RCC_HCLK_DIV1);                  /* AHB 不分频 */
    std_rcc_set_apbdiv(RCC_PCLK_DIV1);                  /* APB 不分频 */
    SystemCoreClock = RCH_VALUE;                        /* 记录内核时钟 = 48MHz */
}

/* GPIO 初始化:使能 GPIOB 时钟并配置 PB1 为推挽输出 */
void gpio_init(void)
{
    std_gpio_init_t gpio_config = {0};

    std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB);      /* ① 开 GPIOB 外设时钟 */

    gpio_config.pin         = LED_PIN;                  /* ② 选择引脚 PB1 */
    gpio_config.mode        = GPIO_MODE_OUTPUT;         /* ③ 输出模式 */
    gpio_config.pull        = GPIO_PULLUP;              /* ④ 上拉 */
    gpio_config.output_type = GPIO_OUTPUT_PUSHPULL;     /* ⑤ 推挽输出 */
    std_gpio_init(LED_GPIO_PORT, &gpio_config);         /* ⑥ 写入配置 */
}

四、代码分段讲解

① 系统时钟(system_clock_config) 任何外设工作前,内核时钟必须先就绪。示例把内部 RCH 振荡器(48MHz)作为系统时钟源, AHB / APB 均 1 分频,因此外设总线时钟也是 48MHz。配置完用 SystemCoreClock 记录真实频率,供库函数计算波特率、定时器等使用。

② 延时初始化(std_delay_init) 基于 Cortex-M0 的 SysTick 定时器实现毫秒延时,后面的 std_delayms(300) 依赖它。

③ GPIO 配置(gpio_init) 这是本示例的核心,也适用于所有 GPIO:

  • 必须先开启对应 GPIO 端口的时钟(库里很多外设都有独立的时钟开关,忘记开时钟是最常见的“配置不生效”原因);
  • 用 std_gpio_init_t 结构体描述引脚模式、上下拉、输出类型,再调用 std_gpio_init() 提交。

④ 主循环翻转 std_gpio_toggle_pin() 把引脚当前电平取反,配合 300ms 延时即得稳定闪烁。

五、实验现象

  • 开发板上的 LED 以约 3.3 次/秒(每 300ms 一次)的频率稳定闪烁。
  • 用示波器/逻辑分析仪测量 PB1,可看到占空比 50%、周期 600ms 的方波。

六、常见问题

现象 可能原因 解决办法
LED 完全不亮 引脚定义与板子不符 确认 LED_GPIO_PORT/LED_PIN 与原理图一致
灯常亮不闪 忘了调用 std_delay_init 确保在 while(1) 前初始化 SysTick
配置后引脚无反应 没开 GPIO 时钟 检查是否调用 std_rcc_gpio_clk_enable()
闪烁太快/太慢 延时参数问题 调整 std_delayms() 的实参

七、小结

GPIO 输出是嵌入式开发的“Hello World”。请记住三个要点:

  1. 先开时钟,再配外设;
  2. 输出模式常用推挽(驱动能力强),开漏多用于 I2C 等需要线与的场合;
  3. 翻转用 std_gpio_toggle_pin(),置高/置低分别用 std_gpio_set_pin() / std_gpio_reset_pin()。

八、拓展应用

  • 把 std_delayms 改成定时器中断翻转,主循环可去做别的事(降低 CPU 空转);
  • 改为读取按键(输入模式 + 上拉),实现“按键按下灯亮、松开灯灭”;
  • 用多个引脚做跑马灯,理解 pin 用 GPIO_PIN_x | GPIO_PIN_y 按位或组合。
世界是你们
使用 Hugo 构建
主题 Stack 由 Jimmy 设计