3.STM32寄存器点灯实战:从命名规则到GPIO配置全解析

引言:本文面向 STM32 初学者和嵌入式开发入门者,旨在通过一个完整的「点亮 LED」实战项目,帮助读者理解 STM32 的命名规则、GPIO 输入输出模式以及寄存器配置方法。文章从基础概念讲起,逐步深入到数据手册查阅、寄存器操作和代码实现,最终带领读者完成从原理分析到实际点灯的全过程。阅读本文后,你将掌握使用寄存器直接控制 STM32 GPIO 的核心方法,为后续学习更复杂的嵌入式开发打下坚实基础。

一、STM32命名规则

1、产品系列
STM32 表示 ST 公司品牌下 Cortex-Mx 平台架构的 32 位处理器系列

2、产品类型
F:基础型,通用型
A:汽车级别
L:低功耗
S:标准型
T:触摸感应
W:无线产品
G:F 的升级款,同等资源的 F1/3/4 芯片提供更多的增强型外设
C:低成本,高性价比

3、产品特定功能-子系列
050:ARM Cortex-M0 内核,
051:ARM Cortex-M0 内核,入门级
100:ARM Cortex-M3 内核,超值型,外设资源相对较少
101:ARM Cortex-M3 内核,基本型,
102:ARM Cortex-M3 内核,USB
103:ARM Cortex-M3 内核,增强型,含 USB
303:是 103 的升级版,带 DSP 和模拟外设
105:ARM Cortex-M3 内核,USB 互联网型
107:ARM Cortex-M3 内核,USB 互联网型+以太网型
108:ARM Cortex-M3 内核,IEEE802.15.4 标准
151:ARM Cortex-M3 内核,无 LCD 资源
152/162:ARM Cortex-M3 内核,LCD 资源
407:ARM Cortex-M4 内核高性能,带 DSP 和浮点运算
415/417:ARM Cortex-M4 内核高性能

4、芯片引脚数量
D->14, F->20, E->25&24, G->28, K->32, T->36, H->40, S->44, C->48&49;
U->63, R->64&66; J->72; M->80; O->90; V->100; Q->132; Z->144; A->169;
I->176&176+25; B->208; N->216; X->256;
汽车级
8->48
9->64
A->80

5、闪存容量
0 --> 1KB; 1 --> 2KB; 2 --> 4KB; 3 --> 8KB; 4 --> 16KB; 5 --> 25KB; 6 --> 32KB;
7 --> 48KB; 8 --> 64KB; 9 --> 72KB; A --> 96KB; B --> 128KB; Z --> 192KB;
C --> 256KB; D --> 384KB; E --> 512KB; F --> 768KB; G --> 1024KB;
H --> 1536KB; I --> 2048KB;

6、封装类型
B- plastic DIP
D- ceramic DIP
G- ceramic QFP
H-LFBGA/TFBGA
I-UFBGA pitch 0.5mm
J-UFBGA pitch 0.8mm
K-UFBGA pitch 0.65mm
M-plastic SOP,SO
P-TSSOP
Q-plastic QFP
T-QFP
U-UFQFPN
V-VFQFPN
Y-WLCSP

7、工作温度
6&A : -40~85℃;
7&B : -40~105℃;
3&C : -40~125℃;
D : -40~150℃;
————————————————
以上文本为优快云博主「Jonathan_NYF」的原创文章。
原文链接:https://blog.youkuaiyun.com/qq_39747958/article/details/134931252

注意:如有需要更详细的说明请移步该博主文章;

二、点亮学海的那盏灯

电路及基础分析

任务需求:点亮发光二极管
需要PC13引脚输出高电平1;

三、根据任务需求查看数据手册

下面我们先来分析一下基本输入输出模式;

输入模式

浮空输入

优点:电平完全由外部决定

缺点:当外部电平不稳定时,对系统是灾难性的

自行在单片机外部接一个上拉电阻

上拉输入

当外部电路电压不稳定时,打开上拉电阻(MCU内部提供)可提供一个稳定的高电平

下拉输入

当外部电路提供电压时,打开下拉电阻可提供一个稳定的低电平

模拟输入

输出

推挽输出

(输出数据寄存器置一则IO口置一;反之置零)

P-MOS(栅极低电平导通)处于可导通的状态;此时IO口接vdd(高电平)

N-MOS(栅极高电平导通)处于可导通的状态;此时IO口接vss(低电平)

开漏输出

P-MOS不工作

开漏本身不能输出高电平,但如果想输出的话

可使用打开内部上拉或者外接上拉电阻实现,外接输出电平更加灵活

复用开漏

复用推挽

总结

共八种输入输出模式

浮空输入

上拉输入

下拉输入

模拟输入

推挽输出

开漏输出

复用推挽

复用开漏

根据本次项目需求找到对应开发用到的引脚(本次以PC2为例),根据数据手册来配置引脚;

1.采用配置寄存器方式完成;

要操作寄存器直接控制,首先,先参考数据手册看看点亮LED需要进行什么配置;

为了方便理解,直接截图放到此处;

点灯操作步骤:

1、看实物找自己想点亮的灯

2、看原理图-分析电路原理(高电平亮还是低电平亮、接到哪一个引脚)

3、配置为输出模式

4、配置为推挽输出或者开漏输出

5、配置输出速度

6、输出数据0、1(ODR)

步骤:

根据原理图分析LED18对应的网络标签为PC2 ; 且低电平点亮;

先配置端口模式(MODE->输出模式(01/10/11);CNF->推挽输出(00)(可以输出0/1));

端口输出数据使用输出数据寄存器(ODR);

具体实现:

1.PC2选用低寄存器->配置为输出模式,推挽输出;

