当前位置: 首页 > news >正文

单片机开发---分层架构设计

文章目录

  • 一、架构总览
      • 单片机程序分层架构总览
      • 详细分层说明
        • 1. 硬件抽象层 (Hardware Abstraction Layer - HAL)
        • 2. 驱动层 (Driver Layer)
        • 3. 业务逻辑层 (Business Logic Layer - BLL) / 中间件层 (Middleware Layer)
        • 4. 应用层 (Application Layer)
      • 总结与优势
  • 二、更详细一点的层
      • 1. **硬件抽象层(Hardware Abstraction Layer, HAL)**
      • 2. **驱动层(Driver Layer)**
      • 3. **中间层(Middleware Layer)**
      • 4. **接口层(Interface Layer)**
      • 5. **板级支持包(Board Support Package, BSP)**
      • 分层设计的优势

一、架构总览

一个结构良好的单片机程序通常会被划分为不同的层次,每一层都职责明确,从而提高代码的可读性、可维护性、可移植性和可测试性。

典型的单片机程序可以划分为以下四个核心层次,从最接近硬件的到最接近用户的逻辑。

单片机程序分层架构总览

下图清晰地展示了常见的四层架构及其依赖关系:

单片机程序分层架构
应用层
App Layer
业务逻辑层
BLL Layer
驱动层
Driver Layer
硬件抽象层
HAL Layer
单片机
MCU & 外设

详细分层说明

下面我们来详细解释每一层的职责、使用方法和示例。

1. 硬件抽象层 (Hardware Abstraction Layer - HAL)

职责:这是最底层,直接与单片机寄存器和外设打交道。它的核心目标是将硬件操作封装成统一的函数接口,从而屏蔽不同型号单片机之间的寄存器操作差异。

使用

  • 对下:直接操作单片机的特定外设寄存器(如 USART1->DR, GPIOA->ODR)。
  • 对上:为驱动层提供标准化的、与硬件无关的API(如 void HAL_UART_WriteByte(uint8_t byte))。
  • 当更换单片机型号时,理论上只需要重写或替换这一层代码,上层代码几乎无需改动。

示例代码

// hal_uart.h
#ifndef __HAL_UART_H
#define __HAL_UART_Hvoid HAL_UART_Init(uint32_t baudrate);
void HAL_UART_WriteByte(uint8_t byte);
uint8_t HAL_UART_ReadByte(void);#endif// hal_uart.c (针对特定MCU,如STM32)
#include "stm32f1xx.h"
#include "hal_uart.h"void HAL_UART_Init(uint32_t baudrate) {// ... 复杂的寄存器配置,如使能时钟、设置波特率、数据位等USART1->BRR = ...; // 根据baudrate计算USART1->CR1 |= USART_CR1_UE | USART_CR1_TE | USART_CR1_RE; // 使能USART、发送、接收
}void HAL_UART_WriteByte(uint8_t byte) {while (!(USART1->SR & USART_SR_TXE)); // 等待发送寄存器空USART1->DR = byte; // 写入数据寄存器
}
2. 驱动层 (Driver Layer)

职责:在HAL的基础上,驱动具体的硬件模块或芯片。它不再关心单片机寄存器,而是关心如何操作一个完整的设备(如温湿度传感器、LCD屏幕、电机驱动芯片)。这一层会实现该设备特定的通信协议和控制逻辑。

使用

  • 对下:调用HAL提供的函数来控制GPIO、SPI、I2C、UART等。
  • 对上:为业务逻辑层提供面向功能的API(如 DHT11_ReadTempHumidity)。

示例代码

// dht11_driver.h
#ifndef __DHT11_DRIVER_H
#define __DHT11_DRIVER_Htypedef struct {float temperature;float humidity;
} DHT11_Data_t;int DHT11_Init(void);
int DHT11_ReadTempHumidity(DHT11_Data_t *data);#endif// dht11_driver.c
#include "hal_gpio.h" // 使用HAL的GPIO函数
#include "hal_delay.h" // 使用HAL的延时函数
#include "dht11_driver.h"// DHT11的通信时序(例如,拉低总线18ms启动信号)
int DHT11_ReadTempHumidity(DHT11_Data_t *data) {// 1. 调用HAL_GPIO_WritePin将数据线拉低// 2. 调用HAL_Delay_ms(18)// 3. 调用HAL_GPIO_ReadPin读取数据线,解析40位数据// 4. 将解析出的二进制数据转换为temperature和humidity,填入data结构体// 5. 返回成功或失败状态
}
3. 业务逻辑层 (Business Logic Layer - BLL) / 中间件层 (Middleware Layer)

