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

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(硬件驱动层)

#include "driver_uart.h"
#include <REG51.H>void UART0_Init(uint32_t baud) {SCON = 0x50;   // 串口模式1TMOD |= 0x20;  // 定时器1模式2TH1 = 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(硬件抽象层)

#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(服务层)

#include "service_key.h"
#include "hal_gpio.h"#define KEY1_PIN P1_0uint8_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(应用层)

#include "service_key.h"
#include "hal_uart.h"void APP_MainLoop(void) {if (Key_Scan()) {HAL_UART_SendString("Key Pressed\r\n");}
}

main.c(系统入口)

#include "hal_uart.h"
#include "app_main.h"void main(void) {HAL_UART_Init();while (1) {APP_MainLoop();}
}

四、这样分层的好处

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

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

相关文章:

  • 解决ROS编译顺序不对,需要内部依赖,因此要多次编译的问题
  • Python初学者笔记第二十二期 -- (JSON数据解析)
  • MySQL 数据库表操作与查询实战案例
  • 双十一美妆数据分析:洞察消费趋势与行业秘密
  • 机械臂的智能升维:当传统机械臂遇见Deepoc具身智能大模型从自动化工具到具身智能体的范式革命
  • Element用法---Loading 加载
  • C++的异常的使用和规范
  • 【盘古100Pro+开发板实验例程】FPGA学习 | 均值滤波 | 图像实验指导手册
  • 【代码随想录day 18】 力扣 501.二叉搜索树中的众数
  • 免费播客翻译与转录:用中文收听全球播客
  • Langchain入门:文本摘要
  • C++学习之数据结构:AVL树
  • java八股文-MySql面试题-参考回答
  • GPFS api
  • 在 C语言 中构建安全泛型容器:使用 maybe 实现安全除法
  • 【PCB设计经验】去耦电容如何布局?
  • 力扣top100(day01-04)
  • 企业级的即时通讯平台怎么保护敏感行业通讯安全?
  • 电竞 体育数据 API 应用场景全解析
  • Day50--图论--98. 所有可达路径(卡码网),797. 所有可能的路径
  • Quartz
  • Mybatis源码解读-SqlSession 会话源码和Executor SQL操作执行器源码
  • 谷歌云代理商:用 AI 启航,Gemini 重塑旅游酒店行业新体验
  • 【SpringBoot】07 容器功能 - SpringBoot底层注解的应用与实战 - @ConfigurationProperties配置绑定
  • 从0入门LangGraph,手搓高质量Agent
  • 【自动化运维神器Ansible】playbook文件内变量定义全流程解析
  • 谷歌ADK接入文件操作MCP
  • Linux中Https配置与私有CA部署指南
  • Java 工厂方法模式
  • C++单继承虚函数表探索