40、HAL_GPIO_ReadPin()、HAL_GPIO_TogglePin()、HAL_GPIO_LockPin()源码详解。

hello,小伙伴们,大家好,这里是左左右。在前面视频中我给大家讲解了GPIO所有相关寄存器。接着,我们打开stm32f1xx_hal_gpio.c这个文件。这里的HAL_GPIO_Init()和HAL_GPIO_WritePin()。这两个函数的源代码我们是做过深度解析的,而这里的HAL_GPIO_DeInit()、HAL_GPIO_EXTI_IRQHandler()、HAL_GPIO_Callback()。

这三个函数是和EXTI外部中断相关的。所以,我们放到后面的视频讲解。这时GPIO相关函数就剩下。HAL_GPIO_ReadPin()、HAL_GPIO_TogglePin()、HAL_GPIO_LockPin()这三个函数了。这期视频我们就把这三个函数的源代码一网打尽。
在讲他们之前我先穿插的讲一个C语言的知识点,那就是枚举类型。在实际应用中,有些变量的取值范围是有限的,就比如说人的性别只有男和女两种。不可能会有第三种性别了。再比如说投出去的硬币落地后。只有正面和反面。当然,你要说可以是立着的。也可以把它加进去,还有比如三原色有红、绿、蓝。
现实中这种情况是数不胜数的,当然,在写程序时,你可以用0代表男性,1代表女性。但是,这时只有写程序的人才知道0,1代表什么。这样代码的可读性就会变得很差。这时就引出枚举这个概念了。
首先,我们定义一个性别的枚举,把鼠标移动到枚举成员这里。我们可以发现male默认为0,female默认为1,也就是说枚举成员默认情况下是从0开始依次递增的。接着,我们定义一个枚举变量。打印输出来看一下。结果就是0和1。和我们预想的一模一样。接着,来看枚举成员占用内存空间大小。
打印输出结果为4。也就可以推断枚举成员是int类型。为了简化枚举变量的定义,我们可以在这里加个typedef。然后,把枚举名称放到后面。这时定义枚举变量就可以不用加enum了。这个方法在定义结构体时也用到了。听过前面视频的小伙伴应该并不陌生。当然,我们也可以将这里的默认值设置为其它值。

这时female值也是递增1。当然,我们也可以根据自己的实际需求定义female的值。好的,关于枚举类型的介绍就到这里了。接着,一起来看一下上期视频写好的代码。按下Ctrl跳转到定义HAL_GPIO_ReadPin()这个函数的地方。这里首先定义了一个枚举类型的变量。GPIO_PinState就是枚举类型。

代表GPIO的引脚状态。GPIO_PIN_RESET代表低电平。对应值为0。GPIO_PIN_SET代表高电平。对应值为1。当PC13对应IDR寄存器值为1时,这里运算结果是一个非零的值。if判断条件成立。返回高电平。当PC13对应IDR寄存器值为0时,这里运算结果为0。

if判断条件不成立。返回低电平。这里写法常常用来判断寄存器中某一位中的值是否为零?大家一定要记住。接着,来看HAL_GPIO_TogglePin()这个函数。这里首先定义了一个名为odr的变量。接着,把GPIOA中odr寄存器中的值赋值到odr变量。接着,来看这行代码。
虽然看起来挺复杂,但是,我们知道它肯定是要实现电平的翻转功能。首先,我们假设此时PA15为高电平。来看一下这里的运算结果。我们将运算结果放入GPIOA BSRR寄存器。这时PA15就实现了电平翻转的目的了。这里我们假设PA15为高电平。你们也可以试试假设PA15为低电平。
是不是也能实现电平翻转的功能?接下来我们再来看看HAL_GPIO_LockPin()这个函数。这里假设我们要锁定的IO口还是PA15。首先,定义变量tmp。它存放的值其实就是1左移16位。接着,来看这里的SET BIT。它就是两者做或运算。
接下来就是将GPIOA LCKR寄存器中位16。进行置1、置0、置1、和读1的操作了。这个和我们前面讲的是一模一样的,接下来判断位16是否被置1?当条件成立,说明PA15就被锁了。到目前为止我们将GPIO相关寄存器和源码全部学习完了。我也希望大家能有所收获。如果有收获,大家可以把“有收获”三个字打到弹幕上。
今天的视频就到这里。下期视频我们就又开始新的章节了。一定要关注、点赞、收藏,评论。您的支持是我这样的小博主持续更新下去的最大动力。期待下期视频再见。