*(volatile unsigned int *)0x40011000 |=(1<<8);// 配置CRL寄存器bit8=1:MODE1[1:0]的bit0置1,配合bit9=0,将PC2配置为输出模式(速度10MHz)
*(volatile unsigned int *)0x40011000 &=~(1<<9);// 配置CRL寄存器bit9=0:MODE1[1:0]的bit1置0,与bit8=1组合为01,即输出模式、最大速度10MHz
*(volatile unsigned int *)0x40011000 &=~(1<<10);// 配置CRL寄存器bit10=0:CNF1[1:0]的bit0置0,与bit11=0组合为00,即通用推挽输出
*(volatile unsigned int *)0x40011000 &=~(1<<11);// 配置CRL寄存器bit11=0:CNF1[1:0]的bit1置0,与bit10=0组合为00,即通用推挽输出
运算过程

*(volatile unsigned int *)0x40011000 |=(1<<8);//1 对应位设置为1 但是不影响其他位

当前值为 0x40011000 处的寄存器地址:

  原值:         xxxx xxxx xxxx xxxx 
| 掩码 0x100:   0000 0001 0000 0000 
   -------------------------------- 
  结果:         xxxx xxx1 xxxx xxxx 
                        ↑ 第8位被强制置1,其余位保持不变

因为或运算的特性:1 | 任何位 = 1,0 | 任何位 = 原值,所以只会把目标位设为 1,其他位不受影响——这正是注释里说的"对应位设置为1,但是不影响其他位"。

补充说明

严格来说,直接写 0x40011000 |= ... 在 C 语言里不能通过编译(常量不能作为左值)。实际工程中通常写成指针解引用的形式;

其中 volatile 是为了防止编译器优化掉对硬件寄存器的读写。

RCC时钟使能
  • 找RCC相关寄存器 这里看下GPIOC连到了哪个总线上

  • 找到相关寄存器

  • 分析寄存器这个位置需要写1使能GPIOC端口

  • 找RCC这个寄存器的地址

偏移地址 0x18

基地址:在第二章存储器映射

寄存器地址=0x40021000+0x18=0x40021018

*(volatile unsigned int *)0x40021018 |=(1<<4);

这行代码和之前原理相同,都是通过绝对地址直接操作硬件寄存器,把目标位置 1。

逐段拆解

*(volatile unsigned int *)0x40021018 |= (1 << 4);

部分

含义

0x40021018

寄存器的物理地址

(volatile unsigned int *)

把这个整数地址强制转换为「指向 unsigned int 的指针」

*

解引用指针,即操作该地址里存的值

|= (1 << 4)

把第 4 位(bit4)置 1,其他位不变

运算过程

1 << 4 = 0x10 = 二进制 0001 0000,即只有第 4 位是 1。

寄存器原值: xxxx xxxx xxxx xxxx 
| 掩码0x10: 0000 0000 0001 0000 
--------------------------------- 
结果:       xxxx xxxx xxx1 xxxx 
                         ↑ 第4位被置1

0x40021018 是 STM32 系列中 RCC(复位和时钟控制)外设 的地址区间,具体是 RCC_APB2ENR(APB2 外设时钟使能寄存器)。1 << 4 对应 bit4,在 STM32F1 系列中该位通常是 IOPCEN(GPIOC 端口时钟使能)。

所以这行代码的实际意图是:

使能 GPIOC 端口的时钟——在使用 GPIOC 之前必须先打开它的时钟,否则外设不工作。

  • 完整的模式配置(输出模式、推挽输出)

*(volatile unsigned int *)0x40021018 |=(1<<4);//RCC时钟使能
*(volatile unsigned int *)0x40011000 |=(1<<8);//1 对应位设置为1 但是不影响其他位
*(volatile unsigned int *)0x40011000 &=~(1<<9);//写0 目的最终配置为输出模式
*(volatile unsigned int *)0x40011000 &=~(1<<10);//写0 目的最终配置为推挽输出
*(volatile unsigned int *)0x40011000 &=~(1<<11);//写0 目的最终配置为推挽输出
2.配置输出数据寄存器(ODR)

//以下代码二选一,分别实现灯灭以及灯亮的效果;
*(volatile unsigned int *)0x4001100C |=(1<<2);//输出1
*(volatile unsigned int *)0x4001100C &=~(1<<2);//输出0
3.添加.s启动文件
;******************** (C) COPYRIGHT 2017 STMicroelectronics ********************
;* File Name          : startup_stm32f103xe.s
;* Author             : MCD Application Team
;* Description        : STM32F103xE Devices vector table for MDK-ARM toolchain. 
;*                      This module performs:
;*                      - Set the initial SP
;*                      - Set the initial PC == Reset_Handler
;*                      - Set the vector table entries with the exceptions ISR address
;*                      - Configure the clock system
;*                      - Branches to __main in the C library (which eventually
;*                        calls main()).
;*                      After Reset the Cortex-M3 processor is in Thread mode,
;*                      priority is Privileged, and the Stack is set to Main.
;******************************************************************************
;* @attention
;*
;* Copyright (c) 2017-2021 STMicroelectronics.
;* All rights reserved.
;*
;* This software is licensed under terms that can be found in the LICENSE file
;* in the root directory of this software component.
;* If no LICENSE file comes with this software, it is provided AS-IS.
;*
;******************************************************************************
; Amount of memory (in bytes) allocated for Stack
; Tailor this value to your application needs
; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Stack_Size		EQU     0x400
            AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp
; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size      EQU     0x200
            AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit
            PRESERVE8
            THUMB
