🔬 实验04:GPIO 口——跑马灯

📌 实验目标
  • 掌握 GPIO 输出模式的配置方法
  • 学会使用 GPIO_Write 和 GPIO_SetBits/ResetBits 函数
  • 实现多种流水灯效果
  • 掌握软件延时和位带操作

一、实验内容

  1. 将 8 个 LED 分别连接到 STM32 的 8 个 GPIO 引脚
  2. 编程实现 LED 流水灯效果(依次点亮、循环)
  3. 实现多种流水灯花样(单灯循环、双灯追逐、闪烁等)
  4. 使用位带操作实现高效 GPIO 控制

二、GPIO 输出原理

GPIO 推挽输出模式下,可通过写 ODR(输出数据寄存器)来控制引脚电平。

三、库函数方式

流水灯(库函数)
#include "stm32f10x.h"

void Delay(uint32_t t)
{
    while(t--);
}

int main(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    uint16_t i;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 |
                                  GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 |
                                  GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    while (1)
    {
        for (i = 0; i < 8; i++)
        {
            GPIO_Write(GPIOB, ~(0x01 << i));  // 依次点亮
            Delay(1000000);
        }
    }
}

四、寄存器方式

流水灯(寄存器)
#define RCC_APB2ENR  (*(volatile unsigned long *)0x40021018)
#define GPIOB_CRL    (*(volatile unsigned long *)0x40010C00)
#define GPIOB_ODR    (*(volatile unsigned long *)0x40010C0C)

int main(void)
{
    unsigned char i;
    RCC_APB2ENR |= (1 << 3);     // 使能 GPIOB 时钟

    // PB0-PB7 推挽输出 50MHz
    GPIOB_CRL = 0x33333333;

    while (1)
    {
        for (i = 0; i < 8; i++)
        {
            GPIOB_ODR = ~(0x01 << i);  // 0000 0001 → 1111 1110
            for (uint32_t j = 0; j < 500000; j++);
        }
    }
}
💡 这两段代码怎么用?
  1. 库函数版用 GPIO_Write(GPIOB, ~(1< 一次写整个端口,寄存器版直接写 GPIOB_ODR——两者都在「改输出寄存器」
  2. 流水灯核心就是「用变量 i 移位生成 8 位图案 + 延时」,把图案换成数组即可做出各种花样
  3. 位带操作(实验目标之一)可把 ODR 的某一位映射到独立地址,实现「单引脚原子操作」

五、参考资料

资料文件
跑马灯 PPT实验2 GPIO口——跑马灯.pptx
实验指导文档实验2GPIO-跑马灯.docx
💡 知识关联本实验对应大课 第2讲 GPIO 口 的理论内容。