STM32F103ZET6

  • 一共有7组IO口(有FT的标识是可以识别5v的)
  • 每组IO口有16个IO
  • 一共16*7=112个IO

4种输入模式:

(1) GPIO_Mode_AIN 模拟输入

(2) GPIO_Mode_IN_FLOATING 浮空输入

(3) GPIO_Mode_IPD 下拉输入

(4) GPIO_Mode_IPU 上拉输入

4种输出模式:

(5) GPIO_Mode_Out_OD 开漏输出

(6) GPIO_Mode_Out_PP 推挽输出

(7) GPIO_Mode_AF_OD 复用开漏输出

(8) GPIO_Mode_AF_PP 复用推挽输出

四种输入模式:

1、一图记住上拉、下拉、浮空输入模式:

原理分析:图中箭头表示信号流动方向。从I/O引脚向左沿着箭头方向,首先遇到两个开关和电阻,与VDD相连的称为上拉电阻,与Vss相连的称为下拉电阻,再连接到施密特触发器(信号转换)把电压信号转化为0、1的数字信号,存储在输入数据寄存器(IDR)。然后通过设置配置寄存器(CRL、CRH)控制这两个开关,于是就可以得到GPIO的上拉输入、下拉输入模式和浮空输入模式,浮空就是既不接上拉也不接下拉。在上拉/下拉/浮空输入模式中,输出缓冲器被禁止(P-MOS和N-MOS),施密特触发器输入被激活,根据输入配置(上拉,下拉或浮动)的不同,弱上拉和下拉电阻被连接,读输入数据寄存器的值可得到I/O状态。

小结:

  1. 上拉输入:接入上拉电阻,与电源接通,所以默认状态下读到的GPIO引脚电平为高电平,即为1
  2. 下拉输入:接入下拉电阻,与地接通,所以默认状态下读到的GPIO引脚电平为低电平,即为0
  3. 浮空输入:既不接上拉也不接下拉,所以输入的是高电平就是高电平,低电平就是低电平
  4. 在输入模式下可以通过ODR寄存器相对应的位来确定具体是上拉还是下拉,0是下拉,1是上拉。

2、一张图记住模拟输入:

原理分析:图中箭头表示信号流动方向。可以看出模拟输入模式关闭了施密特触发器,也不接上、下拉电阻,经由另一线路把电压信号传送到片上外设模块。如传送给 ADC 模数转换模块,由ADC 采集电压信号。所以使用 ADC外设时,必须设置为模拟输入模式。在此模式中,输出缓冲器被禁止,禁止施密特触发输入,实现了每个模拟I/O引脚上的零消耗,施密特触发输出值被强制置为0,弱上拉和下拉电阻被禁止,读取输入数据寄存器时数值为0。

小结:模拟输入模式把图中的红色字体部分都禁止了。注意:GPIO在输入模式下是不需要设置端口的最大输出速度的。

四种输出模式:

1、一张图记住开漏和推挽输出模式:

原理分析:

开漏输出:图中箭头表示信号流动方向。如果往输出数据寄存器写入0,因为N-MOS是接地的,低电平信号会激活N-MOS,所以输出的IO口引脚为低电平。但是反过来是不成立的(另一个模式才可以),你肯定会想,如果写入1,P-MOS接电源,所以输出1,不是这样的。开漏输出模式P-MOS从不被激活,所以开漏模式只可以输出强低电平,高电平得靠外部电阻拉高,要得到高电平状态需要上拉电阻才行。

推挽输出:输出数据寄存器上的0激活N-MOS,I/O口输出低电平;而输出数据寄存器上的1将激活P-MOS,I/O口输出高电平。两个管子轮流导通,一个负责灌电流,一个负责拉电流,使其负载能力和开关速度都比普通方式有很大提高。

小结:开漏就是推挽的二分之一。开漏模式只可以输出强低电平。

2、一张图记住开漏复用和推挽复用输出:

当I/O端口被配置为复用功能时,其他配置跟开漏和推挽一样的,只不过开漏和推挽是由CPU来写,而复用就是外设来写0和1。至于选择复用开漏输出还是复用推挽输出,是根据 GPIO 复用功能来选择的,如 GPIO 的引脚用作串口输出,则使用复用推挽输出模式;如用在I2C、SMBUS 等这些需要“线与”功能的复用场合,就使用复用开漏模式。

小结:复用是外设来写0和1。

GPIO相关寄存器配置

每一组IO口都有以下7个寄存器

 - GPIOx_CRL:端口配置低寄存器(32位)
- GPIOx_CRH:端口配置高寄存器(32位)
- GPIOx_IDR:端口输入寄存器(32位)
- GPIOx_ODR:端口输出寄存器(32位)
- GPIOx_BSRR:端口位设置/清除寄存器(32位)
- GPIOx_BRR:端口位清除寄存器(16位)
- GPIOx_LCKR:端口配置锁存寄存器(32位)不常用