; Vector Table Mapped to Address 0 at Reset
AREA    RESET, DATA, READONLY
EXPORT  __Vectors
EXPORT  __Vectors_End
EXPORT  __Vectors_Size
__Vectors       DCD     __initial_sp               ; Top of Stack
DCD     Reset_Handler              ; Reset Handler
DCD     NMI_Handler                ; NMI Handler
DCD     HardFault_Handler          ; Hard Fault Handler
DCD     MemManage_Handler          ; MPU Fault Handler
DCD     BusFault_Handler           ; Bus Fault Handler
DCD     UsageFault_Handler         ; Usage Fault Handler
DCD     0                          ; Reserved
DCD     0                          ; Reserved
DCD     0                          ; Reserved
DCD     0                          ; Reserved
DCD     SVC_Handler                ; SVCall Handler
DCD     DebugMon_Handler           ; Debug Monitor Handler
DCD     0                          ; Reserved
DCD     PendSV_Handler             ; PendSV Handler
DCD     SysTick_Handler            ; SysTick Handler
            ; External Interrupts
            DCD     WWDG_IRQHandler            ; Window Watchdog
            DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
            DCD     TAMPER_IRQHandler          ; Tamper
            DCD     RTC_IRQHandler             ; RTC
            DCD     FLASH_IRQHandler           ; Flash
            DCD     RCC_IRQHandler             ; RCC
            DCD     EXTI0_IRQHandler           ; EXTI Line 0
            DCD     EXTI1_IRQHandler           ; EXTI Line 1
            DCD     EXTI2_IRQHandler           ; EXTI Line 2
            DCD     EXTI3_IRQHandler           ; EXTI Line 3
            DCD     EXTI4_IRQHandler           ; EXTI Line 4
            DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1
            DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2
            DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3
            DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4
            DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5
            DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6
            DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7
            DCD     ADC1_2_IRQHandler          ; ADC1 &amp; ADC2
            DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX
            DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0
            DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1
            DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE
            DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5
            DCD     TIM1_BRK_IRQHandler        ; TIM1 Break
            DCD     TIM1_UP_IRQHandler         ; TIM1 Update
            DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation
            DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare
            DCD     TIM2_IRQHandler            ; TIM2
            DCD     TIM3_IRQHandler            ; TIM3
            DCD     TIM4_IRQHandler            ; TIM4
            DCD     I2C1_EV_IRQHandler         ; I2C1 Event
            DCD     I2C1_ER_IRQHandler         ; I2C1 Error
            DCD     I2C2_EV_IRQHandler         ; I2C2 Event
            DCD     I2C2_ER_IRQHandler         ; I2C2 Error
            DCD     SPI1_IRQHandler            ; SPI1
            DCD     SPI2_IRQHandler            ; SPI2
            DCD     USART1_IRQHandler          ; USART1
            DCD     USART2_IRQHandler          ; USART2
            DCD     USART3_IRQHandler          ; USART3
            DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
            DCD     RTC_Alarm_IRQHandler        ; RTC Alarm through EXTI Line
            DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
            DCD     TIM8_BRK_IRQHandler        ; TIM8 Break
            DCD     TIM8_UP_IRQHandler         ; TIM8 Update
            DCD     TIM8_TRG_COM_IRQHandler    ; TIM8 Trigger and Commutation
            DCD     TIM8_CC_IRQHandler         ; TIM8 Capture Compare
            DCD     ADC3_IRQHandler            ; ADC3
            DCD     FSMC_IRQHandler            ; FSMC
            DCD     SDIO_IRQHandler            ; SDIO
            DCD     TIM5_IRQHandler            ; TIM5
            DCD     SPI3_IRQHandler            ; SPI3
            DCD     UART4_IRQHandler           ; UART4
            DCD     UART5_IRQHandler           ; UART5
            DCD     TIM6_IRQHandler            ; TIM6
            DCD     TIM7_IRQHandler            ; TIM7
            DCD     DMA2_Channel1_IRQHandler   ; DMA2 Channel1
            DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2
            DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3
            DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 &amp; Channel5
__Vectors_End
__Vectors_Size  EQU  __Vectors_End - __Vectors
            AREA    |.text|, CODE, READONLY
