从头搭建一个STM34F407的固件库工程模板

前言

要验证一些基础代码,为了防止由于现有工程实现有问题。
想从自己干净的工程开始验证。
先从头搭一个STM34F407固件库模板。

已经搭好的STM32F407固件库模板下载点

project_template_stm32f407_stdlib.7z

试验

从0开始搭建一个STM34F4的固件库模板
	参照STM32F4开发指南-库函数版本_V1.1.pdf
	自己从头作一遍, 会感觉自己的工程模板很干净, 没有未知和多余的东西

ST官方固件库下载首页
	https://www.st.com/en/embedded-software/stm32-standard-peripheral-libraries.html

从ST官方下载了STM32F4的固件库(https://www.st.com/en/embedded-software/stsw-stm32065.html), 当前版本为1.8.0
	保存为 STM32F4xx_DSP_StdPeriph_Lib_V1.8.0_from_ST.7z

新建MDK工程
	MDK代码页选为UTF8
	在MDK中选MCU为STM32F407VGTx, 晶振为8MHZ, 这步要根据自己板子来
	不勾选 "Use MicroLIB"
	加入编译宏选项 STM32F40_41xxx, USE_STDPERIPH_DRIVER, USE_FULL_ASSERT
	在"Flash Download"页面中,选上"Reset and Run", 这样程序下载完,就可以自动运行

在工程下新建4个文件夹:
	/DOC 文档
	/USER 用户代码
	/BSP 板级驱动
	/FWLIB ST固件库
	/CORE CM4接口定义和启动文件

设置头文件路径
	.\CORE;.\FWLIB;.\FWLIB\inc;.\FWLIB\src;.\BSP;.\USER

将ST固件库的文件拷贝进自己的模板工程
	STM32F4xx_DSP_StdPeriph_Lib_V1.8.0_from_ST\Libraries\STM32F4xx_StdPeriph_Driver\inc\* => /FWLIB
	STM32F4xx_DSP_StdPeriph_Lib_V1.8.0_from_ST\Libraries\STM32F4xx_StdPeriph_Driver\src\* => /FWLIB
	\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm\startup_stm32f40_41xxx.s => /CORE
	\Libraries\CMSIS\Include\core_cm4.h => /CORE
	\Libraries\CMSIS\Include\core_cmSimd.h => /CORE
	\Libraries\CMSIS\Include\core_cmFunc.h => /CORE
	\Libraries\CMSIS\Include\core_cmInstr.h => /CORE
	\Libraries\CMSIS\Device\ST\STM32F4xx\Include\* => /USER
	\Project\STM32F4xx_StdPeriph_Templates\main.c => /USER
	\Project\STM32F4xx_StdPeriph_Templates\main.h => /USER
	\Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_conf.h => /USER
	\Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_it.c => /USER
	\Project\STM32F4xx_StdPeriph_Templates\stm32f4xx_it.h => /USER
	\Project\STM32F4xx_StdPeriph_Templates\system_stm32f4xx.c => /USER

将加入的文件全部填入工程管理组
	工程管理组也建立5个文件夹 /DOC, /USER, /BSP, /FWLIB, /CORE
	将实体文件夹的内容添加到工程管理组的文件夹中
	将stm32f4xx_fmc.c从工程管理组/FWLIB中删掉, 这个文件不是F407用的, 否则编译不过
	
修改固件库
	将main函数的官方模板实现挪到新建的函数中备用参考, 现在main函数为空
	// @note ls main_example_by_st() // ST官方的例子
	
	修改时钟配置, 使外部告诉时钟为8MHZ(这个要看自己板子的外部晶振的实际情况)
	修改点在MDK中搜索就行
	
	 // @note ls PLL_M 要修改成8, 才能让系统时钟变成168MHZ
	#define PLL_M      8 /*25*/
	
	// @note ls 晶振频率改为8MHZ
	// #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
	#define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
	
	// @note ls 设置系统时钟, 否则进不了SysTick_Handler
	在main函数中设置系统时钟
	RCC_GetClocksFreq(&RCC_Clocks); // 必须调用RCC_GetClocksFreq(), 才能载入前面修改过的时钟参数
	SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000); // @note ls 168000000(168MHZ) / 1000(微秒) = 1ms 发生一次tick

	// 现在系统tick才是1ms发生一次
	void SysTick_Handler(void)
	{
		// @note ls 一个tick = 1ms
	  TimingDelay_Decrement();
	}
	
	// 根据自己的板子硬件情况, 随便初始化一个可以看出效果的硬件, 看看效果
	
	// LED初始化
	void bsp_Init_led(void)
	{
		GPIO_InitTypeDef GPIO_InitStructure;
		
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); // 使能GPIOE的时钟
		
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 输出
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  // 推挽输出
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  // 上拉
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 高速GPIO
		GPIO_Init(GPIOE,&GPIO_InitStructure);
		
		// 让LED灯初始化成灭的状态
		GPIO_ResetBits(GPIOE, GPIO_Pin_3); // GPIOE3,10高电平
	}

	/**
	  * @brief  Main program
	  * @param  None
	  * @retval None
	  */
	int main(void)
	{
		// @note ls main_example_by_st() // ST官方的例子
		
		// @note ls 设置系统时钟, 否则进不了SysTick_Handler
		RCC_GetClocksFreq(&RCC_Clocks);
		SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000); // @note ls 168000000(168MHZ) / 1000(微秒) = 1ms 发生一次tick

		bsp_Init_led(); // 初始化外设 - LED指示灯
		
		// 验证一下固件库是否能正常运行
		do {
			delay_ms(500);
			GPIO_ToggleBits(GPIOE, GPIO_Pin_3); // 将指示灯状态翻转, 形成闪烁
		} while (1);
	}

	// 现在可以看到自己板子上的LED指示灯亮灭的时间总和为1S, 对着PC机的闹钟, 数LED亮灭60次,正好是1S
	// STM32F4固件库的从零开始的移植完成
	
	// 如果要加入后续的板级驱动, 就在/BSP文件夹和/BSP管理组中加
	
	// END
	
发布了436 篇原创文章 · 获赞 126 · 访问量 175万+

猜你喜欢

转载自blog.csdn.net/LostSpeed/article/details/103224333
今日推荐