01-环境搭建.md 10 KB

01-环境搭建

STM32 简介

项目 参数
内核 ARM Cortex-M3 (ARMv7-M)
主频 72MHz (HSE 8MHz PLL 9倍频)
SRAM 20KB
Flash 64KB
封装 LQFP48
电压 2.0V~3.6V (典型 3.3V)
温度 -40℃~+85℃

Cortex-M3 特性:Thumb-2 指令集、硬件乘除法、64MHz→72MHz PLL、位带操作、SysTick 定时器、NVIC 中断嵌套。

片上外设总览

graph TD
    subgraph CORE
        ARM_CORTEX_M3["ARM Cortex-M3<br/>72MHz"]
    end
    
    subgraph BUS
        ICODE["ICode Bus<br/>(Flash Instruction)"]
        DCODE["DCode Bus<br/>(Flash Data)"]
        SYSTEM["System Bus<br/>(SRAM/FSMC)"]
        AHB["AHB<br/>72MHz"]
        APB2["APB2<br/>72MHz"]
        APB1["APB1<br/>36MHz"]
    end
    
    subgraph PERIPHERALS_APB2
        GPIO_A["GPIO A/B/C/D/E"]
        USART1["USART1"]
        SPI1["SPI1"]
        TIM1["TIM1 (高级)"]
        ADC1["ADC1/2"]
        EXTI["EXTI"]
        AFIO["AFIO"]
    end
    
    subgraph PERIPHERALS_APB1
        TIM2_4["TIM2/3/4 (通用)"]
        TIM5_7["TIM5/6/7"]
        USART2_3["USART2/3"]
        SPI2_3["SPI2/3"]
        I2C1_2["I2C1/2"]
        PWR["PWR"]
        BKP["BKP"]
        IWDG["IWDG"]
        WWDG["WWDG"]
        RTC["RTC"]
        DMA["DMA"]
        CAN["CAN"]
        USB["USB"]
    end
    
    ARM_CORTEX_M3 --> ICODE
    ARM_CORTEX_M3 --> DCODE
    ARM_CORTEX_M3 --> SYSTEM
    SYSTEM --> AHB
    AHB --> APB2
    AHB --> APB1
    APB2 --> PERIPHERALS_APB2
    APB1 --> PERIPHERALS_APB1

系统总线结构

总线 频率 连接
ICode 72MHz Cortex-M3 → Flash(指令)
DCode 72MHz Cortex-M3 → Flash(数据)
System 72MHz Cortex-M3 → SRAM / FSMC
AHB 72MHz 桥接 APB2 / APB1 / DMA / RCC
APB2 72MHz 高速外设 (GPIO, USART1, SPI1, TIM1, ADC, EXTI, AFIO)
APB1 36MHz 低速外设 (TIM2~7, USART2/3, SPI2/3, I2C1/2, PWR, BKP, IWDG, WWDG, RTC, DMA, CAN, USB)

注意:APB1 最高 36MHz,如需 72MHz 必须使用 APB2。

引脚定义 (LQFP48)

graph TD
    subgraph LQFP48_top
        direction LR
        PD0["PD0 (OSC_IN)"] --- PD1["PD1 (OSC_OUT)"]
        PD1 --- NRST["NRST"]
        NRST --- PC13["PC13 (TAMPER-RTC)"]
    end

功能引脚速查

引脚 默认功能 复用功能
PA0 GPIO TIM2_CH1_ETR / USART2_CTS / WKUP / ADC12_IN0
PA1 GPIO TIM2_CH2 / USART2_RTS / ADC12_IN1
PA2 GPIO TIM2_CH3 / USART2_TX / ADC12_IN2
PA9 GPIO USART1_TX / TIM1_CH2
PA10 GPIO USART1_RX / TIM1_CH3
PB6 GPIO I2C1_SCL / TIM4_CH1
PB7 GPIO I2C1_SDA / TIM4_CH2
PB8 GPIO I2C1_SCL / TIM4_CH3
PB9 GPIO I2C1_SDA / TIM4_CH4
PC13 GPIO RTC_TAMPER

完整引脚序号

编号 引脚 编号 引脚 编号 引脚 编号 引脚
1 PE2(VDD_1) 13 PA13(SWDIO) 25 PA0 37 PB9
2 PE3(VSS_1) 14 PA14(SWCLK) 26 PA1 38 PB8
3 NRST 15 PA15(JTDI) 27 PA2 39 BOOT0
4 PC13 16 PB3(JTDO) 28 ... 40 PB7
5 PC14(OSC32_IN) 17 PB4(JNTRST) ... ... 41 PB6
6 PC15(OSC32_OUT) 18 PB5 ... ... ... ...