; Reset handler
Reset_Handler   PROC
EXPORT  Reset_Handler             [WEAK]
IMPORT  __main
IMPORT  SystemInit
LDR     R0, =SystemInit
BLX     R0
LDR     R0, =__main
BX      R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler     PROC
EXPORT  NMI_Handler                [WEAK]
B       .
ENDP
HardFault_Handler
PROC
EXPORT  HardFault_Handler          [WEAK]
B       .
ENDP
MemManage_Handler
PROC
EXPORT  MemManage_Handler          [WEAK]
B       .
ENDP
BusFault_Handler
PROC
EXPORT  BusFault_Handler           [WEAK]
B       .
ENDP
UsageFault_Handler
PROC
EXPORT  UsageFault_Handler         [WEAK]
B       .
ENDP
SVC_Handler     PROC
EXPORT  SVC_Handler                [WEAK]
B       .
ENDP
DebugMon_Handler
PROC
EXPORT  DebugMon_Handler           [WEAK]
B       .
ENDP
PendSV_Handler  PROC
EXPORT  PendSV_Handler             [WEAK]
B       .
ENDP
SysTick_Handler PROC
EXPORT  SysTick_Handler            [WEAK]
B       .
ENDP
Default_Handler PROC
EXPORT  WWDG_IRQHandler            [WEAK]
EXPORT  PVD_IRQHandler             [WEAK]
EXPORT  TAMPER_IRQHandler          [WEAK]
EXPORT  RTC_IRQHandler             [WEAK]
EXPORT  FLASH_IRQHandler           [WEAK]
EXPORT  RCC_IRQHandler             [WEAK]
EXPORT  EXTI0_IRQHandler           [WEAK]
EXPORT  EXTI1_IRQHandler           [WEAK]
EXPORT  EXTI2_IRQHandler           [WEAK]
EXPORT  EXTI3_IRQHandler           [WEAK]
EXPORT  EXTI4_IRQHandler           [WEAK]
EXPORT  DMA1_Channel1_IRQHandler   [WEAK]
EXPORT  DMA1_Channel2_IRQHandler   [WEAK]
EXPORT  DMA1_Channel3_IRQHandler   [WEAK]
EXPORT  DMA1_Channel4_IRQHandler   [WEAK]
EXPORT  DMA1_Channel5_IRQHandler   [WEAK]
EXPORT  DMA1_Channel6_IRQHandler   [WEAK]
EXPORT  DMA1_Channel7_IRQHandler   [WEAK]
EXPORT  ADC1_2_IRQHandler          [WEAK]
EXPORT  USB_HP_CAN1_TX_IRQHandler  [WEAK]
EXPORT  USB_LP_CAN1_RX0_IRQHandler [WEAK]
EXPORT  CAN1_RX1_IRQHandler        [WEAK]
EXPORT  CAN1_SCE_IRQHandler        [WEAK]
EXPORT  EXTI9_5_IRQHandler         [WEAK]
EXPORT  TIM1_BRK_IRQHandler        [WEAK]
EXPORT  TIM1_UP_IRQHandler         [WEAK]
EXPORT  TIM1_TRG_COM_IRQHandler    [WEAK]
EXPORT  TIM1_CC_IRQHandler         [WEAK]
EXPORT  TIM2_IRQHandler            [WEAK]
EXPORT  TIM3_IRQHandler            [WEAK]
EXPORT  TIM4_IRQHandler            [WEAK]
EXPORT  I2C1_EV_IRQHandler         [WEAK]
EXPORT  I2C1_ER_IRQHandler         [WEAK]
EXPORT  I2C2_EV_IRQHandler         [WEAK]
EXPORT  I2C2_ER_IRQHandler         [WEAK]
EXPORT  SPI1_IRQHandler            [WEAK]
EXPORT  SPI2_IRQHandler            [WEAK]
EXPORT  USART1_IRQHandler          [WEAK]
EXPORT  USART2_IRQHandler          [WEAK]
EXPORT  USART3_IRQHandler          [WEAK]
EXPORT  EXTI15_10_IRQHandler       [WEAK]
EXPORT  RTC_Alarm_IRQHandler        [WEAK]
EXPORT  USBWakeUp_IRQHandler       [WEAK]
EXPORT  TIM8_BRK_IRQHandler        [WEAK]
EXPORT  TIM8_UP_IRQHandler         [WEAK]
EXPORT  TIM8_TRG_COM_IRQHandler    [WEAK]
EXPORT  TIM8_CC_IRQHandler         [WEAK]
EXPORT  ADC3_IRQHandler            [WEAK]
EXPORT  FSMC_IRQHandler            [WEAK]
EXPORT  SDIO_IRQHandler            [WEAK]
EXPORT  TIM5_IRQHandler            [WEAK]
EXPORT  SPI3_IRQHandler            [WEAK]
EXPORT  UART4_IRQHandler           [WEAK]
EXPORT  UART5_IRQHandler           [WEAK]
EXPORT  TIM6_IRQHandler            [WEAK]
EXPORT  TIM7_IRQHandler            [WEAK]
EXPORT  DMA2_Channel1_IRQHandler   [WEAK]
EXPORT  DMA2_Channel2_IRQHandler   [WEAK]
EXPORT  DMA2_Channel3_IRQHandler   [WEAK]
EXPORT  DMA2_Channel4_5_IRQHandler [WEAK]
WWDG_IRQHandler
PVD_IRQHandler
TAMPER_IRQHandler
RTC_IRQHandler
FLASH_IRQHandler
RCC_IRQHandler
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
DMA1_Channel1_IRQHandler
DMA1_Channel2_IRQHandler
DMA1_Channel3_IRQHandler
DMA1_Channel4_IRQHandler
DMA1_Channel5_IRQHandler
DMA1_Channel6_IRQHandler
DMA1_Channel7_IRQHandler
ADC1_2_IRQHandler
USB_HP_CAN1_TX_IRQHandler
USB_LP_CAN1_RX0_IRQHandler
CAN1_RX1_IRQHandler
CAN1_SCE_IRQHandler
EXTI9_5_IRQHandler
TIM1_BRK_IRQHandler
TIM1_UP_IRQHandler
TIM1_TRG_COM_IRQHandler
TIM1_CC_IRQHandler
TIM2_IRQHandler
TIM3_IRQHandler
TIM4_IRQHandler
I2C1_EV_IRQHandler
I2C1_ER_IRQHandler
I2C2_EV_IRQHandler
I2C2_ER_IRQHandler
SPI1_IRQHandler
SPI2_IRQHandler
USART1_IRQHandler
USART2_IRQHandler
USART3_IRQHandler
EXTI15_10_IRQHandler
RTC_Alarm_IRQHandler
USBWakeUp_IRQHandler
TIM8_BRK_IRQHandler
TIM8_UP_IRQHandler
TIM8_TRG_COM_IRQHandler
TIM8_CC_IRQHandler
ADC3_IRQHandler
FSMC_IRQHandler
SDIO_IRQHandler
TIM5_IRQHandler
SPI3_IRQHandler
UART4_IRQHandler
UART5_IRQHandler
TIM6_IRQHandler
TIM7_IRQHandler
DMA2_Channel1_IRQHandler
DMA2_Channel2_IRQHandler
DMA2_Channel3_IRQHandler
DMA2_Channel4_5_IRQHandler
B       .
ENDP
        ALIGN
