找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1507|回复: 0
打印 上一主题 下一主题
收起左侧

建立STM32工程

[复制链接]
跳转到指定楼层
楼主
ID:179644 发表于 2018-4-21 14:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
环境搭建:
1、安装 Keil uVision4 MDK
2、安装 J-Link
安装Setup_JLinkARM_V4501.exe 驱动时,会弹出【SEGGER J-Link DLL Updater V4.501 】对话框,
不要选择 Keil 直接点击OK即可,因为Keil对支持M3内核SW接口采用了JL2CM3.dll 这个文件,该文
件的版本号是和该目录下Jlink驱动版本号配套的,不要擅自改变他们,否则不能使用。
建立工程:
1、在桌面上建立一个文件夹【MyStm32】文件夹
2、在【MyStm32】文件夹下建立【USER】、【FWlib】、【CMSIS】、【Output】、【Listing】文件夹。
        USER】:存放用户自定义的应用程序
        FWlib】:存放库文件
        CMSIS】:存放M3系列单片机通用的文件
        Output】:存放编译器编译后输出的文件
        Listing】:编译器编译过程中产生的文件
3、将STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver 的【inc】跟【src
        这两个文件夹拷贝到【FWlib】。
        inc】、【src】片上外设驱动的源文件和头文件。
4\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template 下的
        main.cstm32f10x_conf.hstm32f10x_it.hstm32f10x_it.c system_stm32f10x.c拷贝到【USER
        stm32f10x_conf.h:配置文件
        stm32f10x_it.hstm32f10x_it.c:中断函数文件。
        system_stm32f10x.cARM公司提供的符合CMSIS标准的库文件
5STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup
        arm】文件夹的拷贝到 MyStm32\CMSIS\startup
        这些都是用汇编编写的驱动文件,STM32F103ZE芯片是大容量Flash,应选择startup_stm32f10x_hd.s
6STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport core_cm3.c core_cm3.h
        也拷贝到【CMSIS】文件夹下。
7STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x
        stm32f10x.hsystem_stm32f10x.csystem_stm32f10x.h 拷贝到【CMSIS】文件夹下。
8、用keil MDK 建立工程文件到【USER】文件夹下,工程名为【STM32-DEMO
        在该工程下建立四个组:
        STARTCODE】:存放启动代码 添加 startup_stm32f10x_hd.s文件
        USER】:存放用户自定义的应用程序添加main.cstm32f10x_it.c
        FWlib】:存放库文件按需添加src里面的驱动文件
        CMSIS】:存放M3系列单片机通用的文件 添加core_cm3.csystem_stm32f10x.c
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg
配置MDK

file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg

file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image006.jpg
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image008.jpg
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image010.jpg
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image012.jpg
添加USE_STDPERIPH_DRIVER 是为了屏蔽编译器的默认搜索路径,转而使用我们添加
到工程中的 ST 的库,添加 STM32F10X_HD 是因为我们用的芯片是大容量的,添加了
STM32F10X_HD 这个宏之后,库文件里面为大容量定义的寄存器我们就可以用了。
芯片是小或中容量的时候宏要换成STM32F10X_LD或者STM32F10X_MD。其实不管是什么容量的,
    我们只要添加上 STM32F10X_HD 这个宏即可,当你用小或者中容量的芯
片时,那些为大容量定义的寄存器我不去访问就是了,反正也访问不了。

流水灯实验:
只用到 配置GPIO功能和配置时钟功能,所以在stm32f10x_conf.h

只需要包含两个头文件即可:
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

流水灯流程:
        1、开启指定GPIO的外设时钟 ->RCC_APB2PeriphClockCmd()
        2、设置 GPIO_InitTypeDef 指定引脚、工作状态、输出频率
        3、根据 调用GPIO_Init() 初始化IO -> GPIO_Init()
        4、设置IO输出高低电平,实现控制LED灯的亮灭。

led.c:
#include "led.h"        
void LED_GPIO_Config(void)
{
        // 定义一个 GPIO_InitTypeDef 类型的结构体
        GPIO_InitTypeDef GPIO_InitStructure;
        // 开启 GPIOC 的外设时钟
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC,ENABLE);
        // 选择要控制的 GPIOC 引脚
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 |GPIO_Pin_4 | GPIO_Pin_5;
        // 设置引脚模式为通用推挽输出
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        // 设置引脚速率为 50Mhz
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        // 调用库函数,初始化GPIOC
        GPIO_Init(GPIOC, &GPIO_InitStructure);
        // 设置GPIOC3GPIOC4GPIOC5 为高电平
        GPIO_SetBits(GPIOC, GPIO_Pin_3 | GPIO_Pin_4 |GPIO_Pin_5);
}

led.h:
#ifndef __LED_H
#define __LED_H

#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#define ON        0
#define OFF        1

//带参宏,可以向联函数一样使用
#define        LED1(a) if(a) \
                                      GPIO_SetBits(GPIOC, GPIO_Pin_3);\
                               else  \
                                      GPIO_ResetBits(GPIOC, GPIO_Pin_3)