1、CRL和CRH寄存器

这两个32位寄存器是选择输入输出模式的时候起作用的,每4个位控制一个IO口,一组IO口有16个,所以一共需要64位,CRL管理(0~7)的IO口,CRH管理(8 ~15)的IO口。相应的值在MDK中通过一个枚举类型定义,只需要选择对应得值即可。

typedef enum
{ GPIO_Mode_AIN = 0x0,
GPIO_Mode_IN_FLOATING = 0x04,
GPIO_Mode_IPD = 0x28,
GPIO_Mode_IPU = 0x48,
GPIO_Mode_Out_OD = 0x14,
GPIO_Mode_Out_PP = 0x10,
GPIO_Mode_AF_OD = 0x1C,
GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;

2、ODR和IDR寄存器

ODR寄存器只用到了前面的16位。作用是控制GPIOx(x=A ~ G)的输出,即设置某个IO口输出低电平还是高电平,只有在输出模式下有效。

在固件库中设置ODR寄存器来控制IO口的输出状态是通过这两个函数来实现的:
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);//读取一组
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);//读取几个 uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//读取一组
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);//读取几个
两个函数功能类似,区别是,前面的函数用来一次读取一组I/O口所有I/O口输出状态
后面的函数用来一次读取一组I/O口中一个或者几个I/O口的输出状态。

IDR寄存器也只用到了前面的16位。该寄存器用于读取GPIOx的输入,读取的某个I/O电平,如果对应的位为0(IDRy=0),则说明该脚输入为低电平;如果是1(IDRy=1),则表示输入的是高电平。用于寄存器设置的相关库函数为:

前面的函数用来读取一组I/O口的一个或者几个I/O口输入电平,后面的函数用来一次读取一组I/O口中所有I/O口的输入电平。
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef*GPIOx,uint16_t GPIO_Pin);//读取一组
uint16_t GPIO_ReadInputData(GPIO_TypeDef*GPIOx);//读取几个
比如要读取GPIOF.3的输入电平,方法为:GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_3)。

3、端口位 设置/清除寄存器(GPIOx_BSRR)

该寄存器用来置位或复位I/O口,它和ODR寄存器具有类似的作用,都可以用来设置GPIO端口的输出位是1还是0。如果同时设置了BSy和BRy的对应位,BSy位起作用。其中,对于低16位(0 ~ 15),在相应位ODRy写1,对应的I/O口会输出高电平,写0,则对I/O口没有任何影响。高16位(16~31)作用刚好相反,对相应的位ODRy写1会输出低电平,写0没有任何影响。即对于BSRR寄存器,写0对I/O口电平是没有任何影响的。要设置某个I/O口电平,只需要设置相关位为1即可。而ODR寄存器要设置某个I/O口电平,首先需要读出来ODR寄存器的值,然后对整个ODR寄存器重新赋值来达到设置某个或某些I/O口的目的,而BSRR寄存器,就不需先读,而是直接设置。BSRR 寄存器使用方法如下:

GPIOA->BSRR=1<1;//设置GPIOA.1为高电平
GPIOA->BSRR=1<(16+1);//设置GPIOA.1为低电平

操作BSRR寄存器来设置I/O电平的库函数为:

//设置一组I/0口中的一个或者多个I/0口为高电平.
void GPIO_SetBits(GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin);

4、端口位清除寄存器(GPIOx_BRR)

寄存器用来置位或复位I/O口,即设置GPIO端口输出低电平。对于低16位(0~15),在相应位ODRy写1,对应的I/O口会输出低电平,写0则对I/O口没有任何影响。BRR 寄存器使用方法如下:

GPIOA->BRR=0×0001;//设置GPIOA.0为低电平

操作BRR寄存器来设置I/O电平的库函数为:

//设置一组I/0口中的一个或者多个I/0口为低电平
void GPIO_ResetBits(GPIO_TypeDef*GPIOx,uint16_t GPIO_Pin);

小结:BSRR和BRR寄存器最终也是操作ODR寄存器,BRR的作用相当于BSRR的高16位,一般使用BSRR的低16位和BRR来设置电平,BSRR的高16位很少使用。

欢迎关注我的公众号:物联网技术猿

我可以免费帮你下载csdn积分资料!

