STM32(10)-- 创建库函数版工程

1. 新建本地工程文件夹

2. 移植库函数文件

1)

固件库中的CMSIS和Driver文件夹复制到工程中的Libraries文件夹中,

并删除无用的文件

2)

将固件库中官方提供的示例程序中,复制中断相关的函数移植到本地工程的User文件夹中

并删除stm32f4xx_it.c中的一些代码

3. 开始新建工程

打开keil 5新建工程,选择新建的keil5工程的存储位置并命名,选择芯片型号

4. 添加组文件夹

5. 给组文件夹添加文件

5.1 StartUp组文件按夹

在此文件夹中添加汇编写的启动文件,当前使用的芯片是stm32f407

5.2 CMSIS组文件夹

添加内核相关的文件,单片机系统初始化、配置时钟的文件

5.3 FWLB组文件夹

添加全部的固件库的文件

5.4 USER组文件夹

添加中断相关的文件

创建main.c文件

选择创建的文件的存储位置

6.添加头文件路径

以上在给组文件夹移植文件时,都只添加了.c文件,并没有添加.h文件

keil5的魔术棒处可批量添加头文件位置

7.添加宏处理

8. 设置文件是否加入编译

下方调试时也会提到,把stm32f4xx_fmc.c也不加入编译。

9. 编译验证

10. 修改调试

编写main函数后,编译验证

在我编译后,会报错和警告

core_cmFunc.h(629): error: unknown register name 'vfpcc' in asm

这基本可以断定是 CMSIS 版本和你当前用的编译器(toolchain)不匹配 导致的。


vfpcc 这个报错是怎么来的?

vfpccARMCC5(Keil 旧编译器) 那套内联汇编写法里用的 clobber 名称。

但你现在的编译输出风格更像 GCC/Clang(ARM Compiler 6 / armclang) ,这些编译器不认识 "vfpcc" 这个 clobber,于是直接报错。

✅ 结论:你工程里的 CMSIS 头文件(core_cmFunc.h)是偏 ARMCC5 的老版本/写法,但你项目用的却是 GCC 或 ARM Compiler 6(armclang)

  • stm32f4xx_fmc.c: identifier "FMC_BCR1_BURSTEN" is undefined

  • FMC_BWTR1_ADDSET / ADDHLD / DATAST / BUSTURN / ACCMOD ... is undefined

  • FMC_Bank1E / FMC_Bank1 / FMC_Bank2 ... is undefined

  • 你工程把 stm32f4xx_fmc.c 编进去了,但你当前这套头文件/芯片分支对 F407 没把 FMC 那套宏打开 ,所以 stm32f4xx_fmc.c 里用到的 FMC_BCR1_* / FMC_Bank* 全部 undefined。

    而你库里同时有 stm32f4xx_fsmc.cstm32f4xx_fmc.c ,说明 ST 这套库同时兼容两种命名/外设差异,但对某个具体芯片只能用其中一个,不能两个都无脑加进工程。


    你该怎么选(对 STM32F407 来说)

    STM32F407 的外部存储控制器通常是 FSMC (老命名/老寄存器宏体系),而 FMC 更常见于 F42x/F43x 等系列(以及后续统一命名的库)。

    ✅ 所以对你现在的情况,最稳的处理是:

    ✅ 方案 1(推荐):只保留 FSMC,移除 FMC

  • 从工程里 Remove stm32f4xx_fmc.c(只从工程移除,不用删文件)

  • 保留 stm32f4xx_fsmc.c(如果你要用外扩 SRAM/NOR/LCD 才需要;不需要就也可以不加)

  • 重新编译

  • 为什么会这样(通俗解释)

    stm32f4xx_fmc.c 里面写的是 "FMC_* 宏/寄存器名",这些宏通常在对应的头文件分支里才会定义。

    但你现在编译到的 stm32f4xx.h / stm32f4xx_fmc.h 并没有给 F407 提供那套 FMC_* 定义,于是 .c 文件里引用它们就全炸了。

    你现在只是 main 里 while(1),FSMC/FMC 都不需要 ,所以最简单是两个都别加;但你只要不编译 fmc.c,那堆 undefined 就会立刻消失。
    警告:incompatible redefinition of macro "DBGMCU_APB2_FZ_DBG_TIMx_STOP" (declared at line xxxx)

它不是"你写错了代码",而是 ST 的 stm32f4xx.h 里有一组宏被重复定义了两次,而且定义值还不一样 (所以编译器报 incompatible redefinition)。

