hello,小伙伴们,大家好,这里是左左右。上期视频我们使用CLion写了一个MY_GPIO_Init()的函数。将PA15引脚设置为推挽输出模式。我们先自己操作寄存器来试一下。
首先,定义一个32位指针指向GPIOA的CRH寄存器。接着,将MODE15设置为11,将CNF15设置为00。接着,我们就一起来看看HAL库源码是如何将PA15引脚设置为推挽输出模式的。

首先,我们新建了一个结构体变量。变量名为GPIO_InitStruct。我们打开GPIO_InitTypeDef这个结构体看一眼。里面一共就4个结构体成员。接着,我们给结构体成员赋值。这里HAL库都是使用的宏定义。方便程序的阅读和编写。找到他们对应的真实值并记录。接着,来看HAL_GPIO_Init()这个函数。
这里传入的第一个参数GPIOA是我们很熟悉的。GPIOA就是指向GPIO_TypeDef结构体的指针,而且GPIOA结构体指针中存放的地址就是GPIOA的基地址,而刚才定义的结构体变量以指针的形式传入HAL_GPIO_Init()函数作为第二个参数。这样做的目的是HAL_GPIO_Init()函数内部可以通过结构体指针的形式对结构体成员进行读取和赋值。
接着,进入HAL_GPIO_Init()函数内部看看。从代码数量来看,这个函数的代码行数是挺多的。接着,我们从代码结构来看看代码的复杂程度。首先,函数一进来先定义了一些变量。接着,就进入了while循环。while循环中只有一个if判断语句。如果条件不满足就执行position++。
if判断语句中又嵌套了switch选择语句和if判断语句,而这个判断语句是关于EXTI外部中断的,大概率和我们是无关的。这样来看这个函数本身并不复杂。接着,我们从头来看这个函数。此时while循环中GPIO_Init->Pin中的值就是GPIO_PIN_15。对应二进制数就是0x8000(即第15位为1)。

同理将while循环中的条件和变量ioposition、iocurrent用二进制数表示出来。随着while循环的执行,position递增。当position等于15时if判断条件成立,进入switch选择语句。由于我们设置的是推挽输出模式,switch选择语句会跳到这一行。
给config赋值。然后,就跳出switch选择语句了。这里的 ? :是 C 语言中的条件运算符,也叫三元运算符。这个也很简单,当问号前的条件满足就返回冒号后的第一个值。条件不满足就返回冒号后的第二个值。由于这里的iocurrent中的值(0x8000)大于GPIO_PIN_8(0x0100),所以,条件不成立。
返回冒号后的第二个值。此时configregister变量就是指向GPIOA的CRH寄存器的指针。registeroffset变量中的值是28,也就是对应MODE15和CNF15在CRH寄存器中的偏移量。按下CTRL点击MODIFY_REG这个函数。

首先,来看WRITE_REG。很简单就是将后面的值赋值到前面的变量,而READ_REG就是这个值本身。接着,来看MODIFY_REG。它执行的操作是先将第一个参数与第二个参数的取反值做按位与(即清零操作)。再与第三个参数做按位或(即置1操作)。之后将结果赋值到第一个参数。
这里先通过清零操作将GPIOA_CRH寄存器中MODE15、CNF15对应的位清零。接着,通过置位操作将GPIOA_CRH寄存器设置为推挽输出模式,也就是我们自己写的第二行、第三行代码的效果。通过对HAL库源码的学习,我们发现HAL还是很严谨的。在对GPIOA_CRH寄存器设置推挽输出模式前先进行了清零的操作。

现学现用。我们也对自己写的代码进行一个清零的操作。同时CLion这个软件也拥有强大的调试功能。点击这里的行号就会出现一个小红点,也就是我们所熟悉的断点。接着,点击这里的绿色小甲壳虫。点击键盘上的F7。代码就开始单行执行了。在这里我们还可以看到变量中的值。接着,点击这里的外设。
我这里是显示寄存器的,你们第一次打开会提示加载svd文件。接着,打开STM32CubeMX。点击Help下Docs and Resources找到System View Description并下载。下载完成后找到STM32F103.svd文件。把它复制到你能找到的地方。

返回CLion加载STM32F103.svd文件。找到GPIOA_CRH寄存器就可以看到MODE15和CNF15位的值了。接着,回到HAL_GPIO_Init()函数。
下面这个if条件(EXTI配置部分)不成立。position执行加加操作。此时的position值为16。while条件不成立。跳出while循环。HAL_GPIO_Init()函数到此结束。
好的,今天的视频就到这里。如果觉得有收获,一定要关注、点赞、收藏、评论。你的支持是我这样的小博主持续更新下去的最大动力。期待下期视频再见!