职责:这是系统的“大脑”,实现具体的产品功能和应用逻辑。它协调多个驱动,完成复杂的任务。FreeRTOS、文件系统、网络协议栈等也常被视作这一层的一部分。

使用

  • 对下:调用驱动层提供的各种设备API。
  • 对上:为应用层提供简洁的服务接口(如 CheckButtonAndControlMotor)。

示例代码

// control_logic.h
#ifndef __CONTROL_LOGIC_H
#define __CONTROL_LOGIC_Hvoid ControlLogic_Init(void);
void ControlLogic_Run(void); // 主循环中调用#endif// control_logic.c
#include "dht11_driver.h"
#include "fan_driver.h"
#include "button_driver.h"
#include "control_logic.h"void ControlLogic_Run(void) {DHT11_Data_t env_data;static uint32_t last_check_time = 0;// 每5秒检查一次温湿度if (HAL_GetTick() - last_check_time > 5000) {if (DHT11_ReadTempHumidity(&env_data) == SUCCESS) {// 业务逻辑:如果温度高于28度,则打开风扇if (env_data.temperature > 28.0f) {Fan_TurnOn();} else {Fan_TurnOff();}}last_check_time = HAL_GetTick();}// 处理按键事件if (Button_IsPressed()) {Fan_Toggle();}
}
4. 应用层 (Application Layer)

职责:这是整个程序的**“总指挥”,是程序的入口。它负责初始化所有下层模块、创建任务(如果使用RTOS)、启动调度器、并定义整个程序的执行框架**。这一层通常不实现复杂逻辑,只进行组织和调度。

使用

  • 对下:调用业务逻辑层的初始化函数和主循环函数。
  • 对外:它是 main.c 的核心内容。

示例代码

// main.c
#include "hal.h"     // 初始化硬件
#include "drivers.h" // 初始化所有驱动
#include "control_logic.h" // 业务逻辑
#include "FreeRTOS.h"
#include "task.h"// 如果没有RTOS
int main(void) {// 1. 初始化所有底层硬件和驱动HAL_Init();SystemClock_Config();DHT11_Init();Fan_Init();Button_Init();// 2. 初始化业务逻辑ControlLogic_Init();// 3. 主循环(轮询架构)for (;;) {ControlLogic_Run(); // 在循环中执行业务逻辑// 可能还有其他任务...}
}// 如果使用FreeRTOS
int main(void) {// 1. 硬件和基础驱动初始化HAL_Init();SystemClock_Config();// 2. 创建业务逻辑任务xTaskCreate(ControlLogic_Task, "ControlLogic", 128, NULL, 2, NULL);// 3. 启动RTOS调度器vTaskStartScheduler();// 4. 永远不会执行到这里for (;;);
}

总结与优势

层次核心思想依赖关系变化影响
应用层组织与调度依赖BLL产品功能改变时修改
业务逻辑层功能与逻辑依赖Driver业务规则改变时修改
驱动层设备与协议依赖HAL更换传感器/设备时修改
硬件抽象层抽象与统一依赖MCU硬件更换单片机型号时修改

采用分层架构的优势:

  • 高内聚,低耦合:每一层只关注自己的职责。
  • 易于移植:换MCU?主要改HAL。换传感器?主要改Driver。
  • 易于协作与测试:可以模拟下层接口,对上层的业务逻辑进行单元测试。
  • 代码复用:为同一款MCU写的HAL和Driver,可以用在多个不同的项目中。

在实际项目中,根据系统复杂度,层次可能会合并或进一步细分(例如,在HAL和Driver之间再增加一个板级支持包BSP),但核心的“分层”思想是相通的。

二、更详细一点的层

在单片机项目开发中,为了提高代码的可维护性、复用性和模块化程度,通常会采用分层设计思想。除了直接实现业务逻辑的应用层,常见的分层还包括以下几层(不同项目可能有细微差异,核心是按功能职责划分):

1. 硬件抽象层(Hardware Abstraction Layer, HAL)

  • 核心作用:屏蔽底层硬件细节,提供统一的软件接口,使上层代码无需直接操作寄存器或硬件引脚。
  • 具体功能
    • 对单片机的外设(如GPIO、UART、SPI、I2C、ADC、定时器等)进行封装,提供标准化函数(如 gpio_init()uart_send())。
    • 处理硬件相关的初始化参数(如引脚定义、波特率、时钟频率),与具体芯片型号绑定。
  • 举例
    无论用STM32还是51单片机,上层调用 uart_send_data(buf, len) 即可发送数据,无需关心底层寄存器配置(如STM32的USART寄存器、51的SBUF寄存器)。

