STM32F103C8T6 流水灯实验报告一、实验目的掌握 STM32F103C8T6 最小系统核心板的 GPIO 端口寄存器结构与地址映射。学会使用 C 语言直接操作寄存器的方式配置 GPIO 端口为推挽输出模式。理解 GPIO 端口时钟使能、端口配置寄存器CRL/CRH、输出数据寄存器ODR、位设置/清除寄存器BSRR/BRR的作用与用法。利用 GPIOA、GPIOB、GPIOC 三个端口的引脚控制多只 LED 实现轮流闪烁流水灯间隔 1 秒。了解 STM32 最小系统板板载 PC13 LED 的电路原理并将其纳入流水灯序列。二、实验环境项目说明主控芯片STM32F103C8T6Cortex-M372MHz48 引脚 LQFP开发板STM32 最小系统核心板板载 PC13 用户 LED、8MHz 晶振、3.3V 稳压外接元件面包板 × 1、红色 LED × 1、绿色 LED × 1、蓝色 LED × 1、220Ω 限流电阻 × 3、杜邦线若干开发软件Keil MDK-ARMμVision5编程方式C 语言寄存器直接操作不使用 STD 外设库或 HAL 库系统时钟外部 8MHz 晶振 × PLL 倍频 9 72MHz三、硬件电路设计3.1 引脚分配本实验使用 GPIOA、GPIOB、GPIOC 三个端口各一个引脚控制外接 LED另外使用板载 PC13 LED。具体分配如下表所示。LED 颜色连接引脚所属端口用途接法点亮电平红色 LEDPA0GPIOA外接面包板共阴极高电平绿色 LEDPB0GPIOB外接面包板共阴极高电平蓝色 LEDPC14GPIOC外接面包板共阴极高电平板载 LEDPC13GPIOC最小系统板出厂焊接共阳极低电平3.2 外接 LED 接法共阴极三只外接 LED 均采用共阴极接法LED 的阴极短脚/负极共同连接到 GNDLED 的阳极长脚/正极通过 220Ω 限流电阻连接到 STM32 的对应 GPIO 引脚。工作原理当 GPIO 引脚输出高电平3.3V时LED 阳极电位为 3.3V、阴极电位为 0V两端产生约 3.3V 压差电流经限流电阻流过 LEDLED 点亮当 GPIO 输出低电平0V时LED 两端压差接近 0几乎无电流流过LED 熄灭。因此该接法下高电平点亮低电平熄灭。限流电阻计算LED 正向压降约 1.8~2.2V工作电流取 5~10mA。R (3.3V - 2.0V) / 8mA ≈ 160Ω实际取 220Ω 标准值电流约 6mA亮度适中且安全。3.3 板载 PC13 LED 电路原理STM32F103C8T6 最小系统核心板在出厂时已经在 PC13 引脚上焊接了一个用户 LED通常在丝印层标注PC13或LED1。其电路采用共阳极接法与外接 LED 的共阴极接法相反LED 阳极通过一个约 1kΩ 的贴片限流电阻连接到 3.3V 电源轨LED 阴极直接连接到 MCU 的 PC13 引脚。当 PC13 输出低电平时电流从 3.3V 经电阻、LED 流向 PC13LED 点亮当 PC13 输出高电平时LED 两端等电位LED 熄灭。因此板载 PC13 LED 是低电平点亮而外接三只 LED 是高电平点亮两者极性相反。在四灯流水灯程序中必须分别用不同的宏控制外接灯和板载灯的亮灭不可混用。该灯通常用于验证烧录代码是否正常运行——只要 PC13 能按程序预期闪烁即说明下载、时钟、GPIO 配置均已正常工作。注意PC13 在 STM32F103 中属于兼容 TSCTamper/PC13引脚其输出驱动能力比普通 GPIO 略弱最高翻转速度受限但驱动一个板载 LED 完全足够配置为推挽输出 50MHz 即可正常工作。四、程序设计思路4.1 总体流程程序总体执行流程如下系统时钟初始化配置外部 8MHz 晶振经 PLL 倍频 9 倍得到 72MHz 系统时钟。延时函数初始化配置 SysTick 定时器为delay_ms()提供精确时基。GPIO 初始化依次使能 GPIOA/GPIOB/GPIOC 端口时钟将各 LED 引脚配置为通用推挽输出模式并将所有 LED 初始化为熄灭状态。主循环按预定顺序依次点亮一只 LED、熄灭其余 LED延时 1 秒后切换到下一只循环往复形成流水灯效果。4.2 RCC 寄存器配置时钟使能STM32 复位后所有外设时钟默认关闭必须先向 RCC_APB2ENR 寄存器写入使能位GPIO 端口才能工作。相关信息如下表。寄存器地址位名称作用实验设置RCC_APB2ENR0x40021018bit2IOPAENGPIOA 时钟使能1使能RCC_APB2ENR0x40021018bit3IOPBENGPIOB 时钟使能1使能RCC_APB2ENR0x40021018bit4IOPCENGPIOC 时钟使能1使能配置代码RCC-APB2ENR|(12)|(13)|(14);说明RCC 基地址为 0x40021000APB2ENR 偏移为 0x18故绝对地址为 0x40021018。GPIOA/B/C 均挂在 APB2 总线上因此在 APB2ENR 中使能。4.3 GPIO 端口寄存器地址映射STM32F103 的每个 GPIO 端口包含 7 个 32 位寄存器各端口基地址及寄存器偏移如下表所示。寄存器偏移GPIOA 地址GPIOB 地址GPIOC 地址作用CRL0x000x400108000x40010C000x40011000端口配置低寄存器pin0~7CRH0x040x400108040x40010C040x40011004端口配置高寄存器pin8~15IDR0x080x400108080x40010C080x40011008端口输入数据寄存器ODR0x0C0x4001080C0x40010C0C0x4001100C端口输出数据寄存器BSRR0x100x400108100x40010C100x40011010端口位设置/清除寄存器BRR0x140x400108140x40010C140x40011014端口位清除寄存器LCKR0x180x400108180x40010C180x40011018端口配置锁定寄存器各端口基地址GPIOA 0x40010800GPIOB 0x40010C00GPIOC 0x40011000。相邻端口基地址相差 0x4001024 字节这是因为每个端口寄存器块占用 0x400 地址空间。4.4 CRL/CRH 配置寄存器详细参数CRL 和 CRH 每个寄存器用 4 位配置一个引脚其中高 2 位为 CNF[1:0]配置模式低 2 位为 MODE[1:0]输出模式/速度。本实验所有引脚均配置为通用推挽输出50MHz对应 4 位值为 0011即 0x3。各位定义如下位域取值含义MODE[1:0]00输入模式复位默认值MODE[1:0]01输出模式最大速度 10MHzMODE[1:0]10输出模式最大速度 2MHzMODE[1:0]11输出模式最大速度 50MHz本实验选用CNF[1:0]00通用推挽输出本实验选用输出模式下CNF[1:0]01通用开漏输出CNF[1:0]10复用功能推挽输出CNF[1:0]11复用功能开漏输出4.5 各引脚在 CRL/CRH 中的位置CRL 控制 pin0~pin7每个引脚占 4 位引脚 n 对应 bit[4n3 : 4n]CRH 控制 pin8~pin15引脚 n 对应 bit[4(n-8)3 : 4(n-8)]。本实验四个引脚的具体位置如下表。引脚所用寄存器在寄存器中的位段配置值配置代码PA0GPIOA_CRL (0x40010800)bit[3:0]0x3GPIOA-CRL ~(0xF0); GPIOA-CRL | (0x30);PB0GPIOB_CRL (0x40010C00)bit[3:0]0x3GPIOB-CRL ~(0xF0); GPIOB-CRL | (0x30);PC14GPIOC_CRH (0x40011004)bit[27:24]0x3GPIOC-CRH ~(0xF24); GPIOC-CRH | (0x324);PC13GPIOC_CRH (0x40011004)bit[23:20]0x3GPIOC-CRH ~(0xF20); GPIOC-CRH | (0x320);4.6 BSRR / BRR / ODR 输出控制寄存器配置为输出模式后通过以下三个寄存器控制引脚输出电平ODR输出数据寄存器直接读写整个端口的 16 位输出值bit n 对应 pin n。写 1 输出高电平写 0 输出低电平。但直接写 ODR 是读-改-写操作在中断场合可能存在竞态。BSRR位设置/清除寄存器32 位寄存器低 16 位bit0~15写 1 可将对应 ODR 位置 1输出高电平高 16 位bit16~31写 1 可将对应 ODR 位清 0输出低电平。写 0 的位无影响。BSRR 是原子操作不会被中断打断推荐使用。BRR位清除寄存器低 16 位写 1 可将对应 ODR 位清 0输出低电平等价于向 BSRR 高 16 位写 1。本实验中外接 LED 为共阴极接法高电平点亮因此点亮外接灯 输出高电平 向 BSRR 低 16 位对应位写 1熄灭外接灯 输出低电平 向 BRR 对应位写 1或 BSRR 高 16 位写 1。板载 PC13 LED 为共阳极接法低电平点亮极性与外接灯相反点亮板载灯 输出低电平 向 BRR 对应位写 1熄灭板载灯 输出高电平 向 BSRR 低 16 位写 1。4.7 流水灯状态序列三灯版流水灯状态序列每状态持续 1 秒外接灯共阴极高电平点亮状态PA0红PB0绿PC14蓝持续时间1亮灭灭1 秒2灭亮灭1 秒3灭灭亮1 秒四灯版含板载 PC13流水灯状态序列。注意外接三灯高电平点亮板载 PC13 低电平点亮两者极性相反状态PA0红PB0绿PC14蓝PC13板载持续时间1亮灭灭灭1 秒2灭亮灭灭1 秒3灭灭亮灭1 秒4灭灭灭亮1 秒五、三灯流水灯程序寄存器方式详细注解六、四灯流水灯程序含板载 PC13 LED详细注解在三灯版基础上增加对板载 PC13 LED 的初始化和控制形成四灯流水。注意外接三灯为共阴极高电平点亮板载 PC13 为共阳极低电平点亮两者极性相反代码中分别用不同宏控制。七、实验注意事项时钟使能必须先行STM32 复位后所有外设时钟关闭操作 GPIO 寄存器前必须先设置 RCC_APB2ENR 使能对应端口时钟否则写寄存器无效。PC14/PC15 与 LSE 冲突部分最小系统板在 PC14/PC15 引脚上焊接了 32.768kHz 低速外部晶振LSE此时这两个引脚被晶振占用无法作为普通 GPIO 使用。若遇到此情况可将蓝色 LED 改接至 PB1 等其他空闲引脚并相应修改代码中 GPIOB_CRL 的配置位PB1 对应 bit[7:4]。LED 极性确认本实验外接三只 LED 为共阴极接法高电平点亮板载 PC13 LED 为共阳极接法低电平点亮两者极性相反。四灯版程序中已分别用不同宏处理不可混用。若外接灯实际接成共阳极则需将外接灯 ON/OFF 宏的 BSRR/BRR 操作互换。限流电阻不可省略LED 必须串联限流电阻否则电流过大可能烧毁 LED 或 MCU 引脚。外接 LED 推荐 220Ω~1kΩ板载 LED 已由厂家焊接限流电阻无需额外处理。烧录后验证烧录四灯版程序后若板载 PC13 LED 能按 1 秒间隔闪烁即说明时钟配置、GPIO 配置、延时函数、代码烧录均已正常工作。原工程兼容性本代码基于原子哥标准例程寄存器版本工程修改保留了sys_stm32_clock_init()和delay_init()/delay_ms()的调用。若在其他工程中使用需确保 SYSTEM 文件夹下的 sys.c、delay.c 已加入工程并正确配置头文件包含路径。寄存器移位必须是 4 的倍数CRL/CRH 中每个引脚占 4 位配置引脚 n 时移位量必须为 n×4CRL或 (n-8)×4CRH。移位量不是 4 的倍数会跨越引脚边界破坏相邻引脚配置。八、附录寄存器地址速查表寄存器地址本实验用途RCC_APB2ENR0x40021018使能 GPIOA/B/C 端口时钟bit2/3/4GPIOA_CRL0x40010800配置 PA0 为推挽输出 50MHzbit[3:0]0x3GPIOB_CRL0x40010C00配置 PB0 为推挽输出 50MHzbit[3:0]0x3GPIOC_CRH0x40011004配置 PC13bit[23:20]、PC14bit[27:24]为推挽输出 50MHzGPIOA_ODR0x4001080CPA0 输出数据可直接读写本实验未用GPIOB_ODR0x40010C0CPB0 输出数据GPIOC_ODR0x4001100CPC13/PC14 输出数据GPIOA_BSRR0x40010810PA0 位设置/清除原子操作外接灯高电平点亮GPIOB_BSRR0x40010C10PB0 位设置/清除GPIOC_BSRR0x40011010PC13/PC14 位设置/清除GPIOA_BRR0x40010814PA0 位清除输出低电平外接灯熄灭GPIOB_BRR0x40010C14PB0 位清除GPIOC_BRR0x40011014PC13/PC14 位清除PC13 低板载灯亮PC14 低蓝灯灭SysTick_CTRL0xE000E010SysTick 控制寄存器延时函数使用SysTick_LOAD0xE000E014SysTick 重装载值寄存器SysTick_VAL0xE000E018SysTick 当前值寄存器