;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
IF      :DEF:__MICROLIB
EXPORT  __initial_sp
EXPORT  __heap_base
EXPORT  __heap_limit
         ELSE
     IMPORT  __use_two_region_memory
     EXPORT  __user_initial_stackheap
__user_initial_stackheap
LDR     R0, =  Heap_Mem
LDR     R1, =(Stack_Mem + Stack_Size)
LDR     R2, = (Heap_Mem +  Heap_Size)
LDR     R3, = Stack_Mem
BX      LR
ALIGN
     ENDIF
 END&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;
4.完整项目代码
void SystemInit(void);
int main(void)
{
*(volatile unsigned int *)0x40021018 |=(1<<4);//RCC时钟使能 C
*(volatile unsigned int *)0x40021018 |=(1<<2);//RCC时钟使能 A
*(volatile unsigned int *)0x40011000 |=(1<<8);//1 对应位设置为1 但是不影响其他位
*(volatile unsigned int *)0x40011000 &=~(1<<9);//写0 目的最终配置为输出模式  推挽输出  速度10MHZ
*(volatile unsigned int *)0x4001100C |=(1<<2);//输出1
*(volatile unsigned int *)0x4001100C &=~(1<<2);//输出0
return 0;
}
void SystemInit(void)
{
}
添加进工程即可编译下载;
至此用寄存器点亮LED即可完成;

总结:本文通过点亮 LED 的实战项目,完整演示了使用寄存器操作 STM32 GPIO 的流程。回顾整个点灯步骤:首先查看原理图确认 LED 对应的引脚(本例为 PC2,低电平点亮);然后使能 GPIOC 端口时钟,通过 RCC_APB2ENR 寄存器(地址 0x40021018)的 bit4 置 1 实现;接着配置端口模式,通过 CRL 寄存器(地址 0x40011000)将 PC2 配置为输出模式、推挽输出、速度 10MHz;最后通过输出数据寄存器 ODR(地址 0x4001100C)的 bit2 写入 0 或 1 来控制灯的亮灭。关键寄存器配置可归纳为:RCC_APB2ENR 使能时钟、CRL 配置模式、ODR 输出数据。掌握这套寄存器操作思路,就能举一反三,灵活控制 STM32 的其他外设。

四、常见问题与排查

在点灯实战过程中,初学者经常会遇到编译报错、LED 不亮、引脚配置错误等问题。下面针对这些高频问题给出原因分析和解决方法,并附上调试建议。

1. 编译错误

问题现象:编译时报错,例如 lvalue required as left operand of assignment 或 undefined symbol。

原因分析:

  • 直接对常量地址使用 0x40011000 |= ... 这类写法,在 C 语言中常量不能作为左值,无法通过编译。
  • 缺少启动文件(.s 文件)或启动文件未正确添加到工程中,导致链接阶段报 undefined symbol 错误。
  • 头文件路径配置错误,或未包含必要的寄存器定义头文件。

解决方法:

  • 将寄存器操作改写为指针解引用形式:*(volatile unsigned int *)0x40011000 |= (1 << 8);,其中 volatile 防止编译器优化掉对硬件寄存器的读写。
  • 确认已将 startup_stm32f103xe.s 启动文件添加到工程,并正确配置了芯片型号(如 STM32F103C8T6 对应 STM32F103xE 系列)。
  • 检查编译器的 Include Path 是否包含标准外设库或寄存器定义所在目录。

2. LED 不亮

问题现象:程序编译下载成功,但 LED 始终不亮。

原因分析:

  • 未使能对应端口的时钟。GPIOC 端口时钟未打开时,寄存器配置不生效,外设不工作。
  • 引脚配置错误,例如把 PC2 误配成输入模式,或 CNF 位配置成了开漏输出。
  • 输出电平与电路不匹配。本例中 LED18 是低电平点亮,若向 ODR 写入 1(高电平),灯反而不会亮。
  • 硬件连接问题,如 LED 正负极接反、限流电阻缺失或引脚虚焊。

解决方法:

  • 确认已执行 *(volatile unsigned int *)0x40021018 |= (1 << 4); 使能 GPIOC 时钟。
  • 核对 CRL 寄存器配置,确保 PC2 为输出模式(MODE=01)、推挽输出(CNF=00)。
  • 根据原理图确认点亮电平。本例为低电平点亮,应向 ODR 的 bit2 写入 0:*(volatile unsigned int *)0x4001100C &= ~(1 << 2);。
  • 用万用表测量 PC2 引脚电压,检查 LED 及限流电阻是否正常,确认硬件连接无误。

3. 引脚配置错误

问题现象:配置了 PC2 但实际控制的是其他引脚,或引脚无输出。

原因分析:

  • 寄存器位操作错误,例如移位位数算错,把 bit8 写成 bit7,导致配置到了相邻引脚。
  • 使用了错误的寄存器地址,例如把 CRL(0x40011000)与 CRH(0x40011004)混淆。PC2 属于低 8 位引脚,应使用 CRL;若配置 PC8-PC15 则需使用 CRH。
  • ODR 寄存器地址写错,或操作位与引脚号不对应。

解决方法:

  • 对照数据手册逐位核对寄存器配置。PC2 对应 CRL 寄存器的 bit8-bit11(MODE1 和 CNF1),ODR 对应 bit2。
  • 确认引脚编号与寄存器位一一对应:PC0-PC7 使用 CRL,PC8-PC15 使用 CRH。
  • 建议使用调试器(如 ST-Link)在 Keil 中查看寄存器的实时值,确认配置是否写入成功。

