打印
[STM32F1]

STM32之一步一步点亮led

[复制链接]
1438|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

入手stm32以来,一直想快速上手,所以在各大论坛闲逛,各个达人的blog上学习,正所谓欲速则不达,心急是吃不了热豆腐的!有木有?

最终决定使用st官网的库开发,据大侠们写道使用库可以快速上手,貌似的确如此,一个个教程写的那么好,直接拿过来用就是了。可是那么多个库,聪明的你请告诉到底选择哪一个啊?My God!实话实说,我被这些库折腾了个够!好吧,我最后还是承认最后用的是v3.4的库,是很方便!

切入正题,点亮LED。

硬件:红牛开发板,STM32F103ZET6(144封装).

软件: RealView MDK 4.12

stm32固件库:v3.4 附上自己整理后的库:

V3.4_clean.rar  

根据官网库自己整理了下,新建了工程模板如下图:(主要参考**《在Keil MDK+环境下使用STM32 V3.4库.pdf》)在KeilMDK+环境下使用STM32V3.4库.pdf  


入图所示:新建一个目录01_ProLed,建议放在英文路径下,避免不必要的麻烦。将上面的库v3.4解压到此目录,再新建一个project目录,存放工程。

说明:
CMSIS:最底层接口。StartUp:系统启动文件。StdPeriph_Lib:stm32外围设备驱动文件。Project:工程文件。User:用户文件。新建工程步骤:此处略去300字。


简单说明:

1.core_cm3.c/core_cm3.h
该文件是内核访问层的源文件和头文件,查看其中的代码多半是使用汇编语言编写的。在线不甚了解。--摘自《在Keil MDK+环境下使用STM32 V3.4库》


沙发
zhuotuzi|  楼主 | 2016-8-10 20:00 | 只看该作者
2.stm32f10x.h
该文件是外设访问层的头文件,该文件是最重要的头文件之一。就像51里面的reg51.h一样。例如定义了 CPU是哪种容量的 CPU,中断向量等等。除了这些该头文件还定义了和外设寄存器相关的结构体,例如:
typedef struct
{
  __IO uint32_t CR;
  __IO uint32_t CFGR;
  __IO uint32_t CIR;
  __IO uint32_t APB2RSTR;
  __IO uint32_t APB1RSTR;
  __IO uint32_t AHBENR;
  __IO uint32_t APB2ENR;
  __IO uint32_t APB1ENR;
  __IO uint32_t BDCR;
  __IO uint32_t CSR;

#ifdef STM32F10X_CL
  __IO uint32_t AHBRSTR;
  __IO uint32_t CFGR2;
#endif /* STM32F10X_CL */

#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
  uint32_t RESERVED0;
  __IO uint32_t CFGR2;
#endif /* STM32F10X_LD_VL || STM32F10X_MD_VL || STM32F10X_HD_VL */
} RCC_TypeDef;

包含了那么多寄存器的定义,那么在应用文件中(例如自己编写的 main 源文件)只需要包含
stm32f10x.h即可,而不是以前固件库的需要包含 stm32f10x_conf.h这个头文件。--摘自《在Keil MDK+环境下使用STM32 V3.4库》

3.system_stm32f10x.c/h
该头文件也可以称为外设访问层的头文件和源文件。在该文件中可以定义系统的时钟频率,定义低速时钟
总线和高速时钟总线的频率,其中最关键的函数就是 SystemInit()了,这个后面会详细介绍。总之这两
个文件是新固件库的重点,有了它粮也大大简化了使用 stm32的初始化工作。--摘自《在Keil MDK+环境下使用STM32 V3.4库》

4.stm32f10x_conf.h
这个文件和 V2 版本的库的内容是一样的,需要使用哪些外设就取消哪些外设的注释。例如需要使用 GPIO功能,但不使用 SPI功能,就可以这样操作。--摘自《在Keil MDK+环境下使用STM32 V3.4库》

  • #include"stm32f10x_gpio.h"
  • /*#include"stm32f10x_spi.h"*/

5.main.c
这个文件就不用多说了,自己编写。 --摘自《在Keil MDK+环境下使用STM32 V3.4库》

6.stm32f10x_it.c/h
这两个文件包含了 stm32中断函数,在源文件和头文件中并没有把所有的中断入口函数都写出来,而
只写了 ARM内核的几个异常中断,其他的中断函数需要用户自己编写。--摘自《在Keil MDK+环境下使用STM32 V3.4库》

OK,开始写代码了。

由于3.4的库在启动的时候已经设置好时钟了(将在后面有讲述),所以我们只需设置好对应的GPIO即可。

查看硬件连接:

来点亮PF6.

新建led.c与led.h,添加到User Code下面。

led.h

#ifndef _LED_H_
#define _LED_H_

void Delay(uint32_t times);
void LedInit(void);

#endif

led.c

#include "stm32f10x.h"

/************************************************************************

* 函数名 :LedInit(void)

* 描述 :

* 输入 :无

* 输出 :无

* 返回 :无

************************************************************************/

void LedInit(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /*初始化 GPIOF的 Pin_6为推挽输出*/
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOF,&GPIO_InitStructure);
   
}

/************************************************************************

* 函数名 :Delay(uint32_t times)

* 描述 :延时函数

* 输入 :uint32_t times

* 输出 :无

* 返回 :无

************************************************************************/
void Delay(uint32_t times)
{
  while(times--)
  {
     uint32_t i;
     for (i=0; i<0xffff; i++)
     ;
  }
}


