GPIO 外设讲解

通过博主上一篇博客,相信大家已经初步了解到了对于 STM32 的控制原理,但是 STM32 到外设 / 引脚有这么多,是要一个一个的去记住它的地址?或者每一次使用一个外设都要看一下数据手册?这样也太麻烦了吧,所以 STM32 便有固件库来方便大家使用,就不用去记那么多的外设地址了。

固件库
固件库原理是什么?
固件库怎么使用?
首先,固件库的原理其实是和上一篇文章讲到的原理是一样的。

上图可以看到:
其实,固件库就是将基地址宏定义成一个比较好记的名字,比如 GPIOB 的基地址就直接使用 GPIOB 这个宏就可以使用了,固件库将所有的地址全部定义了,省去了用户自己定义的时间,用户移植固件库后可以直接使用宏。
由此看来,固件库确实好操作,好理解了许多。

下面,我就开始讲解 STM32 固件库GPIO 外设的使用吧

GPIO 配置

我们以 GPIOB 为例子(其他 GPIO 外设操作一样)
首先,我们可以打开关于 GPIO 的固件库(stm32f10x_gpio.h 文件)。

里面,我们可以看到有一个关于 GPIO 的初始化结构体,我们只需要配置这个结构体就可以对 GPIO 进行引脚配置。

首先,我们可以看到结构体中有:1. 引脚;2. 模式;3. 速度;
接下来我们就开始分析三种配置;

  1. 引脚
    每一个 GPIO 外设都有 16 个引脚,这儿就可以配置使用的引脚是哪个引脚。

    这儿就有所有引脚的定义,我们只需要往里面填这些值就行:
#define GPIO_PIN GPIO_Pin_3                      //使用宏定义,方面改写,下同。
void GPIO_Config(void)                              //这儿我配置的GPIO初始化函数。
{GPIO_InitTypeDef GPIO_InitStruct;              //定义一个GPIO初始化变量。
//接下来配置GPIO结构体的值。GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;            //这儿将GPIO初始化的引脚定义成了3引脚。
//接下来的配置在下面会提到。
}
  1. 模式
    GPIO 引脚的模式比较多;

    这儿可以看到, GPIO 一共有 8 种模式,每一种模式都是什么?怎么用?我们可以在数据手册里面查看。

    这儿我们可以看到这 8 种模式的名称,可是,在什么情况用什么模式呢?接下来我会讲解,不过,其实在数据手册里面可以看到它对每一种外设的模式有配置。

    这儿就可以看到每一种外设的不同引脚有专用的模式;
    因为我们这儿只是使用普通的 GPIO 输出高电平或者低电平,所以我们可以配置通用推挽输出模式。(关于每种模式详解,文章以后更新会讲到,因为小编对于 8 种模式还只是模糊理解,所以不敢定论,待小编深度学习后,会回来这篇文章末尾补充,这儿不做详解。)
//这个代码插入上述GPIO_Config()函数中,下同。GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  1. 速度
    接下来就配置 GPIO 引脚的速度(并不是每个引脚都需要速度,输出才需要配置速度,输入不需要。)。
    因为上述我们使用的是通用推挽输出,所以要配置速度。

    这儿我们可以看到,对于速度我们有 3 种可以选择,因为下图

可以看到, GPIO 的外设是挂载到 APB2 上的,而固件库是将时钟配置成了 72MHz,所以 AHB 是 72MHz ,APB2 也是 72MHz , APB1 是 36MHz ,所以引脚速度直接配置最高的 50MHz 是没有问题的。

 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO 时钟
这样,我们把 GPIO 配置好了,但是还不能用,博主上一篇博客讲了要使用外设必须打开时钟,所以,我们要打开 GPIO 外设的时钟。
如何使用固件库打开 GPIO 的时钟?我们可以打开 stm32f10x_rcc.h 来看。
因为 GPIO 是挂载在 APB2 上面的,在 stm32f10x_rcc.h 里面我们可以找到这样一个函数:

这个函数就是可以打开 APB2 的时钟,这个时钟打开了,那么 GPIO 的时钟是不是也就打开了。
可是,怎么配置这个函数呢?
我们进入这个函数看看。

有注释来帮助我们看能够填写的变量。
因为我们是需要使用 GPIOB 这个外设,所以可以很清楚的看到里面有 RCC_APB2Periph_GPIOB 这个宏,而后面那个变量有两种选择:ENABLE(使能) or DISABLE(不使能).
所以,我们可以这样配置:

/*
这个定义在函数外。
*/
#define GPIO_PORT RCC_APB2Periph_GPIOB
#define GPIO_CLK RCC_APB2PeriphClockCmd
/*
下面定义在初始化函数内。
*/GPIO_CLK(GPIO_PORT, ENABLE);  //这样就打开了GPIOB外设的时钟。

最后,再初始化结构体就可以了。

在 gpio 固件库中可以看到这样的函数

里面有个 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); 的函数可以用来对 GPIO 的初始化。

怎么配置?

进入函数内部,可以看到:

还是看注释,第一个参数可以填 GPIOx ,什么是 GPIOx ?
就是 GPIOA / GPIOB / GPIOC ……
所以我们可以填 GPIOB ;
第二个参数可以看到,就是填写我们所定义的结构体指针,所以

/*
这个定义在函数外。
*/
#define GPIOx GPIOB
/*
下面定义在初始化函数内。
*/GPIO_Init(GPIOx, &GPIO_InitStruct);   //注意这儿是指针,所以要用&。

这样,GPIOB 就可以使用了!
可是, GPIOB 可以使用,该怎么使用呢?
还记得刚刚 gpio 固件库函数,里面是不是有很多函数?对!我们就是使用这些函数来操作这些 GPIOB 的引脚输出电平!
其实,输出高低电平只有两个函数就可以操作了,所以,我们目前只需要掌握两种函数。

这两个函数就可以设置或者清除 GPIOB 引脚,可以发现两个函数的输入参数是一样的,所以我们只需要看其中一个函数的参数就可以了。

通过这张图,我们就可以发现,填写的参数就是 GPIOx ,和 引脚号了。

 GPIO_SetBits(GPIOx, GPIO_PIN);      //设置IO口,使IO口置1。GPIO_ResetBits(GPIOx, GPIO_PIN);  //清除IO口,使IO口置0

对于上面函数是不是很分散,所以我总结了一下:

//宏定义,建议放在.h里面。
#define GPIO_PIN        GPIO_Pin_3
#define GPIO_PORT       RCC_APB2Periph_GPIOB
#define GPIO_CLK        RCC_APB2PeriphClockCmd
#define GPIOx           GPIOB
//函数放在.c文件。
void GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStruct;GPIO_CLK(GPIO_PORT, ENABLE);  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOx, &GPIO_InitStruct);
}

对于 GPIO 就配置好并可以使用了,接下来详解寄存器

其实,出了使用函数操作 IO 口还可以操作寄存器。
因为我们知道所有寄存器在固件库中都被定义。
所以我们可以直接操作寄存器。
首先我们要了解 GPIO 的寄存器。


这是关于 GPIO 所有的寄存器,我们接下来逐个分析。

CRL 寄存器

已知这个图很明显看出是配置引脚的输出模式和速度,但是这个只是配置的 0 ~ 7 这几个引脚,具体配置图中有。
所以相对的。

CRH 寄存器

这个是 8 ~ 15 引脚配置。与 CRL 寄存器作用相同。

IDR 寄存器


它的高 16 为是保留,就是没有使用,所以它只有低 16 为有效(能够使用低 16 位)。
它的作用就是可以读取 IO 口的状态,这个很好理解吧 IO 是高电平还是低电平。

ODR 寄存器


这个也是低 16 位有效,可以设置 16 个 IO 的输出;

BSRR 寄存器


这个寄存器可以对 IO 口进行设置和清除(也就是置位 0 / 1 )。
高 16 位置 1 就是对 IO 口清除,低 16 置 1 就是对 IO 口置 1 ,当这些位写 0 时不影响,这个就很保险。

BRR 寄存器


这个寄存器跟上述 BSRR 寄存器功能有些相似。
它是高 16 位保留,只有低 16 位有效,低 16 位之 0 时无影响, 置 1 时可以清除(也就是置 0)。

LCKR 寄存器


这个一共有 17 个位可以使用,最高位 16 位是用来激活这个寄存器功能。
置 1 -> 置 0 -> 置 1 -> 读取 0 -> 读取 1 这样就可以使寄存器激活。
低 16 位就是使 IO 口锁定,置 1 则 IO 口将不能再改变,置 0 则 IO 口可以再改变。

至此,小编的分享已经完了,谢谢各位的支持,如果有不对或者欠缺考虑的地方还请各位大佬多多指点。