4. 调试建议

  • 分步验证:先单独使能时钟,再配置模式,最后输出数据,每步都用调试器观察寄存器值是否符合预期。
  • 使用调试器:在 Keil MDK 中进入 Debug 模式,打开 Peripherals 窗口查看 GPIO 和 RCC 寄存器的实时状态,快速定位配置是否生效。
  • 简化电路:排查硬件问题时,可先用万用表直接测量引脚电平,排除 LED 或电阻故障的干扰。
  • 对照参考代码:将完整项目代码与本文示例逐行对比,重点检查时钟使能、CRL 配置和 ODR 输出三处关键代码。
  • 善用搜索:遇到报错时,将错误信息复制到搜索引擎或 优快云 社区搜索,通常能找到同类问题的解决方案。
STM32介绍 STM32是ST公司基于ARM Cortex-M内核开发的32位微控制器;STM32常应用在嵌入式领域,如智能车、无人机、机器人、无线通讯、物联网、工业控制、娱乐电子产品等;STM32F1系列是主流系列,有177的内核跑分和72Mhz的Cortex-M3内核;类型中S代表电源,I代表输入,O代表输出,IO代表输入输出I/O口电平:代表IO口所能容忍的电压;有FT代表能容忍5V的电压,没有FT只能容忍3.3V的电压。如果没有FT的需要接5V的电平,就需要加装电平转换电路了主功能。 阅读详情

相关推荐

STM32单片机入门:从Cortex-M内核选型到GPIO串口实战全解析

在嵌入式开发领域,单片机(MCU)是硬件与软件交汇的核心,而STM32作为基于ARM Cortex-M内核的32位微控制器,凭借其丰富的产品线、成熟的工具链和庞大的生态,已成为工程师从入门到量产的首选之一。理解MCU的基本工作原理,从GPIO控制、串口通信到定时器PWM,是掌握嵌入式系统的基础;而Cortex-M系列从M0到M7的差异,则决定了项目的计算能力上限。无论是点亮LED、打印串口数据,还是驱动电机、采集ADC,STM32都能提供稳定高效的解决方案。本文从内核架构、产品命名到开发环境搭建,系统梳理S

weixin_34357436的博客 332

STM32嵌入式开发入门:从内核选型到实战点灯全解析

微控制器(MCU)是嵌入式系统的核心,基于ARM Cortex-M内核的STM32系列凭借高性价比和丰富外设成为行业主流。其原理是通过集成CPU、内存及多种通信接口,实现对外部电路的精准控制。掌握STM32开发不仅能快速构建智能硬件原型,还能深入理解实时控制与低功耗设计。在物联网、工业自动化及消费电子等领域,STM32应用广泛。本文从内核架构、产品线选型到开发环境搭建与实操流程,系统讲解STM32入门知识,帮助开发者避开常见坑点,高效上手嵌入式开发。

weixin_34326179的博客 371

STM32选型与工程实战:从命名规则到时钟串口调试避坑指南

嵌入式开发中,芯片选型往往决定项目成本与性能边界。理解MCU命名规则和产品系列定位,是快速匹配需求的基础。STM32家族庞大的型号体系看似复杂,但核心差异集中在主频、Flash、外设资源和功耗定位上。工程开发阶段,STM32CubeMX简化了初始化配置,HAL库提升了代码可移植性,而时钟树配置、串口中断接收、调试器接口选择则是实际项目中最常见的三道坎。从传感器采集到电机控制,从FreeRTOS到LVGL界面,STM32拥有覆盖各类应用场景的成熟生态。本文结合实际项目经验,梳理了从选型、建工程到调试避坑的完整

weixin_30861459的博客 426

STM32 使用操作内存地址点灯