BOOT 启动配置

BOOT1 BOOT0 启动区域
X 0 主Flash (0x08000000)
0 1 系统存储器(System Loader, 0x1FFF0000)
1 1 内嵌SRAM (0x20000000)

实际使用:BOOT0=0 (接GND) 从Flash启动。ISP下载时:BOOT0=1, BOOT1=0。

最小系统电路

graph TD
    subgraph POWER
        VDD33["VDD (3.3V)"] --> VDD1["VDD_1"]
        VDD33 --> VDD2["VDD_2"]
        VDD33 --> VDDA["VDDA"]
        VSS1["VSS_1"] --> GND["GND"]
        VSS2["VSS_2"] --> GND
        VSSA["VSSA"] --> GND
    end
    
    subgraph OSCILLATOR
        HSE["8MHz HSE"] --> X1["X1<br/>PD0(OSC_IN)"]
        HSE --> X2["X2<br/>PD1(OSC_OUT)"]
        LSE["32.768kHz LSE"] --> X32_IN["PC14(OSC32_IN)"]
        LSE --> X32_OUT["PC15(OSC32_OUT)"]
    end
    
    subgraph RESET
        NRST_PIN["NRST"] --> R10k["10kΩ → 3.3V"]
        NRST_PIN --> C100nF["100nF → GND"]
    end
    
    subgraph BOOT
        BOOT0_PIN["BOOT0"] --> R10k_GND["10kΩ → GND"]
    end
元件 参数 备注
HSE 晶振 8MHz + 20pF ×2 主时钟源
LSE 晶振 32.768kHz + 12.5pF ×2 RTC 时钟源
复位电容 100nF NRST 对地
复位上拉 10kΩ NRST 接 3.3V
去耦电容 100nF × N 每个 VDD/VSS 对各放一个

开发环境

工具 用途
Keil MDK v5.38+ 编译环境 (AC5 / AC6)
STM32F1xx_DFP Keil 器件包
ST-Link Utility / STM32CubeProgrammer 调试下载
CH340 / FT232 串口 ISP 下载 (FlyMcu)
USB-TTL 模块 串口通信

标准库工程搭建步骤

1. 固件库文件下载

从 ST 官网下载 STM32F10x_StdPeriph_Lib_V3.5.0 或更高版本。

2. 目录结构

Project/
├── CMSIS/
│   ├── core_cm3.c
│   ├── core_cm3.h
│   ├── startup_stm32f10x_md.s
│   ├── stm32f10x.h
│   ├── system_stm32f10x.c
│   └── system_stm32f10x.h
├── STM32F10x_StdPeriph_Driver/
│   ├── inc/              (所有外设头文件)
│   └── src/              (所有外设源文件)
├── User/
│   ├── main.c
│   ├── stm32f10x_conf.h
│   ├── stm32f10x_it.c
│   └── stm32f10x_it.h
└── Output/               (编译输出)

3. 关键宏定义

Keil C/C++ Compiler → Define:

USE_STDPERIPH_DRIVER, STM32F10X_MD
说明
USE_STDPERIPH_DRIVER 启用标准外设驱动库
STM32F10X_MD Medium Density (64KB~128KB Flash, C8T6 用此)
STM32F10X_HD High Density (256KB~512KB Flash)
STM32F10X_CL Connectivity Line (STM32F105/107)

4. 启动文件选择

Flash容量 芯片后缀 启动文件
16~32KB C4/C6/T4/T6 startup_stm32f10x_ld.s
64~128KB C8/CB/T8/TB startup_stm32f10x_md.s
256~512KB RC/RE/RF/VC/VE/VF/ZC/ZE/ZF startup_stm32f10x_hd.s
768KB~1MB RG/VG/ZG startup_stm32f10x_xl.s

C8T6 → startup_stm32f10x_md.s(中容量)

5. Keil 分组设置

Project Targets:
├── Startup
│   └── startup_stm32f10x_md.s
├── StdPeriph
│   ├── misc.c
│   ├── stm32f10x_gpio.c
│   ├── stm32f10x_rcc.c
│   ├── stm32f10x_tim.c
│   ├── stm32f10x_usart.c
│   ├── stm32f10x_exti.c
│   ├── stm32f10x_i2c.c
│   ├── stm32f10x_spi.c
│   ├── stm32f10x_adc.c
│   ├── stm32f10x_dma.c
│   ├── stm32f10x_pwr.c
│   ├── stm32f10x_bkp.c
│   └── stm32f10x_flash.c
├── User
│   ├── main.c
│   ├── stm32f10x_it.c
│   ├── system_stm32f10x.c
│   └── Delay.c
└── Doc
    └── readme.txt

