(一)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状态。

小结:

  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积分资料!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342