初识stm32 St 意法半导体 SOC 产商(使用Arm内核进行外设产品开发) Arm Arm Ip授权商(开内核标准提供给SOC产商使用) 32 即是32 位 32bit M 微控制器 (stc ,stm,NXp,Inter87系列,Atme...

chucedan9177的博客 421

STM32从入门到实战:内核、外设与开发全解析

微控制器(MCU)是嵌入式系统的核心,基于ARM Cortex-M内核的32位MCU因性能与生态优势成为主流。其原理是通过统一内核架构与分层外设设计,实现代码复用与灵活扩展,技术价值在于平衡性能、功耗与开发效率。在工业控制、物联网节点、电机驱动等场景中,MCU需处理GPIO、中断、DMA、ADC及通信外设的协同工作。STM32作为典型代表,凭借丰富的家族系列和成熟工具链,大幅降低了开发门槛。掌握时钟树配置、中断优先级管理及DMA搬运等实操要点,是构建稳定数据采集与实时控制系统的关键。

weixin_33847182的博客 274

STM32最小系统板引脚功能全解析(嵌入式硬件基础)

本文全面解析STM32最小系统板的引脚功能,涵盖电源管理、时钟配置、复位机制和GPIO工作模式等嵌入式硬件基础。重点详解GPIO引脚的8种工作模式、电气特性及实际应用技巧,帮助开发者高效使用STM32进行嵌入式开发与硬件设计。

git9versioner的博客 857

STM32入门:从芯片选型到CubeMX点灯串口实战

STM32是基于ARM Cortex-M内核的32位微控制器,以高性价比、丰富外设和成熟生态成为嵌入式领域的常用选择。其型号命名蕴含着内核、引脚、存储与封装信息,正确理解命名规则与选型逻辑,是硬件开发的第一步。在开发层面,HAL库配合STM32CubeMX图形化配置工具,可大幅降低寄存器操作门槛,提升初始化代码生成效率,让工程师更专注于业务逻辑。该组合适用于工业控制、智能硬件、毕业设计等常见场景,也是从8位单片机进阶到专业平台的主流路径。本文以STM32F103C8T6为例,演示从环境搭建、引脚配置到LED

weixin_34232744的博客 493

Linux云服务器上搭建《僵尸毁灭工程》私服全流程指南(避坑版)

本文详细介绍了在Linux云服务器上搭建《僵尸毁灭工程》私服的全流程指南,包括环境准备、SteamCMD安装、游戏服务器部署、内存优化配置及高级调优技巧。特别针对常见问题提供解决方案,帮助玩家快速搭建稳定的私服环境。

solidity8miner的博客 604

STM32CubeIDE入门指南:从工程创建到配置,轻松实现点灯

在嵌入式开发领域,集成开发环境的选择直接影响开发效率。STM32CubeIDE作为ST官方推出的免费IDE,将图形化配置、代码生成与编译调试整合于一体,改变了传统Keil下手动组织工程的模式。理解其“图形化配置+自动生成代码”的核心原理,是快速上手的关键。通过配置时钟树、GPIO引脚及外设中间件,开发者无需手写初始化代码即可生成可编译的工程,这大大降低了STM32入门门槛。本文从工程创建的基本流程出发,详细讲解MCU选型、时钟配置、代码生成规则与烧录调试,帮助初学者从零搭建一个可运行的点灯工程,为后续串口通

weixin_33884611的博客 435

高级Salesforce开发面试题

自定义设置允许您创建自定义数据集,以及为组织、配置文件或特定用户创建和关联自定义数据。自定义元数据类似于自定义设置,但是自定义元数据类型中的记录被视为元数据而不是数据。自定义设置有列表和层次自定义设置两种。自定义元数据中没有此类类型。此外,自定义元数据不支持基于用户配置文件或特定用户的层次结构类型的数据。自定义设置现在不再支持关系字段。但您可以在自定义元数据对象之间创建查找。元数据查询不占用查询sql次数的限制。

weixin_45663522的博客 1246

《Zephyr OS 入门与实战》第3章:第一个 Zephyr 程序 - Blinky 实战

解决方法:确认设备树overlay文件已正确加载。返回值,确认驱动初始化状态。

2301_79143213的博客 541

STM32单片机从入门到实战:选型、开发与调试全解析

在嵌入式开发中,单片机是构建智能硬件的基础,而32位单片机凭借更强的计算能力和丰富的外设资源,已成为工程实践的主流选择。Cortex-M内核通过统一的内存映射和调试接口,大幅降低了从8位平台迁移的学习成本,同时完善的HAL库和图形化配置工具让开发者能快速完成时钟、GPIO等底层初始化,将精力集中在应用逻辑上。技术价值不仅体现在性能提升,更在于生态成熟带来的高开发效率与低试错成本。实际应用中,从物联网节点到工业控制,不同场景对主频、功耗、引脚数量的需求差异明显,因此选型需综合性能阈值、功耗场景与供应链稳定性。

weixin_34342992的博客 397

具身智能(26):RDK S100的LeRobot或Agile X piper机械臂控制模型

本文档详细介绍了基于ROS2的机器人控制模型架构与标定数据联动机制。核心采用"感知-规划-控制"闭环流程,通过激光雷达、相机和IMU的融合数据实现厘米级定位(≤1cm)。文档包含两大控制模型配置:1)RDKLeRobot模型,重点说明PID参数调节和标定文件路径设置;2)AgileXPiper模型,强调驱动安装与外部标定文件集成。针对常见问题提供解决方案,如控制指令无响应需验证标定路径,运动偏差过大需重新标定等。最后给出批量部署方案,通过复制基准配置文件实现多机器人快速配置,要求定位偏差

码农17年的博客 179

GPIO调试实战:当Keil逻辑分析仪遇见STM32的‘信号交响曲’

本文深入探讨了使用Keil逻辑分析仪进行STM32 GPIO调试的实战技巧。通过多引脚协同调试案例,解析如何可视化信号时序、诊断硬件异常,并提供了基于信号分析的功耗与代码优化策略,帮助开发者从基础调试进阶至复杂系统可靠性提升。

ios99的博客 625

DBeaver配置本地mysql-connector驱动文件

本文摘要:介绍了数据库驱动管理的基本操作步骤:1)新建驱动管理器,填写MySQL驱动名称、类名和类型;2)添加本地MySQL驱动文件;3)创建数据库连接并测试。适用于MySQL5.x和8.x版本,帮助用户快速配置数据库连接。

litlit023的专栏 1698

PCB仿真软件:Altium Designer_(15).AltiumDesigner的版本控制与项目管理

在进行PCB设计时,版本控制和项目管理是确保设计质量和团队协作效率的关键。Altium Designer 提供了强大的版本控制和项目管理功能,可以帮助设计团队更好地管理和维护项目。本节将详细介绍如何在Altium Designer中进行版本控制和项目管理,包括如何使用版本控制系统、如何管理项目文件、如何进行团队协作等。

kkchenjj的博客 1204

2024年最新STM32单片机简介

STM32是ST公司基于ARM Cortex-M内核开发的32位微控制器。STM32常应用在嵌入式领域,如智能车、无人机、机器人、无线通信、物联网、工业控制、娱乐电子产品等。STM32功能强大、性能优异、片上资源丰富、功耗低,是一款经典的嵌入式微控制器。High Performance:高性能系列Mainstream:主流系列Ultra-low-power:超低功耗系列Wireless:无线系列CoreMark:内核跑分,分数越高,性能越好ARM既指ARM公司,也指ARM处理器内核。

m0_74194018的博客 4200

华为od 面试手撕代码题【完成任务最少小时】

