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 扩散风险。
  • 模块化结构更符合大项目管理方式。

相关推荐
RaLi和夕17 小时前
单片机学习笔记.C51存储器类型含义及用法
笔记·单片机·学习
ShiMetaPi17 小时前
操作【GM3568JHF】FPGA+ARM异构开发板 使用指南:蓝牙
arm开发·嵌入式硬件·fpga开发·rk3568
kida_yuan17 小时前
【从零开始】12. 一切回归原点
python·架构·nlp
武文斌7717 小时前
ARM工作模式、汇编学习
汇编·嵌入式硬件·学习·arm
月阳羊17 小时前
【硬件-笔试面试题-76】硬件/电子工程师,笔试面试题(知识点:H桥驱动电路的设计要点)
java·单片机·嵌入式硬件·面试·职场和发展
正在起飞的蜗牛18 小时前
【C语言】函数指针的使用分析:回调、代码逻辑优化、代码架构分层
c语言·架构
wdfk_prog19 小时前
Python脚本深度解析:实现基于YMODEM的单片机固件自动化升级
python·单片机·自动化
纳祥科技19 小时前
分享:一种为蓝牙、WIFI、U段音频发射设备提供ARC回传数字音频桥接功能的方案
网络·单片机·音视频
云和数据.ChenGuang19 小时前
微服务技术栈
微服务·云原生·架构
知识分享小能手20 小时前
React学习教程,从入门到精通, React 新创建组件语法知识点及案例代码(11)
前端·javascript·学习·react.js·架构·前端框架·react