比如这类宏本来用于"调试时冻结 TIM 定时器"的 DBGMCU 功能:

  • DBGMCU_APB2_FZ_DBG_TIM1_STOP

  • DBGMCU_APB2_FZ_DBG_TIM8_STOP

  • DBGMCU_APB2_FZ_DBG_TIM9_STOP

  • DBGMCU_APB2_FZ_DBG_TIM10_STOP

  • DBGMCU_APB2_FZ_DBG_TIM11_STOP

在某些 ST 的头文件版本里,这几个宏有一段写法类似"把 APB2 的宏映射到 APB1 的宏",导致重复定义/值不一致,于是 ARMCC5 就一直警告。

✅ 结论:这是 固件库(header)本身的历史/兼容性问题,不是你工程配置"混库"的唯一证据(当然混库也可能导致更多重复定义,但你这张图看起来就是同一个文件内的重复定义)。

同一个文件里把同一批宏定义了两次,而且第二次(Legacy aliases)把 APB2 的宏错误地映射到了 APB1 的宏,所以 ARMCC 报 "incompatible redefinition"。

你这里的结构是:

  • 11574~11578:正确的 APB2 位定义(数值 0x00000001 / 0x00000002 / 0x00010000...)

  • 11581~11585 :又把同名宏重新 #defineDBGMCU_APB1_FZ_DBG_TIMx_STOP(这明显不对:APB2 不应该 alias 到 APB1)

所以每次包含 stm32f4xx.h 都会产生 5 条 warning,累计就 200+。


推荐修法(最干净,warning 清零,语义也正确)

stm32f4xx.h 里把 "Legacy aliases" 这 5 行改成 不覆盖已有定义

把 11580~11585 这一段改成这样(加 #ifndef 防重定义):

cpp 复制代码
/* Legacy aliases */
#ifndef DBGMCU_APB2_FZ_DBG_TIM1_STOP
#define DBGMCU_APB2_FZ_DBG_TIM1_STOP   DBGMCU_APB1_FZ_DBG_TIM1_STOP
#endif
#ifndef DBGMCU_APB2_FZ_DBG_TIM8_STOP
#define DBGMCU_APB2_FZ_DBG_TIM8_STOP   DBGMCU_APB1_FZ_DBG_TIM8_STOP
#endif
#ifndef DBGMCU_APB2_FZ_DBG_TIM9_STOP
#define DBGMCU_APB2_FZ_DBG_TIM9_STOP   DBGMCU_APB1_FZ_DBG_TIM9_STOP
#endif
#ifndef DBGMCU_APB2_FZ_DBG_TIM10_STOP
#define DBGMCU_APB2_FZ_DBG_TIM10_STOP  DBGMCU_APB1_FZ_DBG_TIM10_STOP
#endif
#ifndef DBGMCU_APB2_FZ_DBG_TIM11_STOP
#define DBGMCU_APB2_FZ_DBG_TIM11_STOP  DBGMCU_APB1_FZ_DBG_TIM11_STOP
#endif

这样做的效果是:

  • 由于前面 11574~11578 已经定义过了,#ifndef 会阻止再次定义

  • warning 直接消失

  • 保留了"如果某些老芯片头文件没给 APB2 定义时,还能兜底 alias"的意图

  • 你也可以更激进:直接把 11581~11585 这 5 行删掉/注释掉。

    但加 #ifndef 更"温和",更不容易引入别的兼容性问题

相关推荐
2501_918126917 小时前
stm32做一个次声波检测器,需要哪些元件
stm32·单片机·嵌入式硬件·学习·个人开发
加斯顿工程师9 小时前
STM32F103C8T6驱动SRF05超声波测距传感器程序
stm32·单片机·嵌入式硬件
姜太公钓鲸23310 小时前
STM32F1有72MHz的Cortex-M3内核。72MHZ是什么意思?指的是什么?
stm32·单片机·嵌入式硬件
染不尽的流年10 小时前
热噪声、散粒噪声、闪烁噪声介绍
嵌入式硬件·测试机
国科安芯10 小时前
医疗成像设备系统电源芯片国产替代可行性研究
网络·单片机·嵌入式硬件·fpga开发·硬件架构
不是AI11 小时前
【电路仿真】【Logisim】二、7408 TTL
单片机·fpga开发
炸膛坦客12 小时前
FreeRTOS 学习:(二十九)任务切换的底层逻辑(了解)
单片机·操作系统·freertos
思茂信息12 小时前
基于CST 3D Combined功能的以太网口RE仿真
开发语言·javascript·单片机·嵌入式硬件·matlab·3d
染不尽的流年14 小时前
散粒噪声的电压密度
单片机·嵌入式硬件
17(无规则自律)16 小时前
你对 argc 和 argv 的理解有多深?
linux·c语言·嵌入式硬件·考研