华为od 面试手撕代码题【完成任务最少小时】

MISAYAONE的博客 1583

STM32入门教程,第2课,STM32简介

本课程详细介绍了STM32F103C8T6微控制器的基本特性和应用。主要内容包括:1)STM32F1系列的基本参数和ARM Cortex-M3内核;2)片上资源与外设功能详解,如GPIO、定时器、ADC、通信接口等;3)芯片命名规则、系统结构和电源管理;4)引脚定义和最小系统电路设计要点;5)启动模式配置方法;6)配套最小系统板电路原理和实物说明。课程资料提供了百度网盘下载链接,适合STM32初学者系统学习硬件基础知识和外设应用开发。

欢迎关注,一起进步! 1419

【系统架构设计师-2025上半年真题】综合知识-参考答案及详解(75题完全回忆版)

【系统架构设计师-2025上半年真题】案例分析-参考答案及部分详解

数据知道的博客 1万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

STM32CubeMX 6.14入门:从下载安装到点灯调试实战指南

嵌入式开发中,外设初始化向来是新手入门的痛点,传统方式需要手查寄存器,配置复杂且易出错。随着图形化配置工具的出现,芯片初始化从手动写代码变成可视化的参数配置,大幅提升开发效率。STM32CubeMX作为ST官方推出的配置工具,通过图形化界面自动生成HAL库初始化代码,帮助开发者将精力聚焦业务逻辑。本文以STM32CubeMX 6.14为例,覆盖从官网下载、安装、固件包预载,到新建工程、时钟树与GPIO/串口配置,再到生成代码与Keil联调点灯的完整路径,并分享常见踩坑与排查方法,适合入门STM32或希望摆脱

weixin_33922672的博客 457

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

STM32嵌入式开发全解析:从内核选型到实战调试

在嵌入式系统开发中,微控制器(MCU)的选型与编程是核心环节。基于ARM Cortex-M内核的32位MCU因其高效能与低功耗被广泛应用,其原理在于通过精简指令集与丰富外设实现实时控制。掌握MCU的架构差异、外设配置及调试技巧,能显著提升开发效率与系统稳定性。从智能家居到工业自动化,这类芯片支撑着海量应用场景。STM32作为典型代表,其家族谱系、开发环境搭建及外设编程细节,正是嵌入式开发者从入门到进阶的关键路径。

weixin_34413103的博客 306

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

STM32从入门到实战:架构解析、选型指南与避坑手册

微控制器(MCU)是嵌入式系统的核心,其选型与开发直接影响项目成败。基于ARM Cortex-M内核的STM32系列,凭借丰富外设与成熟生态,成为工业控制、消费电子及边缘AI的主流平台。理解内核架构、掌握GPIO、ADC、DMA等外设原理,是构建稳定嵌入式应用的基础。在实际工程中,开发环境搭建、通信接口调试与低功耗设计等环节常遇挑战。本文从一线从业者视角,系统梳理STM32的架构逻辑、选型策略与高频问题排查思路,帮助开发者建立清晰的认知框架,提升工程实践效率。

weixin_33889665的博客 316

DAY7嵌入式学习 STM32F103C8T6 裸机寄存器开发: EXTI 外部中断原理、寄存器配置与按键点灯实战

while (1)/* 不停检查 PA0 是否被按下 */这称为轮询。而使用中断时,CPU 不需要持续查询按键状态。当 PA0 出现指定的电平变化时,EXTI 硬件可以产生中断请求。CPU 在满足中断响应条件后,自动跳转到对应的中断服务函数执行。GPIO 输入变化 → EXTI 检测边沿 → EXTI 产生中断请求 → NVIC 接收并仲裁 → CPU 执行 ISR → 返回原程序。EXTI:External Interrupt/Event Controller,外部中断/事件控制器。NVIC。

fxy_be_my_lover的博客 320

STM32入门指南:从选型到开发环境,再到点灯与调试避坑

单片机(MCU)是把CPU、存储与外设集成于单芯片的微型计算机,广泛渗透于智能硬件、工业控制与物联网终端。作为ARM Cortex-M内核的代表,STM32凭借低功耗、强实时性与丰富外设,成为嵌入式开发最热门的入门与量产选择。理解其时钟树、GPIO、串口、PWM与ADC等基础外设原理,再配合CubeMX图形化配置与HAL库,可大幅降低开发门槛。从最小系统搭建到在线调试,开发者需掌握选型逻辑与常见故障排查,才能真正实现从点灯实验到产品级项目的跨越。本文结合实际工程经验,系统梳理STM32的学习路线与关键避坑点

weixin_34174322的博客 324

从STM32到STC32G:GPIO、PWM、ADC迁移实战与避坑指南

在嵌入式开发领域,STM32凭借成熟生态长期占据主流地位,然而近年来的芯片价格波动与供货不稳定,促使越来越多开发者开始关注国产替代方案。STC32G作为增强型51内核芯片,配合逐飞开源库,提供了接近STM32标准库的封装接口,大幅降低了迁移门槛。本文从基础外设操作切入,系统对比STM32与STC32G在GPIO模式、PWM产生方式、ADC采样时序等核心功能上的差异,并结合实际工程经验,详细讲解点灯、电机调速、舵机控制、数据采集等典型应用场景的实现方法。同时,针对引脚配置冲突、时钟频率偏差、调试手段差异等常见

weixin_34117211的博客 377
上一篇: 2.STM32开发方式全解析:寄存器、HAL库、LL库与STD库怎么选?
下一篇: 4.STM32 驱动 74HC138 译码器点亮 LED:寄存器配置与程序优化实战
硅基造物主
博客等级 码龄4年 17粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值