#define        LED2(a) if(a) \
                                      GPIO_SetBits(GPIOC, GPIO_Pin_4);\
                               else  \
                                      GPIO_ResetBits(GPIOC, GPIO_Pin_4)

#define        LED3(a) if(a) \
                                      GPIO_SetBits(GPIOC, GPIO_Pin_5);\
                               else  \
                                       GPIO_ResetBits(GPIOC,GPIO_Pin_5)

void LED_GPIO_Config(void);

#endif

main.c
#include "stm32f10x.h"
#include "led.c"

void Delay(__IO u32 nCount)
{
        for(; nCount !=0; nCount--);      
}

int main(void)
{
        LED_GPIO_Config();
        while (1)
        {
                LED1(ON);
                  Delay(0x0FFFEF);
                LED1(OFF);
                  Delay(0x0FFFEF);
        }
}
-----------------------------------------------------------------------

1.  typedef enum  
2.  {   
3.    GPIO_Speed_10MHz = 1, //枚举常量,值为 1,代表输出速率最高为10MHz   
4.    GPIO_Speed_2MHz,      //对不赋值的枚举变量,自动加 1,此常量值为 2   
5.    GPIO_Speed_50MHz      //常量值为 3   
6.  }GPIOSpeed_TypeDef

1.  typedef enum  
2.  {GPIO_Mode_AIN = 0x0,          //模拟输入模式   
3.    GPIO_Mode_IN_FLOATING = 0x04,  //浮空输入模式   
4.    GPIO_Mode_IPD = 0x28,          //下拉输入模式   
5.    GPIO_Mode_IPU = 0x48,          //上拉输入模式   
6.    GPIO_Mode_Out_OD = 0x14,       //开漏输出模式   
7.    GPIO_Mode_Out_PP = 0x10,       //通用推挽输出模式   
8.    GPIO_Mode_AF_OD = 0x1C,       //复用功能开漏输出   
9.    GPIO_Mode_AF_PP = 0x18         //复用功能推挽输出   
10.  }GPIOMode_TypeDef;

1.  typedef struct  
2.  {   
3.    uint16_t GPIO_Pin;            /*指定将要进行配置的 GPIO引脚*/  
4.    GPIOSpeed_TypeDef GPIO_Speed;  /*指定 GPIO 引脚可输出的最高频率*/  
5.    GPIOMode_TypeDef GPIO_Mode;    /*指定 GPIO 引脚将要配置成的工作状态*/  
6.  }GPIO_InitTypeDef;  

实例:
31.      /*选择要控制的 GPIOC 引脚*/                                                            
32.      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 |GPIO_Pin_4 | GPIO_Pin_5;   
33.   
34.      /*设置引脚模式为通用推挽输出*/  
35.      GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;      
36.   
37.      /*设置引脚速率为 50MHz */      
38.      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-----------------------------------------------------------------------
GPIO控制:
void GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_InitStruct);
功能:根据 GPIOx 初始化GPIO
参数1:允许指为 GPIOAGPIOBGPIOC...GPIOG
参数2GPIO_InitTypeDef 类型的指针,包含了指定引脚、输出工作状态和频率

实例:
40.      /*调用库函数,初始化 GPIOC*/  
41.      GPIO_Init(GPIOC, &GPIO_InitStructure);

void GPIO_SetBits  ( GPIO_TypeDef *  GPIOx,uint16_t  GPIO_Pin)
功能:设置GPIO引脚输出高电平
参数1:允许指为 GPIOAGPIOBGPIOC...GPIOG
参数2:要控制的引脚号 Pin0~Pin15

void GPIO_ResetBits  ( GPIO_TypeDef *  GPIOx,uint16_t  GPIO_Pin)
功能:设置GPIO引脚输出低电平
参数1:允许指为 GPIOAGPIOBGPIOC...GPIOG
参数2:要控制的引脚号 Pin0~Pin15

-----------------------------------------------------------------------
外设时钟控制:
void RCC_APB2PeriphResetCmd  (uint32_t  RCC_APB2Periph,  FunctionalState  NewState)
功能:开启或关闭的挂接在APB2总线上的外设时钟
参数1
        RCC_APB2Periph_AFIO,
        RCC_APB2Periph_GPIOA,
        RCC_APB2Periph_GPIOB,
        RCC_APB2Periph_GPIOC,
        RCC_APB2Periph_GPIOD,
        RCC_APB2Periph_GPIOE,
        RCC_APB2Periph_GPIOF,
        RCC_APB2Periph_GPIOG,
        RCC_APB2Periph_ADC1,
        RCC_APB2Periph_ADC2,
        RCC_APB2Periph_TIM1,
        RCC_APB2Periph_SPI1,
        RCC_APB2Periph_TIM8,
        RCC_APB2Periph_USART1,
        RCC_APB2Periph_ADC3,
        RCC_APB2Periph_TIM15,
        RCC_APB2Periph_TIM16,
        RCC_APB2Periph_TIM17,
        RCC_APB2Periph_TIM9,
        RCC_APB2Periph_TIM10,
        RCC_APB2Periph_TIM11
