stm32新建工程(详细)

原文地址:http://blog.csdn.net/lbl1234

下载固件函数库

     stm32标准外设库是stm32全系列芯片的外设驱动,有了它可以大大加速我们开发stm32。
    首先从st公司的网站下载最新的stm32标准外设库,写本文时最新的版本是V3.5.0。

    解压该zip文件,得到如下文件夹和文件
STM32F10x_StdPeriph_Lib_V3.5.0\
   _htmresc
   Libraries
   Project
   Utilities
   Release_Notes.html
   stm32f10x_stdperiph_lib_um.chm


    其中Libraries包含库的源代码,Project包含stm32各个外设的使用范例和一个工程模板,Utilities是使用st公司评估板的例子,stm32f10x_stdperiph_lib_um.chm教我们怎么用标准外设库。

工程目录结构
    既然准备使用32位单片机,应该是个不小项目,因此工程目录也应该做个规划。这里我推荐一下我所使用的目录结构。假设工程名字叫template,建一个名为template的文件夹,该目录下有个3个固定文件夹doc,src,include,doc用来存放工程相关的资料文件,src放源代码,在src下每个功能模块一个文件夹,include放各个模块都要使用的公共头文件。output放编译输出文件,内含两个子文件夹obj和list。

template\
   doc
   src
   include
   output\obj
             \list
     
整理库代码
    由于Libraries下的CMSIS文件夹中很多代码是和编译器及芯片相关的,导致文件夹多且深度大,不利于工程维护,实际上一个项目往往是用固定的编译器和芯片,因此有必要对库进行整理。
    在src下建立libstm32目录
    1. 把Libraries\STM32F10x_StdPeriph_Driver\下的内容拷贝到libstm32目录下
    2. 在libstm32目录下建立cmsis文件夹,把Libraries\CMSIS\CM3\CoreSupport\下的core_cm3.c,core_cm3.h;Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\下的stm32f10x.h,system_stm32f10x.c,system_stm32f10x.h拷贝到cmsis文件夹中。
    3. 根据你所选的芯片类型将Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm\下对应的启动文件拷贝到cmsis文件夹中。这里我拷贝的是startup_stm32f10x_hd.s(大容量型stm32芯片的启动文件)。

   下面对该库文件做个简单介绍:
    Libraries\STM32F10x_StdPeriph_Driver\下的内容很好理解就是stm32的各个外设模块驱动代码。
    misc.h和misc.c是和CM3内核有关的NVIC和SysTick的驱动代码。  
    Libraries\CMSIS下是什么呢?cmsis英文全称:Cortex Microcontroller Software Interface Standard,是Cortex系列处理器硬件抽象层,可以理解为cortex内核的软件接口。
    core_cm3.c, core_cm3.h
    它们的目录名为CoreSupport,说明这两个文件是CM3内核支撑文件,其他使用CM3内核的芯片也可以用,不一定是stm32。这两个文件用来获取设置CM3内核,配置一些内核寄存器。
    stm32f10x.h, system_stm32f10x.c, system_stm32f10x.h和startup_stm32f10x_hd.s在DeviceSupport目录下,说明这几个文件是和具体的芯片有关的,也就是stm32芯片的支撑文件。其中stm32f10x.h是标准外设库的入口,使用标准外设库的代码中必须包含该头文件。system_stm32f10x.c, system_stm32f10x.h这两个文件提供函数用来初始化stm32芯片,配置PLL、系统时钟和内置flash接口。startup_stm32f10x_hd.s是大容量型stm32芯片的启动文件。
   
建立工程  
    使用keil MDK(我使用4.12版)在template目录下建立工程,工程名为template。选一个stm32系列的芯片,哪一个都无所谓(我选的是STM32F101RC,因为我的板子就是用这个芯片),接下来要注意的是当弹出是否拷贝启动代码到工程文件夹时要选No,因为标准外设库里已经有启动代码了。
    将UV4中project window里的顶层目录名改为template,并将第一个group名改为libstm32。把libstm32目录下所有.c和.s文件加载到工程里的libstm32。
    在src下建立一个init目录用来放置系统初始化代码。把Project\STM32F10x_StdPeriph_Template\下的stm32f10x_it.c拷贝到init文件夹中,stm32f10x_it.h,stm32f10x_conf.h拷贝到include文件夹中。
    stm32f10x_it.c,stm32f10x_it.h是中断服务程序文件。stm32f10x_conf.h是标准外设库的配置文件,对于工程中不需要的外设,可以注释掉里面的包含的头文件。这里我建议先仅留下stm32f10x_gpio.h,stm32f10x_rcc.h,misc.h,用到什么再打开什么,这样编译起来快一点,当然也可都留着。

使用stm32标准外设库
    事实上,stm32标准外设库的使用在stm32f10x_stdperiph_lib_um.chm中的How to use the Library一节中已有说明,下面我把其中的步骤罗列一下:
1. 根据所选芯片,把Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm中的启动代码加到工程中,这一步在上面已经做过了。
2. 在stm32f10x.h的66-73行,根据所选芯片类型,去掉相应注释,这里我去掉STM32F10X_HD行的注释(大容量型stm32芯片)。
3. 去掉105行的USE_STDPERIP
H_DRIVER注释,启用stm32标准外设库。
4. 在system_stm32f10x.c的110-115行,根据所选芯片主频,去掉相应注释,默认SYSCLK_FREQ_72MHz注释已去掉,如果你的芯片主频是72MHz,就不用做修改了,这里我的芯片是36MHz,注释SYSCLK_FREQ_72MHz,去掉SYSCLK_FREQ_36MHz注释。

跑马灯程序
   现在可以使用stm32标准外设库了,下面以一个简单的跑马灯程序说明。

