打印
[应用相关]

【转】STM32库函数中GPIO_Init的理解

[复制链接]
804|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Varus|  楼主 | 2018-7-26 21:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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;
配置一个引脚只需要4位寄存器,而上面却定义了8位,仔细研究GPIO_Init()函数后,确定为ST开发人员加上去的标识位。0x1_ 的是输出标识,其他则为输入模式。
下面看一下GPIO_Init()这个函数:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{
uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
uint32_t tmpreg = 0x00, pinmask = 0x00;
/* Check the parameters
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));

/*---------------------------- GPIO Mode Configuration -----------------------
currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);//屏蔽高半个字节的标识位
if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)//判断是否为输出,0x1_
{
/* Check the parameters
assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
/* Output mode
currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;//如果是输出,则加上相关的速度标志
}
/*---------------------------- GPIO CRL Configuration ------------------------
/* Configure the eight low port pins
if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)//判断引脚是否有效
{
tmpreg = GPIOx->CRL; //读出CRL寄存器中的值,并保存
for (pinpos = 0x00; pinpos < 0x08; pinpos++)
{
pos = ((uint32_t)0x01) << pinpos;
/* Get the port pins position 找出引脚的位置
currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
if (currentpin == pos)
{
pos = pinpos << 2; //pos*4,因为每个引脚配置占4位
/* Clear the corresponding low control register bits
pinmask = ((uint32_t)0x0F) << pos;
tmpreg &= ~pinmask; //把需要配置引脚的4位清0,其位不变
/* Write the mode configuration in the corresponding bits
tmpreg |= (currentmode << pos); //把配置数据写入tmpreg
/* Reset the corresponding ODR bit //如果是下拉输入或者上拉输入,则还需要配置PxODR位
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
{
GPIOx->BRR = (((uint32_t)0x01) << pinpos); //如果下拉,清除对应ODRy为0
}
else
{
/* Set the corresponding ODR bit
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
{
GPIOx->BSRR = (((uint32_t)0x01) << pinpos); //如果上拉,设置对应的ODRy为1
}
}
}
}
GPIOx->CRL = tmpreg; //把配置好的数值写入寄存器
}
沙发
gaoke231| | 2018-7-26 21:38 | 只看该作者
只要会用就可以了,不管它怎么封装的

使用特权

评论回复
板凳
21mengnan| | 2018-7-26 22:24 | 只看该作者
就是手册说的那几种模式的设置。

使用特权

评论回复
地板
jerow| | 2018-7-27 10:07 | 只看该作者
gaoke231 发表于 2018-7-26 21:38
只要会用就可以了,不管它怎么封装的

调试底层驱动的时候用得着的。

使用特权

评论回复
5
dongliushui| | 2018-7-27 14:55 | 只看该作者
那几个定义的确实是4个寄存器,但是4个寄存器包含了8个方法。

使用特权

评论回复
6
gaoke231| | 2018-8-19 19:58 | 只看该作者
jerow 发表于 2018-7-27 10:07
调试底层驱动的时候用得着的。

反正多看看不是坏处

使用特权

评论回复
7
labasi| | 2018-8-20 12:07 | 只看该作者
代码是好的 但是理解部分不多

使用特权

评论回复
8
wowu| | 2018-8-20 12:21 | 只看该作者
用的哪种库函数啊

使用特权

评论回复
9
xiaoqizi| | 2018-8-20 12:41 | 只看该作者
详细  涵盖了方方面面

使用特权

评论回复
10
木木guainv| | 2018-8-20 13:00 | 只看该作者
并不包含所有情况

使用特权

评论回复
11
guanjiaer| | 2018-8-21 09:30 | 只看该作者
wowu 发表于 2018-8-20 12:21
用的哪种库函数啊

看着不像是hal库

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

155

主题

703

帖子

1

粉丝