欢迎光临
我们一直在努力

HAL库分层架构开发模式简介

HAL库分层架构开发模式简介

引言

在HAL库开发有诸多优势:抽象程度高、项目配置过程简单等,但是代价是生成的项目体积较大且整体的文件内容较为冗余,且代码必须按照注释的提示去编写,否则当项目通过CubeMX软件重新生成后部分代码可能就会丢失,这使得实际得开发过程并不像我们想象得那般顺畅,因此我们可以尝试采用分层架构的方式让整体的程序架构更加清晰,同时也能够在更加简洁且不受束缚的环境下进行开发

分层模式介绍

这种目录结构的本质上是将整个工程文件划分为了三大层级,每一层级各司其职,彼此之间互补干扰

  • 硬件驱动层(HardWare文件夹)
    • 作用:这里存放的不是单纯的MCU内部外设,而是基于MCU外设封装出来的具体功能模块或外部芯片驱动
    • 例子:假设我们现在外接了一个超声波模块,那么我们就可以在HardWare目录下创建一个HC_SR04文件夹,在这个文件夹中我们会创建对应的.c和.h文件,在源文件中我们会实现对应的模块驱动和模块功能函数,最后通过头文件将这些函数提供给其它文件调用
  • 板级支持(App/Bsp文件夹)
    • 作用:BSP(Board Support Package)是这个架构的灵魂,当前文件夹中的文件就像是一个大管家,我们会在当前文件中对所有的外设进行统一的初始化、使能、调用和协调,最后在main函数中调用这些函数以减少主文件中的代码体积
    • 具体实现:文件中会实现两个核心函数:bsp_init()(此函数负责统一初始化和使能所有模块),bsp_Loop()(负责执行业务逻辑的主循环,当前函数会在main函数中的while循环中被调用)
  • 顶层入口(main.c)
    • 作用:仅仅作为程序的启动点,在main.c中我们会去调用bsp.c中实现的函数
  • 作用

    分层架构这样处理程序是为了能够让main.c中的内容尽可能地简洁,本身main.c中的内容就比较冗余,如果我们再将相应地模块控制函数等都写在同一文件中那么整个文件中的代码就会变得异常臃肿,且每次通过CubeMX更改项目配置都可能会造成代码丢失从而引发报错。采用了这种新结构后main.c的内容就会变得异常清爽,在使用时我们只需要在main.c中引用相对应的头文件(bsp.h),随后再调用相关函数即可

    // main.c 极其干净的结构
    int main(void)
    {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    // … CubeMX 生成的各种底层初始化 …

    /* USER CODE BEGIN 2 */
    bsp_Init(); // 接管所有外部硬件初始化
    /* USER CODE END 2 */

    while (1)
    {
    /* USER CODE BEGIN 3 */
    bsp_Loop(); // 主业务循环:单片机的外设控制操作都在这一个函数里
    /* USER CODE END 3 */
    }
    }

    优势

    这种架构的主要优势如下:

    • 可移植性增强:假设我们现在用STM32F1系列的开发板做了一个超声波避障小车,过两天我们想要将其移植到H7系列的开发板上,此时我们只需要使用CubeMX软件重新配置一下底层引脚后即可,随后我们将HardWare和App文件将直接拷贝到新的项目路径下即可
    • 协作能力增强:假设现在有多个人需要协同开发一个较为复杂的项目,那么他们就可以进行明确的分工,A负责串口通信、B负责屏幕显示、C负责组织逻辑,每个人都只需要编写自己对应部分的.c和.h文件即可,这样可以极大程度提高协同开发时的效率
    • 兼容性强:如果后续项目的复杂程度提升,我们需要使用FreeRTOS,那么此时我们就不需要修改HardWare内部的外设驱动内容,直接在App文件夹下新建多个任务来替换掉原来的单线程即可

    编码实操

    项目基本配置

    刚好上期讲完了基本定时器的相关内容,这次就尝试使用基本定时器配合超声波传感器来实现非阻塞式的测距功能,首先我们先在CubeMX中进行项目配置,首先选择自己对应的芯片型号,这里我使用的是STM32F103ZET6,我们首先配置相对应的引脚,在当前开发板中我们使用的是PF11作为超声波传感器的触发引脚和PF12作为超声波传感器的接收引脚

    在这里插入图片描述

    超声波引脚配置完成后接下来就要配置对应的基本定时器TIM6

    在这里插入图片描述

    在当前项目中配置预分频器的值为71也就是设置计数器每1微秒自增一次,技术模式只有向上计数一种,自动重装载值只要大于60000即可,因此我们直接将自动重装载值设置为65535(自动重装载值得上限),下面的auto-reload preload是选择是否开启预加载模式,由于此次项目中并没有涉及到修改定时器底层配置的操作,只是用来简单计数,因此这里开不开影响不大。最下面的Trigger Event Selection,这个选项的作用是配置基本定时器的触发输出信号,本次项目中也并没有涉及到相关操作,因此我们也不需要进行相关配置

    随后选择一个串口进行使能,参数根据实际情况进行调节,没有特殊情况就保持默认即可
    在这里插入图片描述

    时钟源配置为72Mhz

    在这里插入图片描述

    后面的项目配置大家根据自己的实际情况进行选择,这里仅作参考

    在这里插入图片描述
    在这里插入图片描述

    至此基本的HAL库项目配置就完成了,接下来我们尝试使用Keil进行进一步的配置

    完整配置

    接下来我们使用keil打开刚才生成的项目之后先进行编译,确定没有报错后在左侧的侧边栏中双击打开main.c文件,随后在代码编辑区右击main.c文件并选择在文件管理器中打开

    在这里插入图片描述

    接下来我们需要返回到当前系统的主目录下并创建对应的文件夹(App文件夹和HardWare文件夹)

    在这里插入图片描述

    接下来我们进入App文件夹中创建Bsp文件夹,并在该文件夹下创建对应的bsp.c和bsp.h文件
    在这里插入图片描述

    随后我们如法炮制,在HardWare文件夹下依次创建对应的外设驱动文件夹:Delay(微秒级延时函数实现)、Tim(定时器驱动)、USART(串口驱动)、Utral_sensor(超声波模块驱动)
    在这里插入图片描述

    当我们完整的创建了对应的文件夹和其中的文件之后接下来我们就要将它们添加到我们的项目中

    再次打开keil软件,随后单击魔法棒旁边的品字形选项,在弹出的界面中点击顶部的虚线框选项,随后按照文件夹的路径进行命名,命名完成之后选中你刚才创建的项目,点击右侧的Add Files选项,随后在弹出的新窗口中返回上级目录并找到对应的文件夹,选中对应的文件后直接双击即可添加对应文件,注意这里只需要添加源文件

    在这里插入图片描述

    依次添加完所有的文件之后接下来就要为项目添加对应的头文件搜索路径,点击顶部选项框中的魔法棒选项,随后在弹出的窗口中选择C/C++选项卡并点击Include Path选项后面的三个点,随后在弹出的界面中点击顶部的虚线框选项,并添加对应的头文件搜索路径,如下图所示
    在这里插入图片描述

    至此项目的配置就完成了,接下来就是如何进行代码编写的操作了,我们可以在对应的文件夹下的对应文件中编写相应的硬件驱动代码,如果你想了解具体的代码应该如何编写,那就可以关注下一篇文章中的内容,下一篇文章中我会详细介绍代码的编写流程,以及底层的硬件测距和连接原理

    赞(0)
    未经允许不得转载:171主机测评 » HAL库分层架构开发模式简介
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址