• Keil MDK STM32系列(三) 基于标准外设库SPL的STM32F407开发


    Keil MDK STM32系列

    概述

    Windows下使用Keil MDK5进行 STM32F407VET6 的开发和编译, 配合ST-LINK工具进行烧录, 使用标准外设库SPL.

    STM32F407硬件环境

    主要参数

    • STM32F407VET6 Arm Cortex-M4
    • 168MHz Max Clock Speed
    • 512k flash
    • 192k ram
    • LQFP 100 pins
    • Backup SRAM 4k

    STM32F407VET6 Black Board 开发板

    具体说明可以查看 https://stm32-base.org/boards/STM32F407VET6-STM32-F4VE-V2.0.html

    使用普通的4线 ST-Link V2, 也可以使用增加了串口的V2.1

    ST-Link 与 stm32核心板的连接需要4根线, 连接关系为

    G   -- GND
    CLK -- SWCLK
    IO  -- SWDIO
    V3  -- 3.3V
    

    烧录时, 如果开发板已经外接了电源, 那么st-link的3.3V不要接到开发板.

    外观

    USB2TTL 转接卡

    在观察串口输出时需要使用.

    STM32F4 官方标准外设库 Standard Peripheral Libraries

    参考STM32F401的说明, 与STM32F401相同

    按步骤手工创建项目

    先组织好库文件和目录, 然后创建项目

    创建目录并填充文件

    参考STM32F401的说明, 与STM32F401相同, 完成后的目录结构是这样的

    test001>
    ├─Drivers
    │  ├─CMSIS
    │  │  ├─Device
    │  │  │  └─ST
    │  │  │      └─STM32F4xx
    │  │  │          ├─Include
    │  │  │          └─Source
    │  │  └─Include
    │  └─STM32F4xx_StdPeriph_Driver
    │      ├─inc
    │      └─src
    └─User
    

    在Keil uVision5中创建项目

    1. Project -> New uVision Project, 选择工作目录 test001, 使用名称test001, 保存
    2. 在弹出的对话框中, 选择芯片型号, 选择芯片型号STM32F407VE
    3. 在后续的 Manage Run-Time Enviroment 对话框中什么都不选, 因为会在项目里自己管理库文件

    配置项目

    在上面的步骤完成后, Keil MDK中就会显示一个项目的初始结构, 目录为 Project:test001, 以及一个 Target1

    修改 Target 名称以及添加源文件

    在菜单中点击 Project -> Manage -> Project Items, 或者直接在图标栏中点击红黄绿品字形的图标, 在弹出的对话框中

    1. 修改 project targets 名称为 test001, 这个可以随便改
    2. 编辑并添加 Groups, 最终会有以下 Groups
      • CMSIS
      • StdPeriph_Driver
      • Startup
      • User

    对每个group, 添加的文件为

    • CMSIS
      • 添加 DriversCMSISDeviceSTSTM32F4xxSourceTemplatessystem_stm32f4xx.c
    • StdPeriph_Driver
      • 添加 DriversSTM32F4xx_StdPeriph_Driversrc 下面的所有c文件, 除了 stm32f4xx_fmc.c 和 stm32f4xx_fsmc.c
    • Startup
      • 注意, 这里是与F401不同的:添加 DriversCMSISDeviceSTSTM32F4xxSourceTemplatesarmstartup_stm32f40_41xxx.s 文件
    • User
      • 添加 user 目录下的所有C文件

    修改项目包含路径

    在菜单中点击Project -> Options for Target 'test001', 或者直接在图标栏中点击configure target option图标, 在弹出的对话框中

    1. 定位到c/c++标签页
    2. Define: 这个是编译参数, 注意这里也与F401不同, 写入 USE_STDPERIPH_DRIVER,STM32F40_41xxx
    3. Include Paths: 这里是头文件的包含路径, 如果按上面的目录结构组织的项目, 可以直接复制下面的配置
    .DriversCMSISInclude;.DriversCMSISDeviceSTSTM32F4xxInclude;.DriversSTM32F4xx_StdPeriph_Driverinc;.User
    

    在下面的 compiler control string 中可以查看完整的命令行

    --c99 --gnu -c --cpu Cortex-M4.fp -g -O0 --apcs=interwork --split_sections -I ../libraries/CMSIS/Include -I ../libraries/CMSIS/Device/ST/STM32F4xx/Include -I ../libraries/STM32F4xx_StdPeriph_Driver/inc -I ../user
    -I./RTE/_stm32f407test01
    -IC:/Keil_v5/ARM/PACK/Keil/STM32F4xx_DFP/2.15.0/Drivers/CMSIS/Device/ST/STM32F4xx/Include
    -IC:/Keil_v5/ARM/CMSIS/Include
    -D__UVISION_VERSION="525" -DSTM32F407xx -DUSE_STDPERIPH_DRIVER -DSTM32F40_41xxx
    -o .Objects*.o --omf_browse .Objects*.crf --depend .Objects*.d
    

    STM32F407 Black Board 示例代码

    下面的例子, 使用开发板自带的led灯(A6, A7)实现交替亮灭的效果.
    在User目录下创建 main.h 和 main.c, 注意通过Keil MDK创建的时候, 要注意文件位置, 默认是放到项目根目录的, 这里要改到User目录下.

    main.c

    #include "main.h"
    
    #define GPIO_LED      GPIOA
    #define GPIO_PIN_LED0 GPIO_Pin_6
    #define GPIO_PIN_LED1 GPIO_Pin_7
    
    static u8  fac_us=0;//us延时倍乘数			   
    static u16 fac_ms=0;//ms延时倍乘数,在ucos下,代表每个节拍的ms数
    
    void delay_init(u8 SYSCLK)
    {
      SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
    	fac_us=SYSCLK/8;		//不论是否使用ucos,fac_us都需要使用
    	fac_ms=(u16)fac_us*1000;//非ucos下,代表每个ms需要的systick时钟数   
    }		
    
    void delay_us(u32 nus)
    {		
    	u32 temp;	    	 
    	SysTick->LOAD=nus*fac_us; //时间加载	  		 
    	SysTick->VAL=0x00;        //清空计数器
    	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //开始倒数 
    	do
    	{
    		temp=SysTick->CTRL;
    	}
    	while((temp&0x01)&&!(temp&(1<<16)));//等待时间到达   
    	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //关闭计数器
    	SysTick->VAL =0X00;       //清空计数器	 
    }
    //延时nms
    //注意nms的范围
    //SysTick->LOAD为24位寄存器,所以,最大延时为:
    //nms<=0xffffff*8*1000/SYSCLK
    //SYSCLK单位为Hz,nms单位为ms
    //对168M条件下,nms<=798ms 
    void delay_xms(u16 nms)
    {	 		  	  
    	u32 temp;		   
    	SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)
    	SysTick->VAL =0x00;           //清空计数器
    	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //开始倒数  
    	do
    	{
    		temp=SysTick->CTRL;
    	}
    	while((temp&0x01)&&!(temp&(1<<16)));//等待时间到达   
    	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //关闭计数器
    	SysTick->VAL =0X00;       //清空计数器	  	    
    } 
    //延时nms 
    //nms:0~65535
    void delay_ms(u16 nms)
    {	 	 
    	u8 repeat=nms/540;	//这里用540,是考虑到某些客户可能超频使用,
    						//比如超频到248M的时候,delay_xms最大只能延时541ms左右了
    	u16 remain=nms%540;
    	while(repeat)
    	{
    		delay_xms(540);
    		repeat--;
    	}
    	if(remain)delay_xms(remain);
    	
    } 
    
    void LED_Init(void)
    {    	 
      GPIO_InitTypeDef  GPIO_InitStructure;
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
      //GPIOF9,F10初始化设置
      GPIO_InitStructure.GPIO_Pin = GPIO_PIN_LED0 | GPIO_PIN_LED1;//LED0和LED1对应IO口
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
      GPIO_Init(GPIO_LED, &GPIO_InitStructure);//初始化GPIO
    	
      GPIO_SetBits(GPIO_LED,GPIO_PIN_LED0 | GPIO_PIN_LED1);//设置高,灯灭
    }
    
    int main(void)
    {
      delay_init(168);		  //初始化延时函数
      LED_Init();		        //初始化LED端口
    	
      /**下面是通过直接操作库函数的方式实现IO控制**/
    	while(1)
    	{
        GPIO_ResetBits(GPIO_LED,GPIO_PIN_LED0);
        GPIO_SetBits(GPIO_LED,GPIO_PIN_LED1);
        delay_ms(500);
        GPIO_SetBits(GPIO_LED,GPIO_PIN_LED0);
        GPIO_ResetBits(GPIO_LED,GPIO_PIN_LED1);
        delay_ms(500);
    	}
    }
    
    

    main.h

    #ifndef __MAIN_H
    #define __MAIN_H
    
    #include "stm32f4xx.h"
    
    
    #endif /* __MAIN_H */
    
    

    编译烧录

    编译和烧录和F401是一样的

  • 相关阅读:
    MySQL主从复制与读写分离
    使用PHPCMS搭建wap手机网站
    phpcms v9不用下插件自己做留言板
    css关于banner图轮播的实现
    MySql和Oracle的日期转换到底有哪些不同?我们来比较一下
    CSS---解决内容过多就会出文本溢出(显示在区域外面,不换行的情况)
    dedecms 后台发布后的文章不能编辑出现一片空白的解决办法
    python常识系列11-->python发送邮件基础
    python常识系列10-->python代码注释规范
    python常识系列09-->logging模块之handlers的使用
  • 原文地址:https://www.cnblogs.com/milton/p/15267529.html
Copyright © 2020-2023  润新知