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

如何从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 << 20操作,这就和我们前面寄存器操作是一致的。
另外还有一个控制输出高低电平的函数,如下:

这里更加清楚,直接调用寄存器操作。这里直接操作GPIOx_BSRR寄存器,那么使用GPIOx_ODR寄存器也是可以。
总结一下,只要你用几次go to definition,你就会发现HAL库函数的实际就是操作寄存器,标准库也是一样。
HAL库,就是将硬件抽象化,相对的,对寄存器相关操作掌握能力就要求不高。在开发效率上,HAL库优势更明显,但是执行效率并不可观。一位技术大咖就认为:初始化用HAL库,方便快捷;其他地方可以使用寄存器操作,简单直接。所以说,想要技术变得贼溜,HAL库、寄存器一起搞起。

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

  1. HAL 库中 GPIO 工作模式配置(H7)

    1.配置流程 (1)时钟使能 (2)结构体赋值 (3)写入寄存器 2.配置说明 2.1使能 IO 口时钟 调用函数为: __HAL_RCC_GPIOX_CLK_ENABLE //使能GPIO时钟(其中 ...

  2. STM32标准库与HAL库中的Mode和Pull设置

    目录 概述 HAL库 标准库 再看HAL库 概述 最近做SDK的BSP驱动.之前使用STM32CubeMX进行开发,设计GPIO的初始化接口包括了mode.pull两个参数. 现在对接另一款国产芯片, ...

  3. 【嵌入式系统基础实验一】-----led流水灯及串口通信的HAL库方式和寄存器编程方式实现,输出波形检测

    文章目录 1.实验知识点简要解析 1.1串口通信协议 1.2 RS232.485电平与TTL电平的区别 1.3 USB/TTL转232"模块 2.LED流水灯的寄存器地址 和HAL库这两种方 ...

  4. 关于HAL库中系统嘀嗒时钟的简单探究

    在利用HAL库建立STM32工程时,系统嘀嗒时钟的初始化是在函数HAL_Init()中实现的: HAL_StatusTypeDef HAL_Init(void) {/* Configure Flash ...

  5. stm32 hal库 rtc 备份 寄存器 备份sram 调试笔记

    rtc 是可以单独供电的,通常设计rtc是带有一个纽扣电池用来给rtc供电.本次是调试rtc 的备份寄存器和备份sram,这两个都是可以在rtc不断电情况下一直保存数据. 步骤 配置rtc参数,用cu ...

  6. HAL库中的MSP文件,及HAL_Init和HAL_DeInit

    \quad\;\;\,MSP(MCU support package),它的作用是进行 MCU 级别的硬件初始化设置,并且它们通常会被上一层的初始化函数所调用,这样做的目的是为了把 MCU 相关的硬件 ...

  7. Proteus无法在您的库中找到系统文件PRODEFS.INT,LIBRARY文件夹路径错误。

    因为打不开之前低版本的proteus工程文件,最近卸载重新安装了一个新版本的proteus8.10,安装时由于系统仍保留上一版本在C盘里的安装路径,这次安到D盘了,出现了一些错误,在此总结一下解决方法 ...

  8. hal库中的UART使用

    1.初始化串口 UART_initStruct.Instance =USART1; UART_initStruct.Init.BaudRate = 9600; UART_initStruct.Init ...

  9. 当Proteus 8 Professional打开出现:已使用符号sMKRORIGIN但未在库中找到.

    这种情况一般是因为用户没有对安装目录里的LIBRARY文件夹写入的权限,解决方法如下: 打开软件安装目录,一般是C:\Program Files (x86)\Labcenter Electronics ...

最新文章

  1. java中产生指定范围内的随机数
  2. caffe2安装篇(三)通过docker安装
  3. ufldl学习笔记与编程作业:Multi-Layer Neural Network(多层神经网络+识别手写体编程)...
  4. python zip用法_Python zip()用法及代码示例
  5. mysql用户表示例_MySQL添加用户、删除用户与授权与关联实例
  6. DBA_Oracle性能优化的基本方法概述(方法论)
  7. 【转】Nodejs链接Mysql批量添加 insert into
  8. Spring源码分析
  9. Qt之获取屏幕分辨率
  10. 键盘各个键所对应的键值
  11. 某音热门---图片转字符SpringBoot版
  12. IP、MAC地址,交换机路由器,ARP、NAT协议串讲
  13. Fluent最全complied错误原因分析:Error: The UDF library you are trying to load (libudf) is not compiled for
  14. C语言数据结构【手抄版】第五章 树和二叉树【尾篇】二叉树C实现
  15. 微信小程序电商实战-入门篇
  16. php 采集 京东 图片,京东商品图片采集详细教程
  17. 百度网盘wine和linux区别,ubuntu16.04安装deepwine并安装QQ微信百度网盘等常用windows软件...
  18. 如何将bug杀死在摇篮里?
  19. 高效轻量级集成区块链(ELIB)用于保护物联网安全和隐私
  20. “厚德载物”是哪几德,做事先学做人

热门文章

  1. 在java中方法的三种调用方式
  2. android 百度地图 驾车路径的距离获取
  3. 安科瑞AFK系列低压复合开关
  4. 我的职业生涯规划:汗水浇灌梦想,在青春里成长
  5. java 代码安全扫描_安全测试-sonarscanner扫描代码
  6. Thinkphp 生成二维码(PHP)
  7. 中午12点之前完成工作
  8. IT创业失败案例解析 - 第三篇
  9. LIRE(Lucene Image Retrieval)相似图像索引和搜索机制
  10. Golang的Fork/Join实现