在init目录下建立main.c作为系统入口。

在src下建立一个bsp目录用来放置板级支持代码,建立led.c,led.h。

代码如下:
led.h

  1. <SPAN style="FONT-SIZE: 18px">#ifndef _LED_H_  
  2. #define _LED_H_   
  3.   
  4. #include <stdint.h>   
  5.   
  6. #define LED_0     0   
  7. #define LED_1     1   
  8. #define LED_2     2   
  9.   
  10. void led_init(void);  
  11. void led_on(uint32_t n);  
  12. void led_off(uint32_t n);  
  13.   
  14. #endif   
  15.   
  16. </SPAN>  
#ifndef _LED_H_
#define _LED_H_

#include <stdint.h>

#define LED_0     0
#define LED_1     1
#define LED_2     2

void led_init(void);
void led_on(uint32_t n);
void led_off(uint32_t n);

#endif

 

led.c

  1. <SPAN style="FONT-SIZE: 18px">#include "stm32f10x.h"  
  2. #include "led.h"   
  3.   
  4. void led_init(void)  
  5. {  
  6.  GPIO_InitTypeDef GPIO_InitStructure;  
  7.    
  8.  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);  
  9.  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;  
  10.  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
  11.  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;  
  12.  GPIO_Init(GPIOC, &GPIO_InitStructure);  
  13. }  
  14.   
  15. void led_on(uint32_t n)  
  16. {  
  17.  switch (n)  
  18.  {  
  19.   case LED_0:  
  20.    GPIO_SetBits(GPIOC, GPIO_Pin_6);  
  21.    break;  
  22.   case LED_1:  
  23.    GPIO_SetBits(GPIOC, GPIO_Pin_7);  
  24.    break;  
  25.   case LED_2:  
  26.    GPIO_SetBits(GPIOC, GPIO_Pin_8);  
  27.    break;  
  28.   default:  
  29.    break;  
  30.  }  
  31. }  
  32.   
  33. void led_off(uint32_t n)  
  34. {  
  35.  switch (n)  
  36.  {  
  37.   case LED_0:  
  38.    GPIO_ResetBits(GPIOC, GPIO_Pin_6);  
  39.    break;  
  40.   case LED_1:                              
  41.    GPIO_ResetBits(GPIOC, GPIO_Pin_7);  
  42.    break;  
  43.   case LED_2:  
  44.    GPIO_ResetBits(GPIOC, GPIO_Pin_8);  
  45.    break;  
  46.   default:  
  47.    break;  
  48.  }  
  49. }</SPAN>  
#include "stm32f10x.h"
#include "led.h"

void led_init(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
 GPIO_Init(GPIOC, &GPIO_InitStructure);
}

void led_on(uint32_t n)
{
 switch (n)
 {
  case LED_0:
   GPIO_SetBits(GPIOC, GPIO_Pin_6);
   break;
  case LED_1:
   GPIO_SetBits(GPIOC, GPIO_Pin_7);
   break;
  case LED_2:
   GPIO_SetBits(GPIOC, GPIO_Pin_8);
   break;
  default:
   break;
 }
}

void led_off(uint32_t n)
{
 switch (n)
 {
  case LED_0:
   GPIO_ResetBits(GPIOC, GPIO_Pin_6);
   break;
  case LED_1:                            
   GPIO_ResetBits(GPIOC, GPIO_Pin_7);
   break;
  case LED_2:
   GPIO_ResetBits(GPIOC, GPIO_Pin_8);
   break;
  default:
   break;
 }
}

 

根据不同的板子需要对该代码中的管脚进行修改,但结构是一样的。

main.c

  1. <SPAN style="FONT-SIZE: 18px">#include "led.h"  
  2.   
  3. static void delay(uint32_t ms)  
  4. {  
  5.  uint32_t count = 8000;  
  6.  while (ms--)  
  7.  {  
  8.   while (count--);  
  9.   count = 8000;  
  10.  }  
  11. }  
  12.   
  13. int main(void)  
  14. {  
  15.  led_init();  
  16.    
  17.  for (;;)  
  18.  {  
  19.   led_on(LED_0);  
  20.   led_off(LED_1);  
  21.   led_off(LED_2);  
  22.   delay(1000);  
  23.   
  24.   led_off(LED_0);  
  25.   led_on(LED_1);  
  26.   led_off(LED_2);  
  27.   delay(1000);  
  28.   
  29.   led_off(LED_0);  
  30.   led_off(LED_1);  
  31.   led_on(LED_2);   
  32.   delay(1000);  
  33.  }  
  34. }  
  35. </SPAN>  
#include "led.h"

static void delay(uint32_t ms)
{
 uint32_t count = 8000;
 while (ms--)
 {
  while (count--);
  count = 8000;
 }
}

int main(void)
{
 led_init();
 
 for (;;)
 {
  led_on(LED_0);
  led_off(LED_1);
  led_off(LED_2);
  delay(1000);

  led_off(LED_0);
  led_on(LED_1);
  led_off(LED_2);
  delay(1000);

  led_off(LED_0);
  led_off(LED_1);
  led_on(LED_2); 
  delay(1000);
 }
}


 

    在project中建立init,bsp组,并将各种代码加入。在工程的Options中,c/c++选项卡的Include Paths中添加.\include;.\src\libstm32\cmsis;.\src\libstm32\inc;.\src\bsp;。
    Output选项卡Select Folder for Objects中选.\output\obj。
    Listing选项卡Select Folder for Listings中选.\output\list。
    Debug选项卡选use ULINK Cortex Debugger, Run to main()打钩,这一步大家可以根据自己手上的仿真器做不同选择。
    编译运行。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值