使用特权

评论回复
板凳
zhuotuzi|  楼主 | 2016-8-10 20:02 | 只看该作者
在main.c中加入led初始化与点亮关闭即可。
/*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */

  /* Add your application code here
     */

    /*初始化 GPIOF时钟*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);

    LedInit();
   
  /* Infinite loop */
  while (1)
  {
       /*关闭 LED1*/
        GPIO_SetBits(GPIOF,GPIO_Pin_6);
        /*延时*/
        Delay(50);
        /*点亮 LED1*/
        GPIO_ResetBits(GPIOF,GPIO_Pin_6);
        /*延时*/
        Delay(50);   
  }
认真学习下这段代码,其实也非常简单,参考自《在Keil MDK+环境下使用STM32 V3.4库》。我想请大家注意的是前面的一段英文注释,这段英文注释什么意思呢。“在运行 main 函数之前,系统时钟已经完成初始化工作,在main函数之前,通过调用启动代码运行了 SystemInit函数,而这个函数位于system_stm32f10x.c”。根据文中的提示我们回到 system_stm32f10x.c 看看 SystemInit如何初始化系统的。在 system_stm32f10x.c 的开头便定义了系统的时钟频率,从下面的这段代码可以看出系统的频率被定
义为 72MHZ,这也是绝大多数 STM32运行时的频率。
  • #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
  • /* #define SYSCLK_FREQ_HSE HSE_VALUE */
  • #define SYSCLK_FREQ_24MHz 24000000
  • #else
  • /* #define SYSCLK_FREQ_HSE HSE_VALUE */
  • /* #define SYSCLK_FREQ_24MHz 24000000 */
  • /* #define SYSCLK_FREQ_36MHz 36000000 */
  • /* #define SYSCLK_FREQ_48MHz 48000000 */
  • /* #define SYSCLK_FREQ_56MHz 56000000 */
  • #define SYSCLK_FREQ_72MHz 72000000
  • #endif

紧接着根据这个宏定义程序试图把系统时钟初始化为 72MHz,代码有点冗长,这里就不一一列出。在
SystemInit 函数中,调用了 SetSysClock 函数,如果设定时钟的频率为 72MHZ 则 SetSysCloc 调用
SetSysClockTo72函数,该函数和 V2 版本固件库中的各范例中的 RCC_Configuration很相似,主要完
成把外部时钟 9 倍频后分配给系统时钟,APB1 时钟和 APB2又由系统时钟分频获得。关键代码如下:

  • /* HCLK = SYSCLK */
  •     RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
  •     /* PCLK2 = HCLK */
  •     RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
  •     /* PCLK1 = HCLK */
  •     RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

从上面的分析可以看出,SystemInit 并不需要用户调用,启动代码会自动执行,这样相当于少了一
个 RCC_Configuration 函数的绝大多数内容。请大家注意是绝大多数内容而不是全部,但是请大家格外
注意使用到的外设还是要第一时间使得该外设的时钟,像这样的一句千万不要忘了

    /*初始化 GPIOF时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);


使用特权

评论回复
地板
zhuotuzi|  楼主 | 2016-8-10 20:03 | 只看该作者
本帖最后由 zhuotuzi 于 2016-8-10 20:55 编辑

如果没有设置好可能编译会出错:
1.设置宏。
2.设置头文件目录:但凡有.h目录的都加进来,还有一点说明,在工程中是不需要加载头文件的,编译器会根据设置自动到相应目录下查找,链接。
有图有真相:
源码: ProLed.rar  
另:由于使用了官网的库,所以很多时候需要在工程中查找文件或者是关键字,这个时候,可以用Source Insight工具来辅助阅读代码,它的Lookup reference很好使。可以在project目录下再建一个目录Source Insight,比较麻烦,但是实在!





使用特权

评论回复
5
mmuuss586| | 2016-8-10 20:20 | 只看该作者
谢谢分享;

使用特权

评论回复
6
fyaocn| | 2016-8-11 11:28 | 只看该作者
不错啊

使用特权

评论回复
7
fplman| | 2016-8-11 20:25 | 只看该作者
谢谢楼主!收藏学习...

使用特权

评论回复
8
dentsgot| | 2016-8-11 21:09 | 只看该作者
点亮LED,其实给GPIO高电平或者低电平

使用特权

评论回复
9
643757107| | 2016-8-12 22:56 | 只看该作者
SystemInit 并不需要用户调用,启动代码会自动执行

使用特权

评论回复
10
bbapple| | 2016-8-13 09:21 | 只看该作者
不错,楼主的思绪很到位,多谢分享

使用特权

评论回复
11
handleMessage| | 2016-8-13 09:33 | 只看该作者
stm32f10x_conf.h  这个文件和 V2 版本的库的内容是一样的,需要使用哪些外设就取消哪些外设的注释。

使用特权

评论回复
12
zhouhuanの| | 2016-8-13 09:34 | 只看该作者
使用st官网的库开发,据大侠们写道使用库可以快速上手我怎么觉得也没那么容易呢

使用特权

评论回复
13
sourceInsight| | 2016-8-13 13:01 | 只看该作者
main.c
这个文件我还是知道的哈

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

201

主题

3300

帖子

7

粉丝