打印
[STM32F4]

【正点原子探索者STM32F407开发板例程连载】第6章 跑马灯实

[复制链接]
3748|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhangyang86|  楼主 | 2014-12-8 15:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
任何一个单片机,最简单的外设莫过于IO口的高低电平控制了,本章将通过一个经典的跑马灯程序,带大家开启STM32F4之旅,通过本章的学习,你将了解到STM32F4的IO口作为输出使用的方法。在本章中,我们将通过代码控制ALIENTEK探索者STM32F4开发板上的两个LED:DS0和DS1交替闪烁,实现类似跑马灯的效果。 本章分为如下四个小节:
       6.1, STM32F4 IO口简介
       6.2, 硬件设计
       6.3, 软件设计
       6.4, 下载验证
6.1 STM32F4 IO简介
本章将要实现的是控制ALIENTEK探索者STM32F4开发板上的两个LED实现一个类似跑马灯的效果,该实验的关键在于如何控制STM32F4的IO口输出。了解了STM32F4的IO口如何输出的,就可以实现跑马灯了。通过这一章的学习,你将初步掌握STM32F4基本IO口的使用,而这是迈向STM32F4的第一步。
这一章节因为是第一个实验章节,所以我们在这一章将讲解一些知识为后面的实验做铺垫。为了小节标号与后面实验章节一样,这里我们不另起一节来讲。
       在讲解STM32F4的GPIO之前,首先打开我们光盘的第一个固件库版本实验工程跑马灯实验工程(光盘目录为:“4,程序源码\标准例程-库函数版本\实验1跑马灯/USER/ LED.uvproj”),可以看到我们的实验工程目录:
               
图6.1.1 跑马灯实验目录结构
    接下来我们逐一讲解一下我们的工程目录下面的组以及重要文件。
①       组FWLib下面存放的是ST官方提供的固件库函数,每一个源文件stm32f4xx_ppp.c都对应一个头文件stm32f4xx_ppp.h。分组内的文件我们可以根据工程需要添加和删除,但是一定要注意如果你引入了某个源文件,一定要在头文件stm32f4xx_conf.h文件中确保对应的头文件也已经添加。比如我们跑马灯实验,我们只添加了5个源文件,那么对应的头文件我们必须确保在stm32f4xx_conf.h内也包含进来,否则工程会报错。
②       组CORE下面存放的是固件库必须的核心文件和启动文件。这里面的文件用户不需要修改。大家可以根据自己的芯片型号选择对应的启动文件。
③       组SYSTEM是ALIENTEK提供的共用代码,这些代码的作用和讲解在第五章都有讲解,大家可以翻过去看下。
④       组HARDWARE下面存放的是每个实验的外设驱动代码,他的实现是通过调用FWLib下面的固件库文件实现的,比如led.c里面调用stm32f4xx_gpio.c内定义的函数对led进行初始化,这里面的函数是讲解的重点。后面的实验中可以看到会引入多个源文件。
⑤       组USER下面存放的主要是用户代码。但是system_stm32f4xx.c文件用户不需要修改,同时stm32f4xx_it.c里面存放的是中断服务函数,这两个文件的作用在3.1节有讲解,大家可以翻过去看看。Main.c函数主要存放的是主函数了,这个大家应该很清楚。
工程分组情况我们就讲解到这里,接下来我们就要进入我们跑马灯实验的讲解部分了。这里需要说明一下,我们在讲解固件库之前会首先对重要寄存器进行一个讲解,这样是为了大家对寄存器有个初步的了解。大家学习固件库,并不需要记住每个寄存器的作用,而只是通过了解寄存器来对外设一些功能有个大致的了解,这样对以后的学习也很有帮助。
首先要提一下,在固件库中,GPIO端口操作对应的库函数函数以及相关定义在文件stm32f4xx_gpio.h和stm32f4xx_gpio.c中。
相对于STM32F1来说,STM32F4的GPIO设置显得更为复杂,也更加灵活,尤其是复用功能部分,比STM32F1改进了很多,使用起来更加方便。
       STM32F4每组通用 I/O 端口包括 4 个 32 位配置寄存器(MODER、OTYPER、OSPEEDR 和 PUPDR)、2 个 32 位数据寄存器(IDR 和 ODR)、1 个 32 位置位/复位寄存器 (BSRR)、1 个 32 位锁定寄存器 (LCKR) 和 2 个 32 位复用功能选择寄存器(AFRH 和 AFRL)等。
