51 单片机分层架构的模块依赖关系图

51 单片机分层架构的模块依赖关系图,并配一份可直接套用的代码框架


一、51 单片机软件分层架构图

复制代码
┌───────────────────────────────┐
│         应用层(APP)           │
│  - 产品业务逻辑(状态机)       │
│  - 用户交互(按键、显示)       │
│  - 流程控制(加热、保温等)     │
└───────────────▲───────────────┘
                │  调用接口
┌───────────────┴───────────────┐
│       服务层(Service)         │
│  - 协议解析(Modbus、私有协议) │
│  - 数据处理(滤波、PID)        │
│  - 按键扫描、显示缓存管理       │
└───────────────▲───────────────┘
                │  调用接口
┌───────────────┴───────────────┐
│   硬件抽象层(HAL)             │
│  - GPIO 接口化                 │
│  - 串口收发接口化               │
│  - 定时器抽象接口               │
│  - 屏蔽不同 51 寄存器差异       │
└───────────────▲───────────────┘
                │  调用接口
┌───────────────┴───────────────┐
│   硬件驱动层(Driver)          │
│  - 直接操作寄存器               │
│  - 初始化、收发、配置           │
│  - 单片机特定寄存器访问         │
└───────────────────────────────┘

依赖规则

  • 上层只能调用下层,不允许跨层调用(例如 APP 不能直接用 Driver)。
  • 硬件变化只改 Driver 和 HAL,业务变化只改 Service 和 APP。

二、代码文件组织结构

复制代码
/project
│
├── app/
│   ├── app_main.c          // 主循环、状态机
│   └── app_main.h
│
├── service/
│   ├── service_key.c       // 按键扫描
│   ├── service_key.h
│   ├── service_display.c   // 显示管理
│   └── service_display.h
│
├── hal/
│   ├── hal_gpio.c          // GPIO 抽象
│   ├── hal_gpio.h
│   ├── hal_uart.c          // 串口抽象
│   └── hal_uart.h
│
├── driver/
│   ├── driver_gpio.c       // 直接操作 P0/P1/P2/P3
│   ├── driver_gpio.h
│   ├── driver_uart.c       // 串口寄存器
│   └── driver_uart.h
│
└── main.c                  // 系统初始化入口

三、示例代码框架

driver_uart.c(硬件驱动层)

c 复制代码
#include "driver_uart.h"
#include <REG51.H>

void UART0_Init(uint32_t baud) {
    SCON = 0x50;   // 串口模式1
    TMOD |= 0x20;  // 定时器1模式2
    TH1 = 256 - (11059200UL / 12 / 32 / baud);
    TL1 = TH1;
    TR1 = 1;
}

void UART0_SendByte(uint8_t dat) {
    SBUF = dat;
    while (!TI);
    TI = 0;
}

uint8_t UART0_RecvByte(void) {
    while (!RI);
    RI = 0;
    return SBUF;
}

hal_uart.c(硬件抽象层)

c 复制代码
#include "hal_uart.h"
#include "driver_uart.h"

void HAL_UART_Init(void) {
    UART0_Init(9600);
}

void HAL_UART_SendString(const char *str) {
    while (*str) {
        UART0_SendByte(*str++);
    }
}

service_key.c(服务层)

c 复制代码
#include "service_key.h"
#include "hal_gpio.h"

#define KEY1_PIN P1_0

uint8_t Key_Scan(void) {
    if (HAL_GPIO_ReadPin(KEY1_PIN) == 0) {
        // 简单消抖
        HAL_DelayMs(10);
        if (HAL_GPIO_ReadPin(KEY1_PIN) == 0) {
            return 1;
        }
    }
    return 0;
}

app_main.c(应用层)

c 复制代码
#include "service_key.h"
#include "hal_uart.h"

void APP_MainLoop(void) {
    if (Key_Scan()) {
        HAL_UART_SendString("Key Pressed\r\n");
    }
}

main.c(系统入口)

c 复制代码
#include "hal_uart.h"
#include "app_main.h"

void main(void) {
    HAL_UART_Init();
    while (1) {
        APP_MainLoop();
    }
}

四、这样分层的好处

  • 换 51 型号,只改 driver_*,不用改上层逻辑。
  • 协议、算法、业务逻辑可直接移植到别的 MCU。
  • 每层可独立调试,降低 bug 扩散风险。
  • 模块化结构更符合大项目管理方式。

相关推荐
山沐与山5 分钟前
【K8S】Kubernetes架构与原理详解
容器·架构·kubernetes
lpfasd1238 分钟前
一次 IDE Agent 死循环问题的架构复盘
ide·架构
Coder个人博客10 分钟前
Apollo 9.0.0 自动驾驶系统整体架构分析
人工智能·架构·自动驾驶
客家元器件16 分钟前
LPDDR5选型参数
嵌入式硬件
✎ ﹏梦醒͜ღ҉繁华落℘19 分钟前
实际项目开发单片机—Flash错误
单片机
一个平凡而乐于分享的小比特23 分钟前
单片机内部时钟 vs 外部时钟详解
单片机·嵌入式硬件·内部时钟·外部时钟
xyx-3v1 小时前
RK3506G移植APM飞控的可行性
单片机·学习
才鲸嵌入式1 小时前
香山CPU(国产开源)的 SoC SDK底层程序编写,以及其它开源SoC芯片介绍
c语言·单片机·嵌入式·arm·cpu·verilog·fpga
d111111111d1 小时前
编码器测速详情解释:PID闭环控制
笔记·stm32·单片机·嵌入式硬件·学习·算法
福大大架构师每日一题2 小时前
ollama v0.13.4 发布——全新模型与性能优化详解
stm32·嵌入式硬件·性能优化·ollama