STM32,GPIO学习

一,GPIO输入和输出模式

STM32 的 IO 口 可以由软件配置成如下 8 种模式:
 ①  输入浮空
 ② 输入上拉
 输入下拉
 模拟输入
 ⑤  开漏输出
 ⑥  推挽输出
 ⑦  推挽式复用功能
 开漏复用功能

1.浮空输入模式下,I/O端口的电平信号直接进入输入数据寄存器。也就是说,I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的。

2.上拉输入模式下,I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在高电平;并且在I/O端口输入为低电平的时候,输入端的电平也还是低电平。

3.下拉输入模式下,I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在低电平;并且在I/O端口输入为高电平的时候,输入端的电平也还是高电平。

4.模拟输入模式下,I/O端口的模拟信号(电压信号,而非电平信号)直接模拟输入到片上外设模块,比如ADC模块等等。

5.开漏输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,途经N-MOS管,最终输出到I/O端口。这里要注意N-MOS管,当设置输出的值为高电平的时候,N-MOS管处于关闭状态,此时I/O端口的电平就不会由输出的高低电平决定,而是由I/O端口外部的上拉或者下拉决定;当设置输出的值为低电平的时候,N-MOS管处于开启状态,此时I/O端口的电平就是低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,I/O端口的电平不一定是输出的电平。其在实际stm32的IO口选用中IO输出0接GND,IO输出1,悬空,需要外接上拉电阻,才能实现输出高电平。当输出为1时,IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式,这样IO口也就可以由外部电路改变为低电平或不变。可以读IO输入电平变化,实现C51的IO双向功能

6.开漏复用输出模式,与开漏输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。

7.推挽输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,途经P-MOS管和N-MOS管,最终输出到I/O端口。这里要注意P-MOS管和N-MOS管,当设置输出的值为高电平的时候,P-MOS管处于开启状态,N-MOS管处于关闭状态,此时I/O端口的电平就由P-MOS管决定:高电平;当设置输出的值为低电平的时候,P-MOS管处于关闭状态,N-MOS管处于开启状态,此时I/O端口的电平就由N-MOS管决定:低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,此时I/O端口的电平一定是输出的电平。其在实际stm32的IO口选用中IO输出0-接GND, IO输出1 -接VCC,读输入值是未知的

8.推挽复用输出模式,与推挽输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。

二,GPIO的配置方法

我们从实例中逐渐分析
#include "led.h"
//初始化 PB5 和 PE5 为输出口.并使能这两个口的时钟 
//LED IO 初始化
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|
RCC_APB2Periph_GPIOE, ENABLE); //使能 PB,PE 端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5 推挽输出
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_SetBits(GPIOE,GPIO_Pin_5); /PE.5 输出高
}

1)首先 使能 IO 口时钟。调用函数为 RCC_APB2PeriphClockCmd()。即上述代码

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB| RCC_APB2Periph_GPIOE, ENABLE); //使能 GPIOB,GPIOE 端口时钟

若使能其他GPIO,只需把上述中GPIOB换成其他GPIO即可,如:RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//使能 GPIOC端口时钟

2)在配置完时钟之后 初始化 IO 参数。调用函数 GPIO_Init();
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
这个函数有两个参数,第一个参数是用来指定 GPIO ,取值范围为 GPIOA~GPIOG
第二个参数为初始化参数结构体指针,结构体类型为 GPIO_InitTypeDef 。即上述代码
GPIO_Init(GPIOB, &GPIO_InitStructure);       GPIO_Init(GPIOE, &GPIO_InitStructure);

结构体定义如下:

typedef struct
{ uint16_t GPIO_Pin;      
GPIOSpeed_TypeDef GPIO_Speed;   
GPIOMode_TypeDef GPIO_Mode;    
}GPIO_InitTypeDef;
结构体 GPIO_InitStructure 的第一个成员变量 GPIO_Pin 用来设置是要初始化
哪个或者哪些 IO 口;如上述代码中
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 推挽输出

第二个成员变量 GPIO_Mode 是用来设置对应 IO 端口的输出输入模式,

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;
其在上述代码中为
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
第三个参数是 IO 口速度设置,有三个可选值,在 MDK 中同样是通过枚举类型定义:
typedef enum
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
在上述代码中
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

 GPIO的配置即完成。设置 GPIO 端口的输入和输出状态多采用以下两种函数

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

比如我们要设 置 GPIOB.5 输出 1 ,那么方法为:
GPIO_SetBits(GPIOB, GPIO_Pin_5);
反之如果要设置 GPIOB.5 输出位 0 ,方法为:
GPIO_ResetBits (GPIOB, GPIO_Pin_5);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值