STM32 GPIO口的配置和应用的更多相关文章

  1. STM32 GPIO口模式配置

    F103系列 typedef struct { uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. This pa ...

  2. stm32寄存器版学习笔记01 GPIO口的配置(LED、按键)

    STM32的I/O口可以由软件配置成如下8种模式:输入浮空.输入上拉.输入下拉.模拟输入.开漏输出.推挽输出.推挽式复用功能及开漏复用功能.每个I/O口由7个寄存器来控制:配置模式的端口配置寄存器CR ...

  3. STM32——GPIO口的八种工作模式

    GPIO的输入工作模式1——输入浮空模式: GPIO_Mode_IN_FLOATING =0x04 工作原理:配置完相应寄存器为此工作模式后,高低电平信号通过1处的IO口输入进去,由于寄存器配置了的缘 ...

  4. (十)stm32 GPIO口复用,重映射 RCC_APB2Periph_AFIO

    什么时候需要用到RCC_APB2Periph_AFIO--复用IO时钟的使用 需要用到外设的重映射功能时才需要使能AFIO的时钟 外部中断(EXTI)中与AFIO有关的寄存器是AFIO-EXTICR1 ...

  5. STM32f10xxx 之 GPIO口配置

    背景 配置stm32f103使其完成PWM输出的过程中,在配置GPIO口的时候,按照习惯配置GPIO口的speed为50MHZ,突然就意识到,为什么大部分例程习惯配置为50MHZ,而不是其它值,即有了 ...

  6. Silicon C8051F340之GPIO口配置与使用

    一.背景: 很久前用过C8051,现在有相关需求需要重新使用C8051,然后发现一年前开发的相关经验都忘得 基本上差不多了.连最基本的GPIO口配置还得重新来看手册,所以有此文,做个记录,以备下次快速 ...

  7. C6748的GPIO口配置使用

    2018年1月17日更新: 这几天用了创龙的C6748的库,对于GPIO配置十分不爽,我移植了RK6748的库,用起来十分酸爽,把下面的文件加入到工程中,然后include头文件后就可以使用.非常好使 ...

  8. GPIO原理与配置(跑马灯,蜂鸣器,按键)

    一.STM32 GPIO固件库函数配置方法 1. 根据需要在项目中删掉一些不用的固件库文件,保留有用的固件库文件 2. 在stm32f10x_conf.h中注释掉这些不用的头文件 3. STM32的I ...

  9. STM32的GPIO口的输出开漏输出和推挽输出

    本文来自cairang45的博客,讲述了STM32的GPIO口的输出开漏输出和推挽输出, 作者博客:http://blog.ednchina.com/cairang45 本文来自: 高校自动化网(Ww ...

随机推荐

  1. [考试反思]阶段性总结:NOIP模拟测试7~13

    苟且Rank#1.第二次分机房结束. 得到了喘息一会的权利. 在最后两场考试中大脸skyh慷慨舍弃264分让出Rank#1的故事也十分感人 然而还是有很多东西值得思考. 虽说是反思,但是还是有一些地方 ...

  2. Android 4.2 获取应用缓存接口变化

    PackageManager.getPackageSizeInfo(String packageName, IPackageStatsObserver observer)不可用,改为PackageMa ...

  3. Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/util/PatternMatchUtils

    { "message": "Handler dispatch failed; nested exception is java.lang.NoClassDefFoundE ...

  4. Scrapy进阶知识点总结(二)——选择器Selectors

    1. Selectors选择器 在抓取网页时,您需要执行的最常见任务是从HTML源提取数据.有几个库可用于实现此目的,例如: BeautifulSoup是Python程序员中非常流行的Web抓取库,它 ...

  5. Medium高赞系列,如何正确的在Stack Overflow提问

    在我们写程序的时候,经常会遇到各色各样的问题,在国内,小伙伴们经常去知乎.CSDN.博客园.思否.安卓巴士等地方提问并获得答案. 这些地方汇集了很多优秀的.爱分享的国内资源.小编比较自豪的一件事情就是 ...

  6. C# web项目中sql数据库转sqlite数据库

    最近做了一个小网站,用到了一个使用sql server 2005的.net cms系统,但是现在我所买虚拟主机的服务商,不给虚拟主机提供sql server服务了,那就转数据库吧,转啥好呢,思来想去, ...

  7. springboot~高并发下耗时操作的实现

    高并发下的耗时操作 高并发下,就是请求在一个时间点比较多时,很多写的请求打过来时,你的服务器承受很大的压力,当你的一个请求处理时间长时,这些请求将会把你的服务器线程耗尽,即你的主线程池里的线程将不会再 ...

  8. Docker学习-Kubernetes - 集群部署

    Docker学习 Docker学习-VMware Workstation 本地多台虚拟机互通,主机网络互通搭建 Docker学习-Docker搭建Consul集群 Docker学习-简单的私有Dock ...

  9. 【algo&ds】1.时间复杂度和空间复杂度分析

    1.时间复杂度分析O(f(n)) 分析方法 只关注循环执行次数最多的一段代码 加法原则 乘法原则 高优先级原则 常见时间复杂度量级 多项式量级和非多项式量级.其中,非多项式量级只有两个:O(2^n) ...

  10. Typescript I: 遍历Array的方法:for, forEach, every等

    Typescript的官方文档 Iterators and Geneators (https://www.typescriptlang.org/docs/handbook/iterators-and- ...