一般MCU开发

准备

FT232HL模块

淘宝上买,或者PDD,咸鱼,自己做也行

FT2332也行,反正用有FTDI的MPSSE功能的

VScode -- Visual Studio Code

VS Code + PlatformIO = 开发 ESP32,RP2040

VS Code + Verilog 插件 = 编写 FPGA 逻辑代码

VS Code + C/C++ 插件 = 普通单片机 C 程序

Visual Studio Code - Windows官方下载 | 微软应用商店 | Microsoft Store

OPENOCD -- Open On-Chip Debugger

一款开源的片上调试与编程工具-- 穷人的 Lauterbach

OpenOCD下载安装保姆级教程(附安装包,非常详细)-阿里云开发者社区

Zadig -- Windows USB 驱动安装工具

Zadig - USB driver installation made easyZadig - USB driver installation made easy

第一步——给FT232HL换Windows USB 驱动

插上FT232H 模块

电脑的识别有时候不好辨认

可以下载FT专用驱动 

===官网的点一下就行

https://ftdichip.com/wp-content/uploads/2025/03/CDM2123620_Setup.zip

===按照步骤来FTDI FT232驱动下载安装 高速转换器UIC系列驱动安装详细教程_ftdi串口驱动-CSDN博客

打开Zidag安装USB驱动

===点Options --> List All Devices

按照图中的指示配置

===点击Replace Driver之后,会显示成功,这样一来,Windows的USB驱动已经在FT232HL上安装好了

===如果想变回出厂驱动,直接右键删掉

第二步——将FT232模块与单片机连接

先看FT232HL的数据手册

FT232HL-REEL -PDF数据手册-参考资料-立创商城

看MPSSE那一栏

对应连接你的开发板或者芯片引脚

