微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > STM32的GPIO使用的函数剖析

STM32的GPIO使用的函数剖析

时间:11-10 来源:互联网 点击:

引脚相或就可以了。若你要多某一个端口的所有为进行配置,那么只需要使用一个宏GPIO_Pin_All。简单吧!哈哈!

GPIOSpeed_TypeDef是一个枚举变量,它用于存储GPIO速度的参数,它的定义如下:

typedefenum

{

GPIO_Speed_10MHz=1,

GPIO_Speed_2MHz,

GPIO_Speed_50MHz

}GPIOSpeed_TypeDef;

通过定义可以知道,GPIOSpeed_TypeDef的变量有三种取值,那么GPIO的速度有三种,

枚举变量的值

对应的速度

1

10MHZ

2

2MHZ

3

50MHZ

GPIOMode_TypeDef也是一个枚举变量,它用于存储GPIO工作的模式,它的定义如下:

typedefenum

{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;

设计这个枚举变量的可取值有一定的意义。在第四位当中只用到了其中的高两位,这两位数据用来存储到某一个引脚的模式控制位MODEx[1:0],而高四位用来标志某一些标志。

高四位的取值

意义

0

输入模式

1

输出模式

2

下拉输入

4

上拉输入

3、函数代码详解

上面是GPIO_Init函数参数的解释。我在我们就可以进入GPIO_Init函数的内部看看了。

先把函数的代码列出,对代码的解释都放在了注释当中,如下:

voidGPIO_Init(GPIO_TypeDef*GPIOx,GPIO_InitTypeDef*GPIO_InitStruct)

{

uint32_tcurrentmode=0x00,currentpin=0x00,pinpos=0x00,pos=0x00;

uint32_ttmpreg=0x00,pinmask=0x00;

/*Checktheparameters*/

assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));

assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));

/*----------------------------GPIOModeConfiguration-----------------------*/

currentmode=((uint32_t)GPIO_InitStruct->GPIO_Mode)&((uint32_t)0x0F);

if((((uint32_t)GPIO_InitStruct->GPIO_Mode)&((uint32_t)0x10))!=0x00)//若为输出上拉就会配置GPIO的速度

{

/*Checktheparameters*/

assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));

/*Outputmode*/

currentmode|=(uint32_t)GPIO_InitStruct->GPIO_Speed;

}

/*----------------------------GPIOCRLConfiguration------------------------*/

/*Configuretheeightlowportpins*/

if(((uint32_t)GPIO_InitStruct->GPIO_Pin&((uint32_t)0x00FF))!=0x00)//若对第八个引脚进行配置,GPIO_Pin的值某一位为1就会对该引脚配置

{

tmpreg=GPIOx->CRL;//暂存GPIO控制寄存器原来的值

for(pinpos=0x00;pinpos<0x08;pinpos++)//扫描8次决定,查看哪一引脚需要配置,若//需要配置则进行配置

{

pos=((uint32_t)0x01)

/*Gettheportpinsposition*/

currentpin=(GPIO_InitStruct->GPIO_Pin)&pos;//currentpin的值为0或者为pos

if(currentpin==pos)//若为pos说明该位需要配置

{

pos=pinpos<2;//pinpos的值乘以4得到某一引脚配置位的最低位号:0,4,8......28

/*Clearthecorrespondinglowcontrolregisterbits*///用于屏蔽某一个引脚的配置位,使这4位为0

pinmask=((uint32_t)0x0F)

tmpreg&=~pinmask;

/*Writethemodeconfigurationinthecorrespondingbits*/

tmpreg|=(currentmode

/*ResetthecorrespondingODRbit*/

if(GPIO_InitStruct->GPIO_Mode==GPIO_Mode_IPD)//若为输入下拉,需要打开相应的开关

{

GPIOx->BRR=(((uint32_t)0x01)

}

else

{

/*SetthecorrespondingODRbit*/

if(GPIO_InitStruct->GPIO_Mode==GPIO_Mode_IPU)//若为输入下拉,需要打开相应的开关

{

GPIOx->BSRR=(((uint32_t)0x01)

}

}

}

}

GPIOx->CRL=tmpreg;//对低8个引脚配置寄存器赋值

}

/*----------------------------GPIOCRHConfiguration------------------------*/

/*Configuretheeighthighportpins*/

if(GPIO_InitStruct->GPIO_Pin>0x00FF)

{

tmpreg=GPIOx->CRH;

for(pinpos=0x00;pinpos<0x08;pinpos++)

{

pos=(((uint32_t)0x01)<(pinpos+0x08));

/*Gettheportpinsposition*/

currentpin=((GPIO_InitStruct->GPIO_Pin)&pos);

if(currentpin==pos)

{

pos=pinpos<2;

/*Clearthecorrespondinghighcontrolregisterbits*/

pinmask=((uint32_t)0x0F)

tmpreg&=~pinmask;

/*Writethemodeconfigurationinthecorrespondingbits*/

tmpreg|=(currentmode

/*ResetthecorrespondingODRbit*/

if(GPIO_InitStruct->GPIO_Mode==GPIO_Mode_IPD)

{

GPIOx->BRR=(((uint32_t)0x01)<(pinpos+0x08));

}

/*SetthecorrespondingODRbit*/

if(GPIO_InitStruct->GPIO_Mode==GPIO_Mode_IPU)

{

GPIOx->BSRR=(((uint32_t)0x01)<(pinpos+0x08));

}

}

}

GPIOx->CRH=tmpreg;

}

}

4、备注

assert_param函数是对参数的检测。参数要么是逻辑0或者1。IS_GPIO_ALL_PERIPH也是一个宏,宏定义为:

#defineIS_GPIO_ALL_PERIPH(PERIPH)(((PERIPH)==GPIOA)||\

((PERIPH)==GPIO

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top