一、GPIO
坚持…
文章目录
- 一、GPIO
-
- 1、概述
- 2、GPIO工作模式(暂时不做深入研究先用)
- 3、GPIO使用
-
- 使用步骤
- ①GPIO输出
-
- LED.C
- main.c
- ②GPIO输入
-
- Key.c
- main.c
- 4、问题总结
1、概述
GPIO,即通用I/O(输入/输出)端口,是STM32可控制的引脚。STM32芯片的GPIO引脚与外部设备连接起来,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。
STM32F103有7组IO。分别为GPIOA~GPIOG,每组IO有16个IO口,共有112个IO口。通常称为 PAx、PBx、PCx、PDx、PEx、PFx、PGx,其中x为0-15,F1系列是基于Cortex-M3内核
2、GPIO工作模式(暂时不做深入研究先用)
─ 输入浮空
─ 输入上拉
─ 输入下拉
─ 模拟输入
─ 开漏输出
─ 推挽式输出
─ 推挽式复用功能
─ 开漏复用功能
3、GPIO使用
使用步骤
1.硬件时钟初始化----开启时钟
2.时钟配置----GPIO_A/GPIO_B
3.GPIO配置----输入/输出、工作模式
4.硬件控制----输出高低电平
1.硬件时钟初始化------参考stm32f10x_rcc.c库这里面包含了芯片的所有时钟
库里面会告诉我们怎样去初始化使用我们需要打开的时钟和配置
如下图:
初始化函数原型:
/*
函数参数:
RCC_APB2Periph:选择你要初始化的硬件时钟
NewState:使能/不使能
*/
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)//初始化时钟
{
/* assert_param 判断有效性 */
/* Check the parameters */
assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); //入口参数 1
assert_param(IS_FUNCTIONAL_STATE(NewState)); //入口参数 2
if (NewState != DISABLE)
{
RCC->APB2ENR |= RCC_APB2Periph;
}
else
{
RCC->APB2ENR &= ~RCC_APB2Periph;
}
}
2.GPIO初始化------参考stm32f10x_gpio.c
GPIO中会用到函数
如图:
初始化函数原型:
/*
函数参数:
GPIOx:选择你要初始化的GPIO组(GPIOA-GPIOG)
GPIO_InitStruct:GPIO初始化结构体(工作模式/IO/工作速度配置)
*/
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
初始化结构体:GPIO_InitTypeDef
/**
* @brief GPIO Init structure definition
*/
typedef struct
{
uint16_t GPIO_Pin; /*GPIO的IO口:PAx(x为0-15)*/
GPIOSpeed_TypeDef GPIO_Speed; /*IO口工作速度*/
GPIOMode_TypeDef GPIO_Mode; /*GPIO工作模式设置 */
}GPIO_InitTypeDef;
结构体成员:GPIOSpeed_TypeDef 速度
/**
* @brief Output Maximum frequency selection
*/
typedef enum //输出速率选择
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_10MHz) || ((SPEED) == GPIO_Speed_2MHz) || \
结构体成员 :GPIOMode_TypeDef 模式
/**
* @brief Configuration Mode enumeration
*/
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;
#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_AIN) || ((MODE) == GPIO_Mode_IN_FLOATING) || \
((MODE) == GPIO_Mode_IPD) || ((MODE) == GPIO_Mode_IPU) || \
((MODE) == GPIO_Mode_Out_OD) || ((MODE) == GPIO_Mode_Out_PP) || \
((MODE) == GPIO_Mode_AF_OD) || ((MODE) == GPIO_Mode_AF_PP))
①GPIO输出
实验1:LED闪烁(f103为例)
LED.C
/**
led1: PB5
led2: PE5
*/
void Led_Init(void)//初始化
{
GPIO_InitTypeDef GPIO_InitStructure;//定义初始化结构体类型用于配置GPIO模式
//1、硬件时钟的初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//使能GPIOE时钟
//2、GPIO的初始化
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//设置为推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//IO口选择
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设置输出速度
//3、初始化
GPIO_Init(GPIOB,&GPIO_InitStructure);//使用GPIOB端口
//4、IO控制
GPIO_SetBits(GPIOB,GPIO_Pin_5);//PB5 输出高电平
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//设置为推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设置输出速度
GPIO_Init(GPIOE,&GPIO_InitStructure); //使用GPIOE端口
GPIO_SetBits(GPIOE,GPIO_Pin_5);//PE5输出高电平
}
main.c
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"//调用延时函数库
int main(void)
{
Led_Init();//调用初始化
delay_init();//延时函数
while(1)
{
GPIO_SetBits(GPIOB,GPIO_Pin_5);//GPIOB输出高电平
GPIO_SetBits(GPIOE,GPIO_Pin_5);//GPIOE输出高电平
delay_ms(500);//延时
GPIO_ResetBits(GPIOB,GPIO_Pin_5);//GPIOB输出低电平
GPIO_ResetBits(GPIOE,GPIO_Pin_5);//GPIOE输出低电平
delay_ms(500);//延时
}
}
②GPIO输入
实验2:按键控制LED闪烁(f103为例)
输入检测
**
函数原型:
/**
* 函数功能:读取指定GPIO组某个引脚的电平状态
* @param GPIOx: 要读取的GPIO组
* @param GPIO_Pin: 选择读取的引脚
* 返回值:Bit_RESET/Bit_SET
*/
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
uint8_t bitstatus = 0x00;
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)
{
bitstatus = (uint8_t)Bit_SET;
}
else
{
bitstatus = (uint8_t)Bit_RESET;
}
return bitstatus;
}
时钟,GPIO初始化与LED上面一样,唯一区别是改为输出改为输入:GPIO_Mode_IPU
Key.c
/**
key0: PE4
key1: PE3
**/
void Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;//定义初始化结构体类型用于配置GPIO模式
//1、硬件时钟的初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//使能GPIOE时钟
//2、GPIO的初始化
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;//设置为上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;//IO口选择
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设置输出速度
//3、初始化
GPIO_Init(GPIOE,&GPIO_InitStructure); //使用GPIOE端口
//4、IO状态初始化
GPIO_SetBits(GPIOE,GPIO_Pin_4|GPIO_Pin_5);//GPIOE输出高电平
//5、读取IO口状态
}
main.c
#include "stm32f10x.h"
#include "delay.h"//调用延时函数库
int main(void)
{
Led_Init();//调用初始化
Key_Init();
delay_init();//延时函数
while(1)
{
if(Bit_RESET == GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4))
{
GPIO_ResetBits(GPIOB,GPIO_Pin_5);//GPIOB输出低电平
GPIO_ResetBits(GPIOE,GPIO_Pin_5);//GPIOE输出低电平
}
else
{
GPIO_SetBits(GPIOB,GPIO_Pin_5);//GPIOB输出高电平
GPIO_SetBits(GPIOE,GPIO_Pin_5);//GPIOE输出高电平
}
}
}