STM32 GPIO口的配置和应用
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状态。
小结:
- 上拉输入:接入上拉电阻,与电源接通,所以默认状态下读到的GPIO引脚电平为高电平,即为1
- 下拉输入:接入下拉电阻,与地接通,所以默认状态下读到的GPIO引脚电平为低电平,即为0
- 浮空输入:既不接上拉也不接下拉,所以输入的是高电平就是高电平,低电平就是低电平
- 在输入模式下可以通过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口的配置和应用的更多相关文章
- STM32 GPIO口模式配置
F103系列 typedef struct { uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. This pa ...
- stm32寄存器版学习笔记01 GPIO口的配置(LED、按键)
STM32的I/O口可以由软件配置成如下8种模式:输入浮空.输入上拉.输入下拉.模拟输入.开漏输出.推挽输出.推挽式复用功能及开漏复用功能.每个I/O口由7个寄存器来控制:配置模式的端口配置寄存器CR ...
- STM32——GPIO口的八种工作模式
GPIO的输入工作模式1——输入浮空模式: GPIO_Mode_IN_FLOATING =0x04 工作原理:配置完相应寄存器为此工作模式后,高低电平信号通过1处的IO口输入进去,由于寄存器配置了的缘 ...
- (十)stm32 GPIO口复用,重映射 RCC_APB2Periph_AFIO
什么时候需要用到RCC_APB2Periph_AFIO--复用IO时钟的使用 需要用到外设的重映射功能时才需要使能AFIO的时钟 外部中断(EXTI)中与AFIO有关的寄存器是AFIO-EXTICR1 ...
- STM32f10xxx 之 GPIO口配置
背景 配置stm32f103使其完成PWM输出的过程中,在配置GPIO口的时候,按照习惯配置GPIO口的speed为50MHZ,突然就意识到,为什么大部分例程习惯配置为50MHZ,而不是其它值,即有了 ...
- Silicon C8051F340之GPIO口配置与使用
一.背景: 很久前用过C8051,现在有相关需求需要重新使用C8051,然后发现一年前开发的相关经验都忘得 基本上差不多了.连最基本的GPIO口配置还得重新来看手册,所以有此文,做个记录,以备下次快速 ...
- C6748的GPIO口配置使用
2018年1月17日更新: 这几天用了创龙的C6748的库,对于GPIO配置十分不爽,我移植了RK6748的库,用起来十分酸爽,把下面的文件加入到工程中,然后include头文件后就可以使用.非常好使 ...
- GPIO原理与配置(跑马灯,蜂鸣器,按键)
一.STM32 GPIO固件库函数配置方法 1. 根据需要在项目中删掉一些不用的固件库文件,保留有用的固件库文件 2. 在stm32f10x_conf.h中注释掉这些不用的头文件 3. STM32的I ...
- STM32的GPIO口的输出开漏输出和推挽输出
本文来自cairang45的博客,讲述了STM32的GPIO口的输出开漏输出和推挽输出, 作者博客:http://blog.ednchina.com/cairang45 本文来自: 高校自动化网(Ww ...
随机推荐
- HTML基本单词《结构化标签》
- [考试反思]1002csp-s模拟测试57:平庸
一天两场,感觉要完. 不粘排行榜,太壮观了. #1:190 #2:180 #4:160 #35:150 #37:140 #39:120 #kx:20呃... 最后一个是考试结束后了. 又是CE盖40分 ...
- [模板]tarjan——最后通牒
这么久了我还是不会板子,你们随便笑话我吧. 再不会打我实在是无能为力了. 这篇博客写的像个智障一样...写它的目的就是自嘲? 才不是,为了方便查阅,因为我真的记不住. 对于割边,要存储该点入边的编号, ...
- STL&&用法集合
.....STL是c++里很强势很好用的一系列容器(函数)之类的,之前一直不太会用,所以总是暴毙....想着快比赛了,是时候理一下这些东西了. -1.pair 存放两个基本元素的东西 定义方法: pa ...
- 洛谷 P 5 3 0 4 [GXOI/GZOI2019]旅行者
题目描述 J 国有 n 座城市,这些城市之间通过 m 条单向道路相连,已知每条道路的长度. 一次,居住在 J 国的 Rainbow 邀请 Vani 来作客.不过,作为一名资深的旅行者,Vani 只对 ...
- Chrome DevTools调试微信X5内核页面
起因:公司最近在做一个双十一的H5宣传页面,大概需求就是模拟微信视频来电,接通视频后弹出某某明星的视频巴拉巴拉@#%!!!~.看到需求我的第一反应是So easy,正当我码代码码的开心的时候,难题他来 ...
- getchar()用法 【转】
1.从缓冲区读走一个字符,相当于清除缓冲区 2.前面的scanf()在读取输入时会在缓冲区中留下一个字符'\n'(输入完s[i]的值后按回车键所致),所以如果不在此加一个getchar()把这个回车符 ...
- html5 点击播放video的方法
html5 点击播放video的方法<pre> <video videosrc="{$vo.shipinurl}" controls="" x ...
- php查询字符串的函数
/* 查找一个字符串在另一个字符串的第一次出现,并返回其余部分(strstr别名) */ var_dump(strchr("hello world hello", "wo ...
- SpringMVC错误:nested exception is java.lang.IncompatibleClassChangeError: class org.springframework.core.type.clas
这是jar包冲突引起的 spring-core.jar已经有asm 所以不用再单独导入asm包了