在嵌入式系统中,经常需要控制许多结构简单的外部设备或者电路,这些设备有的需要通过CPU控制,有的需要CPU提供输入信号。对设备的控制,使用传统的串口或者并口就显得比较复杂,所以,在嵌入式微处理器上通常提供了一种“通用可编程I/O端口”,也就是GPIO。
本节将通过操作LED亮灭的方式,来实现对STM32F407的GPIO口操作。开发板LED相关的硬件原理图,如图4.17所示。
图4.17 LED原理图
根据原理图及LED的特性,我们可知:当LED0、LED1、LED2引脚输出低电平的时候,3个LED将会发光;反之输出高电平的时候,3个LED将熄灭。
而LED0、LED1、LED2这3个引脚又分别对应到STM32F407芯片上的GPIOE_3、GPIOE_4、GPIOG_9。故而,LED的亮灭操作可以转化成STM32F407的引脚输出操作。
STM32F407有7组I/O。分别为GPIOA~GPIOG,每组I/O有16个I/O口,共有112个I/O口,通常称为PAx、PBx、PCx、PDx、PEx、PFx、PGx,其中x为0~15。
STM32F407有很多的内置外设,这些外设的外部引脚都与GPIO共用。也就是说,一个引脚可以有很多作用,但是默认为I/O口,如果想使用一个GPIO内置外设的功能引脚,就需要GPIO的复用,那么当这个GPIO作为内置外设使用的时候,就叫作复用。例如串口就是GPIO复用为串口。
GPIO_Mode_IN_FLOATING浮空输入
GPIO_Mode_IPU上拉输入
GPIO_Mode_IPD下拉输入
GPIO_Mode_AIN模拟输入
GPIO_Mode_Out_OD开漏输出(带上拉或者下拉)
GPIO_Mode_AF_OD复用开漏输出(带上拉或者下拉)
GPIO_Mode_Out_PP推挽输出(带上拉或者下拉)
GPIO_Mode_AF_PP复用推挽输出(带上拉或者下拉)
2MHz(低频)
25MHz(中频)
50MHz(快频)
100MHz(高频)
STM32标准外设库是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。该函数库还包括每一个外设的驱动描述和应用实例,为开发者访问底层硬件提供了一个中间API,通过使用固件函数库,无须深入掌握底层硬件细节,开发者就可以轻松应用每一个外设。
因此,使用固态函数库可以大大减少开发者开发使用片内外设的时间,进而降低开发成本。每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能。同时,STM32官方还给出了大量的示例代码以供学习。
STM32标准外设库可以到ST官网下载,也可以直接使用本书附录部分提供的STM32标准外设库。
使用Keil MDK编写代码时,我们需要将STM32标准外设库添加到工程中去。这里推荐读者直接使用附录已经添加好的工程文件。
使用Keil MDK的new project选项,打开LED demo代码的工程文件:Chapter4/01_led/01_demo.uvprojx,如图4.18所示。
图4.18 LED工程代码
图4.18左边是工程的代码文件。
common:整个工程的公共代码部分,主要实现delay函数等。
main:工程的main函数部分,程序启动后的入口函数。我们从main.c文件开始分析。
startup_config:汇编启动代码部分,我们后续再讲解。
stm32f4_fwlib:STM32F407的标准外设库文件部分。
user:用户编写的代码部分。
打开Chapter4/01_led/Main/main.c文件,代码如下:
void delay(int ms)函数:通过使用两个for循环,实现延时等待。
int main(void)函数:程序启动后的入口函数,调用LED_Init()函数实现GPIO口的初始化。
接下来进入while循环,调用GPIO_WriteBit使引脚输出高低电平。
其中,GPIO_WriteBit是STM32标准外设库里面的函数,其函数原型如下:
void GPIO_WriteBit(GPIO_T ypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
参数列表:
GPIO_TypeDef*GPIOx:对应STM32F407的GPIO口分组,可填参数有GPIOA~GPIOG。
uint16_t GPIO_Pin:具体引脚编号,可填参数有GPIO_Pin_0~GPIO_Pin_15。
BitAction BitVal:控制引脚输出的状态,可填参数有Bit_SET表示输出高电平,Bit_RESET表示输出低电平。
打开Chapter4/01_led/USER/led.c文件,代码如下:
该文件直接使用STM32标准外设库的函数初始化GPIO口。
GPIO_InitTypeDef GPIO_InitStructure;此语句定义GPIO_InitTypeDef结构体的局部变量,用于后面初始化GPIO引脚。
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOG,ENABLE);此语句打开GPIOE、GPIOG时钟。
GPIO_SetBits(GPIOE,GPIO_Pin_3|GPIO_Pin_4);此语句表示使用STM32标准外设库函数,设置GPIOE这一组的3、4引脚输出高电平。
单击方框所标出的build工具按钮,开始对代码进行编译,如图4.19所示。
图4.19 编译代码
编译结束后,可以看到Build Output的输出信息,如图4.20所示,则表示编译成功。
代码下载需要使用J-Link工具把开发板和计算机连接起来。之后单击Keil MDK中的Options for Target工具按钮,如图4.21所示。
图4.20 编译成功
图4.21 Options for Target按钮
单击Debug,在下拉菜单中选择J-LINK/J-TRACE Cortex。之后单击右边的Settings按钮,如图4.22所示。
图4.22 Debug界面
在弹出的界面中,选择Flash Download,如果Programming Algorithm内容是空的,则单击Add按钮,如图4.23所示。
弹出Add Flash Programming Algorithm界面后,如图4.24所示,选择STM32F4xx Flash,单击Add按钮。
图4.23 Flash Download界面
图4.24 Add Flash Programming Algorithm界面
之后会自动回到Flash Download界面,如图4.25所示,在Programming Algorithm中会显示一个STM32F4xx Flash条目,单击“确定”按钮。
图4.25 Flash Download界面
接下来单击方框标出的download工具按钮即可下载程序到开发板运行,如图4.26所示。
图4.26 download按钮
本节通过使用LED的例子,讲解了STM32的GPIO口操作,同时介绍了STM32标准外设库文件的使用。让读者第一次接触STM32的代码开发和程序下载等操作。