参数2:使能外设时钟或关闭外设时钟
        ENABLE or DISABLE

void RCC_APB1PeriphClockCmd  ( uint32_t  RCC_APB1Periph,FunctionalState  NewState)
功能:开启或关闭的挂接在APB2总线上的外设时钟
参数1
        RCC_APB1Periph_TIM2,
        RCC_APB1Periph_TIM3,
        RCC_APB1Periph_TIM4,
        RCC_APB1Periph_TIM5,
        RCC_APB1Periph_TIM6,
        RCC_APB1Periph_TIM7,
        RCC_APB1Periph_WWDG,
        RCC_APB1Periph_SPI2,
        RCC_APB1Periph_SPI3,
        RCC_APB1Periph_USART2,
        RCC_APB1Periph_USART3,
        RCC_APB1Periph_USART4,
        RCC_APB1Periph_USART5,
        RCC_APB1Periph_I2C1,
        RCC_APB1Periph_I2C2,
        RCC_APB1Periph_USB,
        RCC_APB1Periph_CAN1,
        RCC_APB1Periph_BKP,
        RCC_APB1Periph_PWR,
        RCC_APB1Periph_DAC,
        RCC_APB1Periph_CEC,
        RCC_APB1Periph_TIM12,
        RCC_APB1Periph_TIM13,
        RCC_APB1Periph_TIM14
参数2:使能外设时钟或关闭外设时钟
        ENABLE or DISABLE

【注意】:如果用到了I/O引脚的复用功能,则还要开启其复用功能的时钟。
GPIOCPin4还可以作为ADC1的输入引脚,我们把它作为ADC1来使用,
那么除了要开启GPIOC时钟外,还需要开启ADC1的时钟。
        
例子:      
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC,ENABLE);
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1,ENABLE);
-----------------------------------------------------------------------

-----------------------------------------------------------------------
启动文件:startup_stm32f10x_hd.s

1.  ;Reset_Handler 子程序开始  芯片被复位的时候会执行  
2.  Reset_Handler   PROC      
3.         
4.   ;输出子程序Reset_Handler 到外部文件  
5.                EXPORT  Reset_Handler           [WEAK]   
6.   
7.  ;从外部文件中引入 main 函数   
8.           IMPORT  __main   
9.      
10.  ;从外部文件引入SystemInit 函数                                    
11.           IMPORT  SystemInit
12.                    
13.  ; SystemInit 函数调用地址加载到通用寄存器 r0   
14.                 LDR     R0, =SystemInit     
15.         
16.  ;跳转到 r0 中保存的地址执行程序(调用 SystemInit 函数 用于设置系统时钟)   
17.                 BLX     R0            
18.               
19.  ; main 函数调用地址加载到通用寄存器 r0   
20.                 LDR     R0, =__main     
21.   
22.  ;跳转到 r0 中保存的地址执行程序(调用 main 函数)        
23.                 BX      R0   
24.                       
25.  ;Reset_Handler 子程序结束   
26.                 ENDP  

启动代码中,它会调用SystemInit()SysteInit()会先将与配置时钟相关的寄存器复位为默认值。
然后它再调用SetSysClock()函数:
1.  static void SetSysClock(void)   
2.  {   
3.  #ifdef SYSCLK_FREQ_HSE   
4.    SetSysClockToHSE();   
5.  #elif defined SYSCLK_FREQ_24MHz   
6.    SetSysClockTo24();   
7.  #elif defined SYSCLK_FREQ_36MHz   
8.    SetSysClockTo36();   
9.  #elif defined SYSCLK_FREQ_48MHz   
10.    SetSysClockTo48();   
11.  #elif defined SYSCLK_FREQ_56MHz   
12.    SetSysClockTo56();     
13.  #elif defined SYSCLK_FREQ_72MHz   
14.    SetSysClockTo72();                  // 配置相关寄存器
15.  #endif   
19.  }  
SetSysClock()才是真正配置系统时钟函数,会根据宏来进行不同频率的配置。
system_stm32f10x.c文件启用宏。
1.  #if defined (STM32F10X_LD_VL)|| (defined STM32F10X_MD_VL)|| (defined STM32F10X_HD_VL)  
2.  /* #define SYSCLK_FREQ_HSE    HSE_VALUE */  
3.   #define SYSCLK_FREQ_24MHz  24000000   
4.  #else   
5.  /* #define SYSCLK_FREQ_HSE    HSE_VALUE */  
6.  /* #define SYSCLK_FREQ_24MHz  24000000 */   
7.  /* #define SYSCLK_FREQ_36MHz  36000000 */  
8.  /* #define SYSCLK_FREQ_48MHz  48000000 */  
9.  /* #define SYSCLK_FREQ_56MHz  56000000 */  
10.  #define SYSCLK_FREQ_72MHz  72000000   
11.  #endif
-----------------------------------------------------------------------

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表