野火STM32学习笔记(构建库函数模型第五节课)

解释初始化函数是怎么运作的
第四节课我们已经了解了如何通过固件库编程的方式初始化一个GPIO口,配置其速度,工作模式等等,这一切都有一个“幕后黑手”就是那一个一百多行的GPIO_Init()函数。我们再来一睹一下芳容:

第一部分
我们从第一行开始看:

大括号内第一二行都是存放这些变量的初始值,可以不用太在意。再看下面模式配置那边,第一行注释是把模式的低四位存入变量currentmode,这样做的目的是取出这些值(与0x0F相与取值),再判断它的bit4位是几(如下图),是0则是输入,是1则是输出,判断方式也很简单,即赋值给currentmode的值和0x10(二进制00010000)与运算,看看是不是0就知道是输入还是输出了。如果是输出就要配置工作速度,可以看到if下面那个括号里就是配置工作速度的,把想要设置的代表速度的值,加到变量currentmode里面去。

第二部分
下面我们要判断是低八位的io还是高八位的,这就需要我们通过结构体GPIO_Pin确定

可以看到第一行if里面,32位的结构体成员GPIO_Pin(在结构体GPIO_InitTypeDef里,用GPIO_InitStruct这个名字代表)和0x00FF(二进制数0000000011111111)与运算,看看是不是等于0。如果不等于0,就先把低八位寄存器备份到变量tmpreg中,再执行for循环里面的内容。
for循环里,设置记录GPIO_Pin口的位置的变量初值为0x00,设置循环8次,每循环一次+1。循环里面pos的值设置为1,并且左移pinpos位,每次的得到的值和结构体成员GPIO_Pin做与运算,并且赋值给变量currentpin。如果currentpin和pos相等,则说明(GPIO_InitStruct->GPIO_Pin)&pos等于pos,即GPIO_InitStruct->GPIO_Pin是1,就是说这个GPIO口我们会取到。
这个时候if(currentpin==pos)这个条件成立,执行if里面的内容。第一行pos = pinpos << 2;注释是 pinpos的值左移两位(乘以4),因为寄存器中4个寄存器位配置一个引脚,它的作用具体来说是由于pinpos是从0开始,0对应着第一个寄存器位PX0,四个位对应一个IO口,例如PB1它是端口配置低寄存器CRL的第4567四个位控制的。如果我想通过pinpos控制他,就要把他左移两位(1→100→乘4)来控制PB1口。简单描述就是数值对应的口,是从0开始的,而寄存器必须从第一个bit开始就算他是PB0,因此每控制一个寄存器口就要pinpos左移四个bit,即乘4,即pinpos左移两位。

下面两行是清零操作,和寄存器编程的折这部分作用相同。

下面这一行是把将要配置的引脚位,引脚模式写入变量currentmode里面去,再赋值给tmpreg里面,多次循环之后再判断是上拉还是下拉输入,就可以把currentmode的临时变量存入CRL寄存器中了(见第一张图的最后一行)。

寄存器初始化函数到此就结束了,谢谢大家。