任何一个单片机,最简单的外设莫过于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、开漏式复用功能 首先看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当和配套实验源码。
实验1 跑马灯实验.zip
(465.75 KB)
第六章 跑马灯实验-STM32F4开发指南-正点原子探索者STM32开发板.pdf
(1.7 MB)
|