工程创建
创建这个工程模版,是为了我们后面免去我们后面创建工程模版的步骤
创建这个文件,这个文件是用来存放我们编译生成的一些中间文件,C,汇编,链接的一些列表清单,调试信息,以及需要我们下载到单片机的hex文件。
再创建一个User这个是我们用户编写的文件
比如main.c,stm32的头文件和配置文件,中断文件
这个存放我们stm32的一些库,以及我们CMSIS标准的一些文件
我们的库文件可以直接在我们的固件库中提取
这些文档是我们不需要的可以直接删除
这个也不需要直接删除就行了
这个是我们F407要使用的头文件
接下来寻找启动文件
我们使用的编译器是MDK
找到这里复制粘贴进去
然后我们接着找stm32的头文件
找到Include,然后拷贝这两个文件进去
然后系统时钟的文件也是需要的
从这里拷贝进去
接下来就找配置文件
以及我们系统时钟对应的原文件
系统时钟对应的原元件在这里
然后还要拿我们的中断文件、
因为F407和F429差不多,所以我们的中断文件直接从F429里面拿就行了
main.c文件,中断文件it.c也拷贝进来
再把头文件复制进来
创建工程,然后命名不要是中文
选着F407ZGT6
编译给我们生成了列表清单什么的
这个也是保存一些中间的文件的
但是最终我们还是要把他生成在我们obj文件夹下面才行
鼠标点击target然后点击管理
在这里添加文件
点击三个方块也同样能进入这个图标
给你的文件夹改名字,然后存放·他的一些文件,这些就会好辨认
start up 是用来添加启动文件的
hal_driver是存放HAL的一些驱动文件
CMSIS的文件就放在这里面,然后启动文件也要放在这里面
User里面添加main,c 添加中断,添加时钟文件
发现这些文件都是有钥匙的
工程配置
勾选维库
不勾选的话,到时候你输出的时候就什么都没有
生成hex文件
添加宏为什么要添加呢
在我们的固件库里面他会识别你的宏有没有定义,来决定你的这些文件有没有编译
USE_HAL_DRIVER,STM32F407xx
还要添加头文件的路径,不然等一下会报错,找不到路径
JTAG的管脚更多
Debug的设置
勾选这个开发板自动复位运行
如果你不勾选的话,你就要自己按复位,不然的话就没用
添加一个ST芯片的一个算法
这样搞好后,配置就完成
编译后完后发现有错误
如果你不打开brows那么就会打不开你对应的函数
点击下面的蓝色那里就能跳到这个函数对应的地方
因为复制的F429,不是F407所以那个函数就没有定义
看这个是白的就是没有定义
没办法我们只有F407的宏,所以这时候
拷贝F407的新函数
static void SystemClock_Config(void)
{RCC_ClkInitTypeDef RCC_ClkInitStruct;RCC_OscInitTypeDef RCC_OscInitStruct;/* Enable Power Control clock */__HAL_RCC_PWR_CLK_ENABLE();/* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);/* Enable HSE Oscillator and activate PLL with HSE as source */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 8;RCC_OscInitStruct.PLL.PLLN = 360;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = 7;if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){/* Initialization Error */Error_Handler();}if(HAL_PWREx_EnableOverDrive() != HAL_OK){/* Initialization Error */Error_Handler();}/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK){/* Initialization Error */Error_Handler();}
}
//ʱÖÓϵͳÅäÖú¯Êý
//Fvco=Fs*(plln/pllm);
//SYSCLK=Fvco/pllp=Fs*(plln/(pllm*pllp));
//Fusb=Fvco/pllq=Fs*(plln/(pllm*pllq));//Fvco:VCOƵÂÊ
//SYSCLK:ϵͳʱÖÓƵÂÊ
//Fusb:USB,SDIO,RNGµÈµÄʱÖÓƵÂÊ
//Fs:PLLÊäÈëʱÖÓƵÂÊ,¿ÉÒÔÊÇHSI,HSEµÈ.
//plln:Ö÷PLL±¶ÆµÏµÊý(PLL±¶Æµ),È¡Öµ·¶Î§:64~432.
//pllm:Ö÷PLLºÍÒôƵPLL·ÖƵϵÊý(PLL֮ǰµÄ·ÖƵ),È¡Öµ·¶Î§:2~63.
//pllp:ϵͳʱÖÓµÄÖ÷PLL·ÖƵϵÊý(PLLÖ®ºóµÄ·ÖƵ),È¡Öµ·¶Î§:2,4,6,8.(½öÏÞÕâ4¸öÖµ!)
//pllq:USB/SDIO/Ëæ»úÊý²úÉúÆ÷µÈµÄÖ÷PLL·ÖƵϵÊý(PLLÖ®ºóµÄ·ÖƵ),È¡Öµ·¶Î§:2~15.//Íⲿ¾§ÕñΪ8MµÄʱºò,ÍƼöÖµ:plln=336,pllm=8,pllp=2,pllq=7.
//µÃµ½:Fvco=8*(336/8)=336Mhz
// SYSCLK=336/2=168Mhz
// Fusb=336/7=48Mhz
//·µ»ØÖµ:0,³É¹¦;1,ʧ°Ü
void SystemClock_Init(u32 pllm,u32 plln,u32 pllp,u32 pllq)
{HAL_StatusTypeDef ret = HAL_OK;RCC_OscInitTypeDef RCC_OscInitStructure; RCC_ClkInitTypeDef RCC_ClkInitStructure;__HAL_RCC_PWR_CLK_ENABLE(); //ʹÄÜPWRʱÖÓ//ÏÂÃæÕâ¸öÉèÖÃÓÃÀ´ÉèÖõ÷ѹÆ÷Êä³öµçѹ¼¶±ð£¬ÒÔ±ãÔÚÆ÷¼þδÒÔ×î´óƵÂʹ¤×÷//ʱʹÐÔÄÜÓ빦ºÄʵÏÖƽºâ¡£__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);//ÉèÖõ÷ѹÆ÷Êä³öµçѹ¼¶±ð1RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_HSE; //ʱÖÓԴΪHSERCC_OscInitStructure.HSEState=RCC_HSE_ON; //´ò¿ªHSERCC_OscInitStructure.PLL.PLLState=RCC_PLL_ON;//´ò¿ªPLLRCC_OscInitStructure.PLL.PLLSource=RCC_PLLSOURCE_HSE;//PLLʱÖÓÔ´Ñ¡ÔñHSERCC_OscInitStructure.PLL.PLLM=pllm; //Ö÷PLLºÍÒôƵPLL·ÖƵϵÊý(PLL֮ǰµÄ·ÖƵ),È¡Öµ·¶Î§:2~63.RCC_OscInitStructure.PLL.PLLN=plln; //Ö÷PLL±¶ÆµÏµÊý(PLL±¶Æµ),È¡Öµ·¶Î§:64~432. RCC_OscInitStructure.PLL.PLLP=pllp; //ϵͳʱÖÓµÄÖ÷PLL·ÖƵϵÊý(PLLÖ®ºóµÄ·ÖƵ),È¡Öµ·¶Î§:2,4,6,8.(½öÏÞÕâ4¸öÖµ!)RCC_OscInitStructure.PLL.PLLQ=pllq; //USB/SDIO/Ëæ»úÊý²úÉúÆ÷µÈµÄÖ÷PLL·ÖƵϵÊý(PLLÖ®ºóµÄ·ÖƵ),È¡Öµ·¶Î§:2~15.ret=HAL_RCC_OscConfig(&RCC_OscInitStructure);//³õʼ»¯if(ret!=HAL_OK) while(1);//Ñ¡ÖÐPLL×÷ΪϵͳʱÖÓÔ´²¢ÇÒÅäÖÃHCLK,PCLK1ºÍPCLK2RCC_ClkInitStructure.ClockType=(RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2);RCC_ClkInitStructure.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;//ÉèÖÃϵͳʱÖÓʱÖÓԴΪPLLRCC_ClkInitStructure.AHBCLKDivider=RCC_SYSCLK_DIV1;//AHB·ÖƵϵÊýΪ1RCC_ClkInitStructure.APB1CLKDivider=RCC_HCLK_DIV4; //APB1·ÖƵϵÊýΪ4RCC_ClkInitStructure.APB2CLKDivider=RCC_HCLK_DIV2; //APB2·ÖƵϵÊýΪ2ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_5);//ͬʱÉèÖÃFLASHÑÓʱÖÜÆÚΪ5WS£¬Ò²¾ÍÊÇ6¸öCPUÖÜÆÚ¡£if(ret!=HAL_OK) while(1);//STM32F405x/407x/415x/417x Z°æ±¾µÄÆ÷¼þÖ§³ÖԤȡ¹¦ÄÜif (HAL_GetREVID() == 0x1001){__HAL_FLASH_PREFETCH_BUFFER_ENABLE(); //ʹÄÜflashԤȡ}
}
因为我们是没有什么定义是u32,所以从库函数那里找就行了
定义的话就要放到main.h下面就行了
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;typedef const int32_t sc32;
typedef const int16_t sc16;
typedef const int8_t sc8; typedef __IO int32_t vs32;
typedef __IO int16_t vs16;
typedef __IO int8_t vs8;typedef __I int32_t vsc32;
typedef __I int16_t vsc16;
typedef __I int8_t vsc8; typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;typedef const uint32_t uc32;
typedef const uint16_t uc16;
typedef const uint8_t uc8; typedef __IO uint32_t vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t vu8;typedef __I uint32_t vuc32;
typedef __I uint16_t vuc16;
typedef __I uint8_t vuc8;
原本没参数,但是拷贝后是有的,所以要放参数进去
找到基础实验hal库工程模版创建,就这样复制上去就行了
这时候我们的系统时钟就是168MHZ了
因为声明没有定义,所以我们定义一下
大致搞成这样
/********************************************************************************* @file Templates/Src/main.c * @author MCD Application Team* @brief Main program body******************************************************************************* @attention** <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>** Redistribution and use in source and binary forms, with or without modification,* are permitted provided that the following conditions are met:* 1. Redistributions of source code must retain the above copyright notice,* this list of conditions and the following disclaimer.* 2. Redistributions in binary form must reproduce the above copyright notice,* this list of conditions and the following disclaimer in the documentation* and/or other materials provided with the distribution.* 3. Neither the name of STMicroelectronics nor the names of its contributors* may be used to endorse or promote products derived from this software* without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.********************************************************************************//* Includes ------------------------------------------------------------------*/
#include "main.h"//¶¨ÒåһЩ³£ÓõÄÊý¾ÝÀàÐͶ̹ؼü×Ö
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;typedef const int32_t sc32;
typedef const int16_t sc16;
typedef const int8_t sc8; typedef __IO int32_t vs32;
typedef __IO int16_t vs16;
typedef __IO int8_t vs8;typedef __I int32_t vsc32;
typedef __I int16_t vsc16;
typedef __I int8_t vsc8; typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;typedef const uint32_t uc32;
typedef const uint16_t uc16;
typedef const uint8_t uc8; typedef __IO uint32_t vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t vu8;typedef __I uint32_t vuc32;
typedef __I uint16_t vuc16;
typedef __I uint8_t vuc8;
/** @addtogroup STM32F4xx_HAL_Examples* @{*/
//ʱÖÓϵͳÅäÖú¯Êý
//Fvco=Fs*(plln/pllm);
//SYSCLK=Fvco/pllp=Fs*(plln/(pllm*pllp));
//Fusb=Fvco/pllq=Fs*(plln/(pllm*pllq));//Fvco:VCOƵÂÊ
//SYSCLK:ϵͳʱÖÓƵÂÊ
//Fusb:USB,SDIO,RNGµÈµÄʱÖÓƵÂÊ
//Fs:PLLÊäÈëʱÖÓƵÂÊ,¿ÉÒÔÊÇHSI,HSEµÈ.
//plln:Ö÷PLL±¶ÆµÏµÊý(PLL±¶Æµ),È¡Öµ·¶Î§:64~432.
//pllm:Ö÷PLLºÍÒôƵPLL·ÖƵϵÊý(PLL֮ǰµÄ·ÖƵ),È¡Öµ·¶Î§:2~63.
//pllp:ϵͳʱÖÓµÄÖ÷PLL·ÖƵϵÊý(PLLÖ®ºóµÄ·ÖƵ),È¡Öµ·¶Î§:2,4,6,8.(½öÏÞÕâ4¸öÖµ!)
//pllq:USB/SDIO/Ëæ»úÊý²úÉúÆ÷µÈµÄÖ÷PLL·ÖƵϵÊý(PLLÖ®ºóµÄ·ÖƵ),È¡Öµ·¶Î§:2~15.//Íⲿ¾§ÕñΪ8MµÄʱºò,ÍƼöÖµ:plln=336,pllm=8,pllp=2,pllq=7.
//µÃµ½:Fvco=8*(336/8)=336Mhz
// SYSCLK=336/2=168Mhz
// Fusb=336/7=48Mhz
//·µ»ØÖµ:0,³É¹¦;1,ʧ°Ü
void SystemClock_Init(u32 pllm,u32 plln,u32 pllp,u32 pllq)
{HAL_StatusTypeDef ret = HAL_OK;RCC_OscInitTypeDef RCC_OscInitStructure; RCC_ClkInitTypeDef RCC_ClkInitStructure;__HAL_RCC_PWR_CLK_ENABLE(); //ʹÄÜPWRʱÖÓ//ÏÂÃæÕâ¸öÉèÖÃÓÃÀ´ÉèÖõ÷ѹÆ÷Êä³öµçѹ¼¶±ð£¬ÒÔ±ãÔÚÆ÷¼þδÒÔ×î´óƵÂʹ¤×÷//ʱʹÐÔÄÜÓ빦ºÄʵÏÖƽºâ¡£__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);//ÉèÖõ÷ѹÆ÷Êä³öµçѹ¼¶±ð1RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_HSE; //ʱÖÓԴΪHSERCC_OscInitStructure.HSEState=RCC_HSE_ON; //´ò¿ªHSERCC_OscInitStructure.PLL.PLLState=RCC_PLL_ON;//´ò¿ªPLLRCC_OscInitStructure.PLL.PLLSource=RCC_PLLSOURCE_HSE;//PLLʱÖÓÔ´Ñ¡ÔñHSERCC_OscInitStructure.PLL.PLLM=pllm; //Ö÷PLLºÍÒôƵPLL·ÖƵϵÊý(PLL֮ǰµÄ·ÖƵ),È¡Öµ·¶Î§:2~63.RCC_OscInitStructure.PLL.PLLN=plln; //Ö÷PLL±¶ÆµÏµÊý(PLL±¶Æµ),È¡Öµ·¶Î§:64~432. RCC_OscInitStructure.PLL.PLLP=pllp; //ϵͳʱÖÓµÄÖ÷PLL·ÖƵϵÊý(PLLÖ®ºóµÄ·ÖƵ),È¡Öµ·¶Î§:2,4,6,8.(½öÏÞÕâ4¸öÖµ!)RCC_OscInitStructure.PLL.PLLQ=pllq; //USB/SDIO/Ëæ»úÊý²úÉúÆ÷µÈµÄÖ÷PLL·ÖƵϵÊý(PLLÖ®ºóµÄ·ÖƵ),È¡Öµ·¶Î§:2~15.ret=HAL_RCC_OscConfig(&RCC_OscInitStructure);//³õʼ»¯if(ret!=HAL_OK) while(1);//Ñ¡ÖÐPLL×÷ΪϵͳʱÖÓÔ´²¢ÇÒÅäÖÃHCLK,PCLK1ºÍPCLK2RCC_ClkInitStructure.ClockType=(RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2);RCC_ClkInitStructure.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;//ÉèÖÃϵͳʱÖÓʱÖÓԴΪPLLRCC_ClkInitStructure.AHBCLKDivider=RCC_SYSCLK_DIV1;//AHB·ÖƵϵÊýΪ1RCC_ClkInitStructure.APB1CLKDivider=RCC_HCLK_DIV4; //APB1·ÖƵϵÊýΪ4RCC_ClkInitStructure.APB2CLKDivider=RCC_HCLK_DIV2; //APB2·ÖƵϵÊýΪ2ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_5);//ͬʱÉèÖÃFLASHÑÓʱÖÜÆÚΪ5WS£¬Ò²¾ÍÊÇ6¸öCPUÖÜÆÚ¡£if(ret!=HAL_OK) while(1);//STM32F405x/407x/415x/417x Z°æ±¾µÄÆ÷¼þÖ§³ÖԤȡ¹¦ÄÜif (HAL_GetREVID() == 0x1001){__HAL_FLASH_PREFETCH_BUFFER_ENABLE(); //ʹÄÜflashԤȡ}
}int main(void)
{HAL_Init();/* Configure the System clock to 180 MHz */
SystemClock_Init(8,336,2,7); //ÉèÖÃʱÖÓ,168Mhz/* Add your application code here*//* Infinite loop */while (1){}
}
加上LED点灯函数测试能不能使用
如果亮灯,证明以后就能够使用这个模版了
接下来查看有没有头文件
进去main.h里面看看有没有我们F407的头文件
把main.h换成上面这个
然后main.h就不用管了
下载程序到开发板
第一种PZ-ISP
第二种ARM仿真器
KEIL常用图标功能
这个第一个仅仅只是对当前的文件进行修改
第二个对改动的文件进行编译
第三个不管你有没有改,全部都编译了,时间长,通常使用第二个
这个用来仿真器的下载的
启动文件详解
启动文件我们知道都是使用汇编代码来写的
这个文件是用来执行微控制器到main函数的执行过程
1.初始化堆栈指针
2.初始化PC指针
3.中断向量表
4.配置系统时钟
声明全局属性的一个标号