MCU的电源最好单独供电,别用模块的PC电源,但是别忘了共地

    好的,这样一来我们就完成了硬件层的工作,下面就要在OPENOCD上配置FT232HL和MCU了

    第三步——在OPENOCD上配置.cfg文件

    下载并解压

    文件路径不要有中文

    里面的OPENOCD文件是这样的

    OpenOCD 本身没有图形窗口,是命令行程序,用来驱动 FT232/J-Link/DAPLink,做 JTAG/SWD 调试

    i.  点开bin文件,先进入CMD

    左键点击地址栏,就是图片中最上面有很多箭头的,左键后会变成蓝色的,在键盘上输入CMD,紧接着点击键盘上的Enter会跳转到专用的命令提示符

     这里就是OPENOCD的运行区域

    ii.  配置调试器和MCU芯片的.cfg文件

    OPENOCD厂商已经写好了,你要去找到你需要的,我们这里的MCU以STM32F103为例,也可以换成你需要的,这里有很多对应的资源

    这里是对.cfg文件的解释

    我们主要用interface 和 target

    找到ft232h-module-swd.cfg,按照下图修改,把transport select   swd改成jtag

    再改个名字ft232h-module-jtag.cfg

    transport select jtag = 告诉 OpenOCD:底层 MPSSE 硬件走 JTAG 时序引擎

    D:\openocd-0.11_mingw64_msys2_repack\bin>环境写入指令,必须保证接线无误

    "D:\openocd-0.11_mingw64_msys2_repack\bin\openocd.exe"

    -s "D:\openocd-0.11_mingw64_msys2_repack\share\openocd\scripts"

    -f "interface/ftdi/ft232h-module-jtag.cfg"

    -f "target/stm32f4x.cfg"

    模拟JTAG

    JTAG 或者 SWD

    • FPGA/ZYNQ 开发:只能用 JTAG;
    • STM32、GD32、nRF 等 Cortex-M 单片机:一律用 SWD,省引脚、速度快;
    • 一块板上同时有 FPGA+MCU:JTAG 菊花链,一个下载器调试全部;
    • 小引脚单片机(如 STM32F0/F103C4T6)引脚紧张,必须 SWD
    • 树莓派PICO RP2040也可以用STlink

      JTAG 或者 SWD

    • FPGA/ZYNQ 开发:只能用 JTAG;
    • STM32、GD32、nRF 等 Cortex-M 单片机:一律用 SWD,省引脚、速度快;
    • 一块板上同时有 FPGA+MCU:JTAG 菊花链,一个下载器调试全部;
    • 小引脚单片机(如 STM32F0/F103C4T6)引脚紧张,必须 SWD
    • 树莓派PICO RP2040也可以用STlink

    如果你用STLINK JTAG模块

    调试器换成stlink-v2-1.cfg 或者 jlink.cfg

    • JTAG(IEEE 1149.1):通用标准边界扫描协议,原生四线并行调试;
    • SWD(Serial Wire Debug):ARM 专为 Cortex-M 系列设计的精简串行调试协议,是 JTAG 的轻量化替代方案

    第四步 ——在VScode上开发

    到这里就是在VS平台上开发嵌入式了,无论你是用STLink的SWD协议还是JTAG协议,这都是前面的步骤,接下来我们就来到VScode继续配置

    文件目录格式

    对着截图里面的来

    .bin

    .elf

    .hex

    这三个是我们要生成的文件,这里我已经跑过一次了

    不需要配置

    下载arm-tool-chain 

          Arm GNU Toolchain    

    launch.json

    {
        "version": "0.2.0",
        "configurations": [
            {
                //自己取一个名字
                "name": "烧录并调试 (STM32F407)",
                //先安装 Cortex-Debug 插件
                "type": "cortex-debug",
                "request": "launch",
                "servertype": "openocd",
                "cwd": "${workspaceFolder}",
                "executable": "${workspaceFolder}/build/stm32f407.elf",
                //GDB路径,如果没有安装GDB,请先安装ARM-GCC工具链
                "gdbPath": "D:\ARM-TOOL-CHAIN\xpack-arm-none-eabi-gcc-15.2.1-1.1-win32-x64\xpack-arm-none-eabi-gcc-15.2.1-1.1\bin\arm-none-eabi-gdb.exe"",
                //OpenOCD.exe路径,如果没有安装OpenOCD,在bin目录下找openocd.exe
                "serverpath": "D:/openocd-0.11_mingw64_msys2_repack/bin/openocd.exe",
                //OpenOCD配置文件路径,注意这里是OpenOCD安装目录下的scripts文件夹
                "searchDir": [
                    "D:/openocd-0.11_mingw64_msys2_repack/share/openocd/scripts"
                ],
                //OpenOCD配置文件路径,按照刚刚找到的对应的配置文件路径填写
                "configFiles": [
                    //调试器
                    "interface/ft232h-module-jtag.cfg",
                    //芯片型号
                    "target/stm32f4x.cfg"
                ],
                //调试器端口号,默认是3333
                "runToEntryPoint": "main"
            }
        ]
    }

    c_cpp_properties.json

    {
        "configurations": [
            {
                "name": "STM32F407",
                "includePath": [
                    "${workspaceFolder}/Inc"
                ],
                "defines": [
                    "STM32F407xx",
                    "USE_HAL_DRIVER"
                ],
                "compilerPath": "D:/ARM-TOOL-CHAIN/xpack-arm-none-eabi-gcc-15.2.1-1.1-win32-x64/xpack-arm-none-eabi-gcc-15.2.1-1.1/bin/arm-none-eabi-gcc.exe",
                "cStandard": "c99",
                "intelliSenseMode": "gcc-arm"
            }
        ],
        "version": 4
    }

    ***关于STM32F407的详细说明,可以通过一下资源学习

    野火【STM32F407开发板-霸天虎】
    https://pan.baidu.com/s/11NsIrK254nAGgVn4j9xfkw?pwd=8bSu

    Inc和Src

    复制链接,我这里的是F407HAL和STAD库


    链接:https://pan.quark.cn/s/c1dc6cae9f26?pwd=aanj
    提取码:aanj

    当然你也可以自己找其他的

    选HAL或者STAD(标准库)

    然后放到上面就行

    我们接下来要补齐一些   .h和  .c文件还有  .s(启动文件),  .ld描述文件

    stm32f4xx.s启动汇编文件

    启动文件--gcc 版本

     GCC based toolchains

    cmsis-device-f4/Source/Templates/gcc at master · STMicroelectronics/cmsis-device-f4

    .h头文件寻配

    STM32 HAL库头文件三胞胎stm32f4xx.h---f407.h---f4xx_hal.h解析(区别和联系) - FBshark - 博客园

    可以看看这篇文章理解.h头文件的工作原理

    stm32f4xx.h顶级文件

    cmsis-device-f4/Include/stm32f4xx.h at 2e1724e592931693ce4dfc43e2fd6b3bc375d6a0 · STMicroelectronics/cmsis-device-f4

    再找到你需要的芯片的寄存器映射文件,比如我这里是

    stm32f407xx.h 

    cmsis-device-f4/Include/stm32f407xx.h at 2e1724e592931693ce4dfc43e2fd6b3bc375d6a0 · STMicroelectronics/cmsis-device-f4

    system_stm32f4xx.h   时钟配置

    stm32f4/include/system_stm32f4xx.h at master · elliottt/stm32f4

    在没有配置好makefile之前,顶层头文件会报错

    还有一些core.h支持API文件

    core_cm4.h  

    cmsis_gcc.h

    core_cmInstr.h 

    core_cmSimd.h

    core_cmFunc.h

    CMSIS_4/CMSIS/Include/core_cmInstr.h at master · ARM-software/CMSIS_4

    以上这些带 .h的都放到Inc文件夹

    STM32F407ZGTX_FLASH.ld

    STM32F407ZGTX_FLASH.ld-CSDN博客

    .c文件寻配

    system_stm32f4xx.c

    cmsis-device-f4/Source/Templates/system_stm32f4xx.c at master · STMicroelectronics/cmsis-device-f4

    syscalls.c
    #include <sys/stat.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <signal.h>
    
    extern int errno;
    
    char *__env[1] = { 0 };
    char **environ = __env;
    
    void _exit(int status)
    {
        while (1);
    }
    
    int _close(int file)
    {
        return -1;
    }
    
    int _fstat(int file, struct stat *st)
    {
        st->st_mode = S_IFCHR;
        return 0;
    }
    
    int _isatty(int file)
    {
        return 1;
    }
    
    int _lseek(int file, int ptr, int dir)
    {
        return 0;
    }
    
    int _read(int file, char *ptr, int len)
    {
        return 0;
    }
    
    int _write(int file, char *ptr, int len)
    {
        return len;
    }
    
    int _getpid(void)
    {
        return 1;
    }
    
    int _kill(int pid, int sig)
    {
        errno = EINVAL;
        return -1;
    }
    
    /* 堆内存分配 - 使用链接脚本提供的符号 */
    extern char _end;
    extern char _estack;
    
    void *_sbrk(int incr)
    {
        static char *heap_end = 0;
        char *prev_heap_end;
    
        if (heap_end == 0)
            heap_end = &_end;
    
        prev_heap_end = heap_end;
    
        if (heap_end + incr > &_estack)
        {
            errno = ENOMEM;
            return (void *) -1;
        }
    
        heap_end += incr;
        return (void *) prev_heap_end;
    }

    !!!!!!注意:要写一个main.c文件,不然会报错!!!!!!!

    makefile配置

    当你直接运行 make 时,Makefile 会执行第一个目标。而你的 Makefile 里第一个目标是 $(BUILD_DIR)(创建 build 目录),所以 make 认为 build 目录已存在,就直接结束了

    
    .DEFAULT_GOAL := all
    
    # ====================== 1. 芯片与全局宏(解决#error报错) ======================
    MCU_TARGET = STM32F407xx
    # -D 全局传入芯片宏与HAL库宏,无需在.h里手动定义
    DEFINES = -D$(MCU_TARGET) -DUSE_HAL_DRIVER
    
    # ====================== 2. GCC工具链配置(已填你验证成功的完整路径) ======================
    TOOL_PREFIX := /d/ARM-TOOL-CHAIN/xpack-arm-none-eabi-gcc-15.2.1-1.1-win32-x64/xpack-arm-
    #换上你的GCC工具链地址
    none-eabi-gcc-15.2.1-1.1/bin/arm-none-eabi-
    CC  := $(TOOL_PREFIX)gcc
    AS  := $(TOOL_PREFIX)gcc
    LD  := $(TOOL_PREFIX)gcc
    OBJCPY := $(TOOL_PREFIX)objcopy
    SIZE := $(TOOL_PREFIX)size
    RM  := rm -rf
    MKDIR := mkdir -p
    
    
    # ====================== 3. 内核&编译参数 Cortex-M4 ======================
    CPU_FLAGS = -mcpu=cortex-m4 -mthumb
    FPU_FLAGS = -mfpu=fpv4-sp-d16 -mfloat-abi=hard
    CFLAGS = $(CPU_FLAGS) $(FPU_FLAGS)
    # 编译选项:警告、调试、C99标准
    CFLAGS += -Wall -g3 -O0 -std=c99
    CFLAGS += $(DEFINES)
    # 链接参数:浮点printf、精简库
    LDFLAGS = $(CPU_FLAGS) $(FPU_FLAGS)
    LDFLAGS += --specs=nano.specs -u _printf_float
    LDFLAGS += -TSTM32F407ZGTX_FLASH.ld
    
    # ====================== 4. 头文件搜索路径 ======================
    INCLUDES = \
    -I./Inc \
    -I./Drivers/STM32F4xx_HAL_Driver/Inc \
    -I./Drivers/CMSIS/Device/ST/STM32F4xx/Include \
    -I./Drivers/CMSIS/Include
    
    # ====================== 5. 源文件配置 ======================
    # C源码:Src目录下所有.c文件
    C_SRCS = $(wildcard Src/*.c)
    # 启动汇编文件
    ASM_SRCS = startup_stm32f407xx.s
    #!!!务必对应.s启动文件
    
    # ====================== 6. 编译输出目录与产物 ======================
    BUILD_DIR = build
    # 所有目标.o文件,统一放到build文件夹
    OBJS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SRCS:.c=.o)))
    OBJS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SRCS:.s=.o)))
    TARGET = app
    ELF = $(TARGET).elf
    BIN = $(TARGET).bin
    HEX = $(TARGET).hex
    #这些就是我们用makefile编译好的二进制和十六进制文件了
    
    # ====================== 7. 编译规则(所有命令行首字符为Tab,禁止空格)======================
    # 创建build文件夹
    $(BUILD_DIR):
    	$(MKDIR) $(BUILD_DIR)
    
    # 编译Src下的.c文件
    $(BUILD_DIR)/%.o: Src/%.c | $(BUILD_DIR)
    	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
    
    # 编译启动汇编.s文件
    $(BUILD_DIR)/%.o: %.s | $(BUILD_DIR)
    	$(AS) $(CFLAGS) -c $< -o $@
    
    # 链接生成elf可执行文件
    $(ELF): $(OBJS)
    	$(LD) $(OBJS) $(LDFLAGS) -o $(ELF)
    	$(SIZE) $(ELF)
    
    # 生成bin烧录文件
    $(BIN): $(ELF)
    	$(OBJCPY) -O binary $(ELF) $(BIN)
    
    # 生成hex烧录文件
    $(HEX): $(ELF)
    	$(OBJCPY) -O ihex $(ELF) $(HEX)
    
    # ====================== 8. 顶层命令 ======================
    # 全部编译生成elf/bin/hex
    all: $(ELF) $(BIN) $(HEX)
    
    # 清理编译中间文件与产物
    clean:
    	$(RM) $(BUILD_DIR) $(ELF) $(BIN) $(HEX)
    #下面的是你在OPENOCD的链接硬件的指令,我在上面有提到过,换上对应的烧录器与芯片的配置链接指令
    # OpenOCD一键下载(适配VSCode openocd调试,可直接make flash)
    flash: all
    	openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c "program $(BIN) 0x08000000 verify reset exit"

    第五步——MSYS2 开始编译

    首先我们要确保已经在环境变量里面有这三样

    下载MSYS2    mingw64/32

    MSYS2

    MinGW-w64的安装详细步骤(c/c++的编译器gcc、g++的windows版,win10、win11真实可用)-CSDN博客

    理解三者关系

    # MSYS、MinGW、Makefile 三者完整区别
    先一句话分清定位:
    1. **MinGW**:Windows 下编译 C/C++ 的**GCC编译器套件**(核心是gcc.exe)
    2. **MSYS / MSYS2**:Windows 上一套**类Linux运行环境+Shell工具**(bash、rm、ls、make等)
    3. **Makefile**:**构建脚本文件**,和系统无关,用来告诉 `make` 怎么编译代码
    
    ## 一、MinGW(Minimal GNU for Windows)
    ### 是什么
    把 Linux 的 GCC、g++、ld 等编译工具移植到 Windows,**原生Windows程序**,不依赖Linux内核。
    ### 作用
    - 提供 `gcc.exe`、`g++.exe`、`ar.exe`、`ld.exe` 编译器
    - 编译出来是 `.exe`,可直接双击在Windows运行
    ### 缺点
    - 只有编译器,缺少Linux命令:没有 `bash`、`ls`、`rm`、`make`、`sed`、`git`
    - Windows cmd语法和Linux完全不同,手写Makefile极易报错(路径分隔符`\` vs `/`、换行符差异)
    
    ## 二、MSYS / MSYS2(MinGW配套类Unix环境)
    ### 是什么
    一套轻量POSIX兼容层,自带 **bash shell + 全套Linux工具链**,分为两代:
    - 老MSYS:配套旧MinGW,过时
    - MSYS2:现在主流,自带包管理器pacman,可一键装gcc、cmake、git、python等
    
    ### 和MinGW关系
    MSYS2内部包含**MinGW-w64**(新版MinGW,支持32/64位):
    - MSYS2环境 = Shell工具(bash/make) + MinGW-w64编译器(gcc)
    ### 作用
    1. 提供类Linux终端,支持`ls cd rm mkdir`等命令
    2. 自带`make.exe`,完美解析Linux风格Makefile
    3. 统一路径写法 `/c/Users/xxx`,不用折腾Windows反斜杠
    ### 运行区分(MSYS2三种环境)
    1. **MSYS**:纯POSIX环境,编译Linux风格程序
    2. **MINGW32/MINGW64**:调用MinGW-w64编译器,生成原生Windows exe(日常开发用这个)
    
    ## 三、Makefile
    ### 是什么
    **文本脚本**,是 `make` 工具的配置文件,不属于MinGW/MSYS,Linux/macOS/Windows通用。
    ### 作用
    描述工程编译规则:哪些源文件要编译、依赖关系、编译参数、链接库、清理、打包等。
    示例极简Makefile:
    ```makefile
    all: main
    main: main.c
    	gcc main.c -o main.exe
    clean:
    	rm -f main.exe
    ```
    ### 依赖工具
    必须有 `make` 程序才能执行Makefile:
    - Windows cmd无make,单纯装MinGW用不了Makefile
    - MSYS/MSYS2自带make,直接 `make / make clean`
    
    # 四、三者核心对比表
    | 名称     | 类型               | 核心用途                          | 单独使用可行吗 |
    | -------- | ------------------ | --------------------------------- | -------------- |
    | MinGW    | C/C++编译器(GCC)   | 把C代码编译成Windows exe          | 单独只能编译,不能跑Makefile |
    | MSYS2    | Unix Shell+工具集  | 提供bash、make、git等Linux命令,封装MinGW | 可以独立完整开发C项目 |
    | Makefile | 构建脚本文件       | 定义工程自动编译流程              | 必须搭配make工具,本身无法运行 |
    
    # 五、开发场景关系(完整流程)
    1. 写代码 + 写 **Makefile**
    2. 打开 **MSYS2 MINGW64** 终端(内置MinGW编译器+make)
    3. 执行 `make`:make读取Makefile,调用MinGW的gcc完成编译
    
    # 六、常见误区澄清
    1. 误区:MinGW能跑Makefile
       错。MinGW只有gcc,不带make、bash,cmd里执行make会报“不是内部命令”。
    2. 误区:MSYS就是编译器
       错。MSYS只是终端环境,编译代码还是靠内部的MinGW-w64。
    3. 误区:Makefile是MSYS专属
       错。Linux、macOS、WSL、MSYS2都能用Makefile,只是Windows原生环境缺少make工具。
    
    # 七、最简总结
    - **MinGW = 编译器(造exe的工具)**
    - **MSYS2 = 类Linux工作台(提供终端、make、配套命令,里面自带MinGW)**
    - **Makefile = 编译说明书(告诉make怎么调用gcc编译工程)**

    启动MSYS2.exe

    输入在VScode上的文件地址,改成以下风格

    cd /d/Enbed/OPENOCD-F407

    粘贴到MSYS2.c的工作区

    记住必须右键,不能ctrl+V

    然后输入 

    make clean
    
    make -j4

    就可以开始编译了

    等待编译

    最后输出这种东西就算成功编译,最后生成了二进制和十六进制的文件,让MCU执行

    下一步就是烧录了

    再在刚刚的MSYS2命令窗口输入

    make flash

    就可以烧录你的程序!

    到此为止就完成了!!!

    ARM--XILINX开发

    FPGA---XILINX开发

    更多推荐