这样,STM32F4每组IO有10个32位寄存器控制,其中常用的有4个配置寄存器+2个数据寄存器+2个复用功能选择寄存器,共8个,如果在使用的时候,每次都直接操作寄存器配置IO,代码会比较多,也不容易记住,所以我们在讲解寄存器的同时会讲解是用库函数配置IO的方法。
同STM32F1一样,STM32F4的IO可以由软件配置成如下8种模式中的任何一种:
1、输入浮空
2、输入上拉
3、输入下拉
4、模拟输入
5、开漏输出
6、推挽输出
7、推挽式复用功能
8、开漏式复用功能
关于这些模式的介绍及应用场景,我们这里就不详细介绍了,感兴趣的朋友,可以看看这个帖子了解下:http://www.openedv.com/posts/list/32730.htm 。接下来我们详细介绍IO配置常用的8个寄存器:MODER、OTYPER、OSPEEDR、PUPDR、ODR、IDR 、AFRH和AFRL。同时讲解对应的库函数配置方法。
首先看MODER寄存器,该寄存器是GPIO端口模式控制寄存器,用于控制GPIOx(STM32F4最多有9组IO,分别用大写字母表示,即x=A/B/C/D/E/F/G/H/I,下同)的工作模式,该寄存器各位描述如表5.2.5.1所示:
表5.2.5.1 GPIOx MODER寄存器各位描述
       该寄存器各位在复位后,一般都是0(个别不是0,比如JTAG占用的几个IO口),也就是默认条件下一般是输入状态的。每组IO下有16个IO口,该寄存器共32位,每2个位控制1个IO,不同设置所对应的模式见表5.2.5.1描述。
       然后看OTYPER寄存器,该寄存器用于控制GPIOx的输出类型,该寄存器各位描述见表5.2.5.2所示:
表5.2.5.2 GPIOx OTYPER寄存器各位描述
       该寄存器仅用于输出模式,在输入模式(MODER[1:0]=00/11时)下不起作用。该寄存器低16位有效,每一个位控制一个IO口,复位后,该寄存器值均为0。
       然后看OSPEEDR寄存器,该寄存器用于控制GPIOx的输出速度,该寄存器各位描述见表5.2.5.3所示:
表5.2.5.3 GPIOx OSPEEDR寄存器各位描述
       该寄存器也仅用于输出模式,在输入模式(MODER[1:0]=00/11时)下不起作用。该寄存器每2个位控制一个IO口,复位后,该寄存器值一般为0。
