您当前的位置: 首页 > 

正点原子

暂无认证

  • 1浏览

    0关注

    382博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

如何从HAL库中找到寄存器的蛛丝马迹

正点原子 发布时间:2021-10-22 16:06:10 ,浏览量:1

以下文章来源于:公_众_号开源电子网 读取更多技术文章,请扫码关注 请添加图片描述

如何从HAL库中找到寄存器的蛛丝马迹 对于初学者来说,有时候知其然而不知其所以然,换句话来讲,知道这个东西是这样子操作,但是不知道为啥这么做。虽然老话有讲,不管黑猫白猫,捉到老鼠就是好猫,但是某些时候我们还是得需要知道为啥这么干。 举个栗子,配置一个GPIO去控制一个LED灯。 寄存器版本的代码: 在这里插入图片描述

这里就涉及两个与GPIO相关的寄存器:GPIOx_CRL,GPIOx_ODR。通过注释我们也知道了这两个寄存器的功能。 为什么这么赋值呢?下面就先看一下这两个寄存器的详情。 首先是端口配置低寄存器(GPIOx_CRL),因为我们配置的GPIO口为PB5,所以是看端口配置低寄存器。假如是GPIO8~GPIO15,我们就需要查看GPIOx_CRH。 我们是用PB5来控制LED灯,所以说模式要设置为推挽输出模式,速度可以设置为50MHz。所以说我们对Bit[23:20]赋值0x3。 在这里插入图片描述

通过上面,已经把PB5设置好了,这里就相当于我们理解中的初始化成功。初始化成功后,那么就是对该GPIO口的控制了,让它输出高电平还是低电平,这里使用端口输出数据寄存器(GPIOx_ODR)去实现了。 对ODR5位置1或者清0就是控制GPIO输出高电平还是低电平了,具体根据原理图查看才知道,赋值0还是1能让LED亮。当然我们的LED灯设计是低电平点亮,高电平熄灭。初始化情况下,还是赋值1,让LED处于熄灭状态。 在这里插入图片描述

以上就是寄存器版本对GPIO口配置,我们可以很清晰的看到相对底层的操作。 我们再来看一下HAL库对GPIO的操作。 在这里插入图片描述

很明显,HAL库函数就是有封装了,标准库同样也是一样的。初始化一个外设,老掉牙的套路:定义一个外设结构体,并且对其成员进行赋值,然后调用HAL_XXX_Init函数完成。 GPIO初始化结构体哪里找呢?就在stm32f1xx_hal_gpio.h中已经定义好了,具体如下: 在这里插入图片描述

Pin就是引脚号,Mode就是模式设置,Pull就是上下拉设置(F1的话,输出模式不用设置),Speed就是速度设置。 我们是用PB5去控制灯,和寄存器版本一样的配置,模式是设置推挽输出,速度设置50MHz。 那么如何赋值?其实上面已经有图了,这里还是简单提一下吧。 gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; 怎么知道“GPIO_MODE_OUTPUT_PP”含义呢?如下图所示: 在这里插入图片描述 就是使用最为常用的操作“Go to Definition”去走到底查看这个宏代表的值,那么通过上图就可以知道“GPIO_MODE_OUTPUT_PP”为1。 同样的,查看“GPIO_SPEED_FREQ_HIGH”含义呢?如下图所示: 在这里插入图片描述

这个宏相对上一个宏再多跳转了一级,我们要以获得值为前提,所以说还没有见到我们熟悉的数字时,就需要一直“Go to Definition”,最终我们发现该宏是为3。 到这里还没有看到寄存器的操作,但是看到这个0x3的出现,我们现在已经有点底了。前面也说了对结构体成员赋值后,就可以调用初始化函数,这时候同样的Go to Definition。函数如下(经过处理): 在这里插入图片描述

解析过程如上图,经过漫长的兜兜转转,最终你会发现HAL库的实际依然是操作寄存器,对GPIOB_CRL进行0x3

关注
打赏
1665308814
查看更多评论
立即登录/注册

微信扫码登录

0.0404s