STM32 固件库外设 GPIO 讲解(关于 GPIO 寄存器讲解)相关推荐

  1. 解读STM32标准库的程序架构 - 以GPIO操作为例

    前言 在开发新产品时,想必大家都曾像我一样碰到过一时难以解决的技术难题,在苦恼和无助中,只得求助于互联网,如果在网上突然发现有此问题相关的解决办法,以此解决了困扰了一整天甚至好几天的问题,这时大家的心 ...

  2. GD32F303固件库开发(5)----GPIO输出模式,速率测试、开漏和输出说明

    GD32F303固件库开发.5----GPIO输出模式,速率测试.开漏和输出说明 概述 样品申请 视频教学 csdn课程 硬件准备 开发板管脚配置 不同速率对应的波形 GPIO_OSPEED_2MHZ ...

  3. 8 . STM32固件库介绍

    STM32固件库介绍 前面为大家简单介绍了如何使用寄存器点亮开发板上LED,这种开发方式显然是不适合大众,对于STM32 这样庞大的芯片,内部寄存器实在太多,如果操作的外设比较多,那么就需要花很多时间 ...

  4. 第9章 初识STM32固件库—零死角玩转STM32-F429系列

    第9章     初识STM32固件库 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...

  5. STM32固件库(标准外设库)入门学习 第四章OLED屏幕使用

    STM32固件库(标准外设库)入门学习 第四章OLED屏幕使用 本学习教程,参考B站江科大自化协STM32视频,型号为STM32F103C8T6. 文章目录 STM32固件库(标准外设库)入门学习 第 ...

  6. STM32 固件库,CMSIS 标准,STM32Cube

    STM32 固件库与 CMSIS 标准讲解 STM32F4 固件库就是函数的集合,那么对这些函数有什么要求呢? 这里就涉及到一个 CMSIS 标准的基础知识.经常有人问到 STM32 和 ARM 以及 ...

  7. STM32固件库文件分析

    STM32固件库文件分析 1.汇编编写的启动文件 startup/stm32f10x.hd.s:设置堆栈指针,设置pc指针,初始化中断向量,配置系统时钟,对用c库函数_main最后去c语言世界里. 2 ...

  8. STM32固件库(标准外设库)入门学习 第六章TIM定时器(一)

    STM32固件库(标准外设库)入门学习 第六章TIM定时器(一) 文章目录 STM32固件库(标准外设库)入门学习 第六章TIM定时器(一) 前言 一.定时器类型 1 基本定时器 2 通用定时器 3 ...

  9. STM32固件库文件树及构成详解

    (想要pfd格式文件的可以留下邮箱) STM32固件库文件树及构成详解(库版本:STM32F10x_StdPeriph_Lib_V3.5.0) 库减压后所有文件夹构成如下: /

最新文章

  1. mysql 中default 和NULL
  2. java的同步块_Java 同步块
  3. c语言两种排序方法的组合,排列和组合算法的实现方法_C语言经典案例
  4. linux如何使用uboot的命令,Uboot常用命令使用
  5. java string rt_如何使jvm加载我的java.lang.String而不是rt.jar中的那个
  6. Android Native 内存泄漏系统化解决方案
  7. 机器学习——统计学习方法——第1章 统计学习及监督学习概论
  8. Ubuntu时间管理方法
  9. Tricks(三十二)—— 遍历全部的子串(子数组)
  10. Android小提示四
  11. solaris 系统信息查看
  12. c语言运算符的三大特性,逻辑运算符及其优先级,C语言逻辑运算符及其优先级详解...
  13. C++ 游戏服务器开发有什么推荐的学习资料或者书籍?
  14. Jenkins构建从github上克隆时,报Host key verification failed.
  15. js中的JSON对象转换,过滤特殊字符数据
  16. API理解清晰(转载)
  17. 数据缓存层及相关知识
  18. 微信-生成小程二维码
  19. 第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛(部分题解)
  20. 炸翻AI和生化环材圈!GPT-4学会自己搞科研,手把手教人类做实验

热门文章

  1. 三星Galaxy S20:如何调整振动强度和模式
  2. python坐标系转换_GNSS学习笔记-坐标转换
  3. 深入理解Spark RDD——RDD分区计算器Partitioner
  4. Kubernetes K8S之Pod跨namespace名称空间访问Service服务
  5. Python break语句:多层循环中break是终止(或跳出)本层(也即所在层)循环,后者说是跳出最内层循环。也就是break只能跳出一层循环而不是多层循环
  6. 66句震撼人心的禅语(转)
  7. 开机读不了bios,提示为 press del to enter setup, esc to enter boot menu?
  8. QT信号槽第五个参数
  9. nvm 安裝不同版本的node(詳細過程无图)
  10. nc608串口服务器型号,康海时代NC608系列产品信息