STM32的GPIO使用的函数剖析
引脚相或就可以了。若你要多某一个端口的所有为进行配置,那么只需要使用一个宏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
STM32GPIO使函数剖 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)