2. 驱动层(Driver Layer)

  • 核心作用:在HAL之上,针对具体外部硬件(如传感器、执行器、模块)编写专用驱动,实现硬件的控制逻辑。
  • 具体功能
    • 基于HAL提供的接口,实现特定硬件的初始化、数据读写、状态控制等(如OLED屏驱动、温湿度传感器DHT11驱动、电机驱动L298N)。
    • 处理硬件的时序要求、通信协议(如I2C协议的传感器驱动需实现起始/停止信号、数据收发逻辑)。
  • 与HAL的区别
    HAL针对单片机内部外设(芯片自带功能),驱动层针对外部硬件模块(芯片外部的元器件)。

3. 中间层(Middleware Layer)

  • 核心作用:提供通用功能或协议支持,连接驱动层与应用层,解决跨模块的共性问题。
  • 常见模块
    • 通信协议栈:如Modbus、MQTT、蓝牙协议(BLE)、WiFi协议的封装,使应用层无需处理复杂协议细节。
    • 数据处理:如数据校验(CRC、校验和)、加密解密(AES)、JSON/XML解析。
    • 任务调度:在多任务系统(如FreeRTOS)中,封装任务创建、信号量、队列等接口,简化应用层的任务管理。
    • 通用工具:如内存管理、日志打印、延时函数等。

4. 接口层(Interface Layer)

(部分项目会单独划分,或融入中间层/HAL)

  • 核心作用:定义各层之间的接口标准,明确函数的输入输出、返回值和功能职责,实现“接口与实现分离”。
  • 具体形式
    通常用头文件(.h)定义函数声明、结构体、枚举等,而.c文件实现具体逻辑。例如,sensor_interface.h 定义传感器的通用接口(sensor_read()),不同传感器的驱动(DHT11、SHT30)分别实现该接口。

5. 板级支持包(Board Support Package, BSP)

(多见于复杂项目,可理解为“硬件抽象层+驱动层”的结合)

  • 核心作用:针对特定电路板(而非单一芯片)提供硬件支持,包含板载资源的初始化和控制。
  • 具体内容
    例如,某块开发板上有LED、按键、OLED屏、温湿度传感器,BSP层会统一初始化这些硬件,并提供 bsp_led_on()bsp_key_scan() 等接口,应用层直接调用即可,无需关心硬件在板上的具体连接(如LED接哪个GPIO引脚)。

分层设计的优势

  • 模块化:每层职责清晰,修改某一层(如更换传感器驱动)不影响其他层。
  • 可移植性:更换单片机型号时,只需修改HAL层,上层代码可复用。
  • 协作效率:多人开发时,可按层分工(如一人写驱动,一人写应用逻辑)。

实际项目中,分层并非绝对严格,简单项目可能只分“应用层+驱动层”,复杂项目(如带操作系统的工业控制)则会细分更多层级。

http://www.dtcms.com/a/530022.html

相关文章:

  • 响应式网站建设福州网页版微信二维码扫描
  • 山东港基建设集团网站wordpress双主题缓存
  • 岳阳企业网站定制开发wordpress 4.8.2 漏洞
  • BELLE-A论文翻译
  • (三)Gradle 依赖版本控制
  • 汕头网站建设工作做一个电子商务网站建设策划书
  • 【Java 反射机制】
  • 2016年网站设计风格山西seo网站设计
  • 局域网建设网站视频教程网站制作都包括什么
  • 网站建设工作推进会上的讲话在电商网站上做推广的技巧
  • 公司做网络推广哪个网站好网络推广专员好做吗
  • 最优传输理论学习(1)+PINN文献阅读
  • 网站关键词几个好wordpress 徽标
  • 培训网站项目ppt怎么做东莞网站优化案例
  • 如何建团购网站网站建设推广襄樊
  • C++数据结构【顺序表和Vector】
  • mujoco 仿真导纳控制律
  • 做引流去那些网站好网站挖掘工具
  • 西安免费自助建站模板淄博seo排名
  • 在线商城的程序源代码
  • 网站图片大小大连事件最新消息
  • 网站 设计 语言注册资金1000万实际需要多少钱
  • 做网站的市场网站建设预算明细
  • 学生管理系统升级
  • 网站解析密码宁波led网站建设
  • 襄阳住房和城乡建设局网站秦皇岛市房价
  • 建站如何收费wordpress博客价格
  • 电商网站开发技术上海网站建设高端定制
  • 大规模TSP问题规划方案中的避坑事项
  • 什么是代理隧道?代理隧道用来做什么?