6. C/C++ 头文件路径

$PROJ_DIR$\CMSIS
$PROJ_DIR$\STM32F10x_StdPeriph_Driver\inc
$PROJ_DIR$\User

7. 魔术棒设置

Tab 设置
Device STM32F103C8
Target Xtal: 8.0MHz, Use Cross-Module Optimization
Output Select Folder for Objects... → Output
Listing Select Folder for Listings... → Output
Debug ST-Link Debugger → Settings → SW

启动文件流程

Reset_Handler
  → SystemInit()           (system_stm32f10x.c)
    → RCC配置: HSE→PLL(x9)→SYSCLK=72MHz
    → AHB/APB1/APB2 分频器设置
    → Flash 预取缓冲/等待周期配置
  → __main                  (C库初始化)
    → 变量初始化 (ZI/BSS清零, RW复制)
    → 跳转 main()

SystemInit 时钟树 (默认配置 HSE 8MHz)

HSE (8MHz)
  → PLLSRC (HSE)
  → PLLMUL (x9)
  → PLLCLK = 8MHz × 9 = 72MHz
  → SYSCLK = 72MHz
  → AHB Prescaler (/1) → HCLK = 72MHz
    → APB1 Prescaler (/2) → PCLK1 = 36MHz
    → APB2 Prescaler (/1) → PCLK2 = 72MHz
  → ADC Prescaler (/6) → ADCCLK = 12MHz

SysTick 延时函数

SysTick 是 Cortex-M3 内核的 24 位递减计数器,挂载在 AHB (72MHz)。

// Delay.h
#ifndef __DELAY_H
#define __DELAY_H

#include "stm32f10x.h"

void Delay_Init(void);
void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);

#endif

// Delay.c
#include "Delay.h"

static uint32_t fac_us;
static uint32_t fac_ms;

void Delay_Init(void)
{
    fac_us = SystemCoreClock / 1000000;         // 72
    fac_ms = SystemCoreClock / 1000;            // 72000
}

void Delay_us(uint32_t us)
{
    uint32_t load = us * fac_us;
    // 最大 2^24-1 = 16777215, us 超出会复位
    if (load > 0xFFFFFF) return;
    
    SysTick->LOAD = load - 1;
    SysTick->VAL = 0;
    SysTick->CTRL = 0x01;                       // 使能, 不中断, 使用 HCLK
    while (!(SysTick->CTRL & (1 << 16)));       // 等待 COUNTFLAG
    SysTick->CTRL = 0;                          // 关闭
}

void Delay_ms(uint32_t ms)
{
    while (ms--) {
        Delay_us(1000);
    }
}

或用轮回方式(简单无 SysTick 冲突):

void Delay_ms(uint32_t ms)
{
    uint32_t i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 7200; j++);    // 72MHz 实测约 1ms
}

编译与下载

ST-Link 方式(推荐)

  1. 连接 SWD: PA13(SWDIO), PA14(SWCLK), GND, 3.3V(可选供电)
  2. Keil → Flash → Download (Ctrl+F8)
  3. 使用 ST-Link Utility 或 STM32CubeProgrammer 也可以

ISP 串口下载 (FlyMcu)

  1. BOOT0=1, BOOT1=0 → 上电/复位 → 进入系统 Loader
  2. 使用 CH340/FT232 USB-TTL 连接 PA9(TX)→模块RX, PA10(RX)→模块TX
  3. FlyMcu 选择串口, 勾选"编程后校验", 下载
  4. 下载完成后 BOOT0=0 → 复位 → 从 Flash 启动

常见坑点/注意事项

  1. 启动文件选错 — C8T6 用 _md.s,用 _hd.s 会导致 FLASH 地址映射错误无法运行
  2. 忘记添加 USE_STDPERIPH_DRIVER — 编译报错 stm32f10x.h 不包含外设定义
  3. 忘记添加 STM32F10X_MD — 外设寄存器地址映射错误
  4. C/C++ 头文件路径未配置 — 找不到 stm32f10x.h
  5. 晶振频率与 SystemInit 不符 — 8MHz 用 PLL×9=72MHz;如用 12MHz 晶振需改成 PLL×6 或改配置(HSE_VALUE 宏)
  6. SysTick 优先级 — 默认内核优先级最高,会影响 HAL_Delay 等;标准库手动实现无冲突
  7. ST-Link 驱动 — Win10/11 可能需禁用驱动签名或安装旧版驱动
  8. ISP 下载失败 — 检查 BOOT0/BOOT1 电平,串口 TX/RX 交叉连接,波特率不宜过高(115200或57600)