然后看PUPDR寄存器,该寄存器用于控制GPIOx的上拉/下拉,该寄存器各位描述见表5.2.5.4所示:
表5.2.5.4 GPIOx PUPDR寄存器各位描述
该寄存器每2个位控制一个IO口,用于设置上下拉,这里提醒大家,STM32F1是通过ODR寄存器控制上下拉的,而STM32F4则由单独的寄存器PUPDR控制上下拉,使用起来更加灵活。复位后,该寄存器值一般为0。
前面,我们讲解了4个重要的配置寄存器。顾名思义,配置寄存器就是用来配置GPIO的相关模式和状态,接下来我们讲解怎么在库函数初始化GPIO的配置。
GPIO相关的函数和定义分布在固件库文件stm32f4xx_gpio.c和头文件stm32f4xx_gpio.h文件中。
在固件库开发中,操作四个配置寄存器初始化GPIO是通过GPIO初始化函数完成:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
这个函数有两个参数,第一个参数是用来指定需要初始化的GPIO对应的GPIO组,取值范围为GPIOA~GPIOK。第二个参数为初始化参数结构体指针,结构体类型为GPIO_InitTypeDef。下面我们看看这个结构体的定义。首先我们打开我们光盘的跑马灯实验,然后找到FWLib组下面的stm32f4xx_gpio.c文件,定位到GPIO_Init函数体处,双击入口参数类型GPIO_InitTypeDef后右键选择“Go to definition of …”可以查看结构体的定义:
typedef struct
{
  uint32_t GPIO_Pin;   
  GPIOMode_TypeDef GPIO_Mode;   
  GPIOSpeed_TypeDef GPIO_Speed;
  GPIOOType_TypeDef GPIO_OType;  
  GPIOPuPd_TypeDef GPIO_PuPd;   
}GPIO_InitTypeDef;
下面我们通过一个GPIO初始化实例来讲解这个结构体的成员变量的含义。
通过初始化结构体初始化GPIO的常用格式是:
GPIO_InitTypeDef  GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9//GPIOF9
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIO
上面代码的意思是设置GPIOF的第9个端口为推挽输出模式,同时速度为100M,上拉。
从上面初始化代码可以看出,结构体GPIO_InitStructure的第一个成员变量GPIO_Pin用来设置是要初始化哪个或者哪些IO口,这个很好理解;第二个成员变量GPIO_Mode是用来设置对应IO端口的输出输入端口模式,这个值实际就是配置我们前面讲解的GPIOx的MODER寄存器的值。在MDK中是通过一个枚举类型定义的,我们只需要选择对应的值即可:
typedef enum
{
  GPIO_Mode_IN   = 0x00, /*!< GPIO Input Mode */
  GPIO_Mode_OUT  = 0x01, /*!< GPIO Output Mode */
  GPIO_Mode_AF   = 0x02, /*!< GPIO Alternate function Mode */
  GPIO_Mode_AN   = 0x03  /*!< GPIO Analog Mode */
}GPIOMode_TypeDef;
GPIO_Mode_IN是用来设置为复位状态的输入,GPIO_Mode_OUT是通用输出模式,GPIO_Mode_AF是复用功能模式,GPIO_Mode_AN是模拟输入模式。
第三个参数GPIO_Speed是IO口输出速度设置,有四个可选值。实际上这就是配置的GPIO对应的OSPEEDR寄存器的值。在MDK中同样是通过枚举类型定义:
typedef enum
{
  GPIO_Low_Speed     = 0x00, /*!< Low speed    */
  GPIO_Medium_Speed  = 0x01, /*!< Medium speed */
  GPIO_Fast_Speed    = 0x02, /*!< Fast speed   */
  GPIO_High_Speed    = 0x03  /*!< High speed   */
}GPIOSpeed_TypeDef;
/* Add legacy definition */
#define  GPIO_Speed_2MHz    GPIO_Low_Speed   
#define  GPIO_Speed_25MHz   GPIO_Medium_Speed
#define  GPIO_Speed_50MHz   GPIO_Fast_Speed
#define  GPIO_Speed_100MHz  GPIO_High_Speed


由于字数显示,详细内容请参考附件pdf当和配套实验源码。
GPIO相关的函数我们先讲解到这里。虽然IO操作步骤很简单,这里我们还是做个概括性的总结,操作步骤为:
1)  使能IO口时钟。调用函数为RCC_AHB1PeriphClockCmd ()。
2)  初始化IO参数。调用函数GPIO_Init();
3)  操作IO。操作IO的方法就是上面我们讲解的方法。
       上面我们讲解了STM32F4 IO口的基本知识以及固件库操作GPIO的一些函数方法,下面我们来讲解我们的跑马灯实验的硬件和软件设计。
6.2 硬件设计
由于字数显示,详细内容请参考附件pdf当和配套实验源码。



实验详细手册和源码下载地址:http://www.openedv.com/posts/list/41586.htm
正点原子探索者STM32F407开发板购买地址:http://item.taobao.com/item.htm?id=41855882779


  

实验1 跑马灯实验.zip (465.75 KB)
第六章 跑马灯实验-STM32F4开发指南-正点原子探索者STM32开发板.pdf (1.7 MB)

沙发
mmuuss586| | 2014-12-8 21:32 | 只看该作者

都是中文资料,支持楼主分享;

使用特权

评论回复
板凳
搞IT的| | 2014-12-8 23:40 | 只看该作者
好资料,顶一个。。。

使用特权

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

本版积分规则

个人签名:正点原子STM32开发板购买单击这里

80

主题

916

帖子

51

粉丝