1. 基于标准库外设库开发的一般流程
基于标准外设库开发的一般流程
- 开启系统时钟
- 确定功能引脚
- 初始化外设硬件
a. 开启相应外设硬件
b. 配置外设功能参数,调用初始化函数,初始化外设相关的参数
c. 使能相关的外设 - 应用功能的实现
- 若有中断,则编写中断服务程序
2. GPIO 标准库外设接口函数及引用
GPIO 标准外设库接口函数主要分为以下三大类,其常用接口函数如表所示。
(1)初始化及复位函数。
(2)引脚功能操作函数。
(3)外部中断处理函数。
NO. | 类型 | 函数 | 功能描述 |
---|---|---|---|
1 | 初始化及复位函数 | GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) | 工具 GPIO 初始化结构参数初始化 GPIOx 外设寄存器 |
2 | 初始化及复位函数 | GPIO_DeInit(GPIO_TypeDef* GPIOx) | 将 GPIOx 外设寄存器恢复为默认复位值 |
3 | 初始化及复位函数 | GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct) | 初始化 GPIO 结构体 |
4 | 初始化及复位函数 | GPIO_AFIODeInit(void) | 取消所有复用功能 |
1 | 引脚功能操作函数 | GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal) | 置位或复位选定的 GPIO 数据端口 |
2 | 引脚功能操作函数 | GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal) | 置位或复位选定的 GPIO 端口引脚 |
3 | 引脚功能操作函数 | GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | 置位选定的 GPIO 端口引脚 |
4 | 引脚功能操作函数 | GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | 复位选定的 GPIO 端口引脚 |
5 | 引脚功能操作函数 | GPIO_ReadInputData(GPIO_TypeDef* GPIOx) | 读取选定的 GPIO 输入端口数据 |
6 | 引脚功能操作函数 | GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | 读取选定的 GPIO 输入端口引脚数据 |
7 | 引脚功能操作函数 | GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | 读取选定的 GPIO 输出端口数据 |
8 | 引脚功能操作函数 | GPIO_ReadOutputData(GPIO_TypeDef* GPIOx) | 读取选定的 GPIO 输出端口引脚数据 |
1 | 外部中断处理函数 | GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource) | 外设端口作为中断线配置 |
2 | 外部中断处理函数 | GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource) | 事件输出配置 |
GPIO 标准外设库接口函数的源代码在stm32f103x_gpio.c
中,其对应的头文件stm32f103x_gpio.h
声明了 GPIO 的所有库函数,共18种,如下图。
GPIO_Init()函数用于初始化 GPIO,该函数有两个输入参数,第一个参数用于指定 GPIO 的具体端口 x (x=A,B,C,D,E)
,第二个参数根据 GPIO_StructInit 结构体变量种指定的参数初始化 GPIO,GPIO_StructInit 是指向 GPIO_InitTypeDef 结构体的指针,包含 GPIO 的配置参数,如具体的 GPIO 引脚、输出速度、GPIO 引脚的工作模式灯,GPIO_InitTypeDef 结构体在stm32f10x_gpio.h
中定义,如下图所示。
GPIO_InitTypeDef 结构体成员及其取值。
GPIO_InitTypeDef 的结构体成员 | 取值范围 |
---|---|
GPIO_Pin | GPIO_Pin_0 ~ GPIO_Pin_15 GPIO_Pin_All(端口所有引脚) |
GPIO_Speed | GPIO_Speed_10MHz(最大输出速率为 10MHz GPIO_Speed_2MHz(最大输出速率为 2MHz GPIO_Speed_50MHz(最大输出速率为 50MHz) |
GPIO_Mode | GPIO_Mode_AIN(模拟输入模式) GPIO_Mode_IN_FLOATING(浮空输入模式) GPIO_Mode_IPD(下拉输入模式) GPIO_Mode_IPU(上拉拉输入模式 GPIO_Mode_Out_OD(通用开漏输出模式) GPIO_Mode_Out_PP(通用推挽输出模式) GPIO_Mode_AF_OD(复用开漏输出模式) GPIO_Mode_AF_PP(复用推挽输出模式) |
3. 实例:点亮 LED 灯
3.1 硬件设计
普中科技STM32F103ZET6开发板上 LED 电路图如下图所示:
在前面我们介绍过如何查看原理图,相同网络标号表示它们是连接在一起的,因此 DS0、DS1 发光二极管阴极是连接在 STM32 的 PB5、PE5 管脚上。如果要使 DS0 指示灯亮,只需要控制 PB5 管脚输出低电平,如果要使 DS0 指示灯灭,只需控制 PB5 输出高电平。对于其他的 LED 控制方法一样。如果你们使用的是其他板子,连接 LED 的管脚和极性不一样,那么只需要在程序中修改对应的 GPIO 管脚和输出电平状态即可,原理是一样的。
我们所要实现的功能是点亮 DS0 发光二极管,即让 STM32 的 PB5管脚输出一个低电平。
3.2 系统流程图
本实例的主流程图由两部分构成:初始化函数部分和无限循环功能部分,如下图。
3.3 软件设计
(1)新建一个 led.h
头文件。 该文件用于存放led.c
文件的管脚定义、全局变量声明和函数等内容,相关代码如下:
// 宏定义,用于防止头文件被重复包含,这样编译时不会提示“redefine(重复定义)”的错误
#ifndef _led_H
#define _led_H
#include "stm32f10x.h"
void LED_Init(void);
#endif
(2)新建一个 led.c
文件。 该文件用于 GPIO 端口初始化操作,即硬件驱动程序的编写,相关代码如下:
#include "led.h"
/**
* @brief LED初始化函数
* @brief :简介,简单介绍函数作用
* @param :介绍函数参数
* @return:函数返回类型说明
* @exception NSException 可能抛出的异常.
* @author zhangsan: 作者
* @date 2011-07-27 22:30:00 :时间
* @version 1.0 :版本
* @property :属性介绍
*/
void LED_Init(void)
{
//2.1 定义结构体变量
GPIO_InitTypeDef GPIO_InitStructure;
//1、开启GPIO外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
//2、初始化GPIO
//2.2 给定义的结构体变量成员赋值
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5; // 选择要设置的IO口
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; // 设置传输速率
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; // 设置通用推挽输出模式
//2.0 初始化GPIO
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_5); // 将LED端口拉高,熄灭所有LED
}
(3) main.c
文件的代码如下:
#include "stm32f10x.h"
#include "led.h"
/**
* @brief delay,延时函数,通过while循环占用CPU,达到延时功能
*
* @param i
*/
void delay(u32 i)
{
while (i--)
{
}
}
int main()
{
LED_Init();
while(1)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_5); // 将LED端口拉低,LED亮
delay(6000000);
GPIO_SetBits(GPIOB,GPIO_Pin_5); // // 将LED端口拉高,熄灭所有LED
delay(6000000);
}
}