基于STM32单片机流水灯控制中的GPIO_Init()函数解析

控制/MCU

1854人已加入

描述

学习STM32时,首先要熟悉流水灯例程,在这里就来分析流水灯中的GPIO_Init()函数

例如:流水灯例程中使用的端口是macLED1_GPIO_PORT=GPIOB,

控制的引脚是GPIO_Pin_0,

引脚的模式是GPIO_Mode_Out_PP(通用推挽输出),

引脚的速率是GPIO_Speed_50MHz,

用到的寄存器是CRL

将上述的引脚、模式、速率换算成32位的16进制,分别是:

1)控制的引脚是GPIO_Pin_0

换算成32位的16进制是:0x0000 0001

2)引脚的模式是GPIO_Mode_Out_PP(通用推挽输出)

换算成32位的16进制是:0x0000 0010

3)引脚的速率是GPIO_Speed_50MHz

换算成32位的16进制是:0x0000 0003

然后调用库函数GPIO_Init(),初始化GPIOB

GPIO_Init(macLED1_GPIO_PORT, &GPIO_InitStructure);

GPIO_Init()函数的定义如下:

流水灯

GPIO Mode Configuration

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

可以得出currentmode=0x0000 0010 & 0x0000 000F

=0x0000 0000

if ((((uint32_t)GPIO_InitStruct-》GPIO_Mode) & ((uint32_t)0x10)) != 0x00)

判断是否是输出模式,“是”,执行下面代码;“否”,不执行

如:0x0000 0010 & 0x0000 00010 !=0x 0000 0000

则执行下面语句

{

/* Output mode */

currentmode “= (uint32_t)GPIO_InitStruct-》GPIO_Speed;

可以得出currentmode=currentmode | 0x0000 0003=0x0000 0000

=0x0000 0003

}

GPIO CRL Configuration

if(((uint32_t)GPIO_InitStruct-》GPIO_Pin&((uint32_t)0x00FF)) != 0x00)

判断是否是Pin0~Pin7引脚,“是”,执行下面代码;“否”,不执行

如:0x0000 0001 & 0x 0000 00FF != 0x0000 0000

则执行下面语句

{

tmpreg = GPIOx-》CRL;

备份原CRL寄存器的值

则是:tmpreg=0x4444 4444

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

{

pos = ((uint32_t)0x01) 《《 pinpos;

pos是0x0000 0001左移 pinpos 位得到的

如:pos=0x0000 0001 《《 0x00

= 0x0000 0001

为后面的if (currentpin == pos) 判断作准备

/* Get the port pins position */

currentpin = (GPIO_InitStruct-》GPIO_Pin) & pos;

可得currentpin= 0x0000 0001 & 0x0000 0001

=0x0000 0001

为后面的if (currentpin == pos) 判断作准备

if (currentpin == pos)

由上面得出的pos = 0x0000 0001

currentpin = 0x0000 0001

两者相等,则执行下面代码语句

{

pos = pinpos 《《 2;

可得pos= 0x0000 0000 《《 2

=0x 0000 0000

/* Clear the corresponding low control register bits */

pinmask = ((uint32_t)0x0F) 《《 pos;

可得pinmask=0x0000 000F 《《 0x0000 0000

= 0x0000 000F

tmpreg &= ~pinmask;

可得tmpreg= tmpreg & ~pinmask

= 0x4444 4444 & 0xFFFF FFF0

= 0x4444 4440

/* Write the mode configuration in the corresponding bits */

tmpreg |= (currentmode 《《 pos);

首先,要知道currentmode 《《 pos = 0x0000 0003 《《 0x 0000 0000

= 0x 0000 0003

可得tmpreg= tmpreg | 0x0000 0003

= 0x4444 4440 & 0x0000 0003

= 0x4444 4443

/* Reset the corresponding ODR bit */

if (GPIO_InitStruct-》GPIO_Mode == GPIO_Mode_IPD)

判断是否为下拉输入模式

{

GPIOx-》BRR = (((uint32_t)0x01) 《《 pinpos);

}

else

{

/* Set the corresponding ODR bit */

if (GPIO_InitStruct-》GPIO_Mode == GPIO_Mode_IPU)

判断是否为上拉输入模式

{

GPIOx-》BSRR = (((uint32_t)0x01) 《《 pinpos);

}

}

结果,两种输入模式都不是,而是通用推挽输出,所以不执行

}

}

GPIOx-》CRL = tmpreg;

把前面处理后的暂存值写入到CRL寄存器之中

也就是GPIOx-》CRL= 0x4444 4443

}

最终,向GPIOB组的CRL寄存器写入一个值:

GPIOx-》CRL = 0x4444 4443

转换为二进制是:(0100 0100 0100 0100 0100 0100 0100 0011)B

因此,Pin0的控制值为(0011)B

下面是CRL寄存器的说明

流水灯

对比一下CRL寄存器的说明,Pin0的控制值正好可以把GPIO设置为符合我们输入参数要求的状态,即最大速率为50MHz的通用推挽输出模式。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分