本文仅包括代码架构文件树设计和功能需求分析,不包括具体的如芯片选型、各功能实现等。本文仅属于电力电子代码系列文章的一小章,后面会详细讲如芯片选择、底层配置、命名风格推荐、各种功能细节…
电力电子代码特点
- 代码简洁:项目代码量少,易于阅读和复用,逻辑清晰。例如,最近本人在做的项目总代码量(含测试不含库)为5685行,实际功能代码仅约3000行(可用
cloc
工具统计)。 - 团队小:通常只有1到2人参与开发。
- 资源有限:项目可用的计算资源和存储空间较少。
- 实时性要求高:系统需要严格按照设定的频率运行,确保及时响应。
- 多重保护机制:系统设计了多级保护措施,确保安全运行。
- 用户通讯实时性要求低:与用户的交互不需要高实时性,允许一定的延迟。
电力电子代码需要实现哪些功能?
- 底层:初始化、运行时变模态、启动与关闭等功能。Timer、PWM、ADC、DAC(DAC是必要的,尤其是在调控制环路时)、GPIO、CMP、CAN、UART…等。(这里的CAN等通讯主要指可以正常收发,收发的数据代表的逻辑设定由通讯部分完成)
- 调度:根据数控原理,对非变频电力电子变换器来说,开关频率是控制频率的整数倍,一般尽量为一倍,并令控制器带宽为控制频率的1/5~1/10。因此,关键控制代码必然运行某定时器的中断中。低实时性功能(主要指通讯)可以放在
main()
的主循环中,也可使用FreeRTOS
等操作系统进行管理,但本人更推荐放在main()
的主循环中,因为功能较少,没必要使用操作系统进行调度管理。总之,使用TimerX_ISR()
和while
进行功能逻辑调度。 - 控制:如PID、PR、MPPT、DQ变换、PLL…等各种控制算法和其组合使用。
- 状态机:主要分为两类,一类是状态机逻辑,一类是状态逻辑。状态机逻辑包括状态机的状态机初始化逻辑和状态之间的切换逻辑;状态逻辑包括空闲、运行、错误、调试、更新、配置等状态的初始化、进入、退出、执行函数。
- 保护:此处只是简要的说明一下,会在介绍保护的章节专门介绍保护逻辑。
电力电子系统的保护通常需要多级设计,以确保在不同时间尺度上应对各种故障。根据响应速度的不同,保护机制可以分为最快响应、次快响应和较慢响应三类。最快响应的保护通常通过硬件实现,如使用比较器(COMP)和数模转换器(DAC)进行比较,或通过外部电路结合PWM模块的FAULT功能,直接硬件关断PWM输出,实现微秒级的快速保护。随后触发中断,处理相关业务逻辑,如记录故障信息和切换状态。这种保护适用于过流、短路等需要极快响应的故障。
次快响应的保护在每个控制周期内通过ADC采集关键参数(如电压、电流),并与保护阈值进行比较。如果超出阈值,则触发保护动作。这种保护适用于欠压、过压等需要较快响应的故障。较慢响应的保护则在主循环中周期性检查系统状态(如温度、功率),如果检测到异常,则执行相应的保护动作。这种保护适用于过温、通信异常等允许稍慢响应的故障。
在实现保护机制时,最快响应的保护需要在系统初始化阶段配置相关硬件,如PWM FAULT功能和比较器。触发保护时,通过中断设置对应的fault_flag
,以便后续处理。最慢响应的保护则在主循环中检测到故障后,修改对应的fault_flag
,以便统一处理。保护逻辑可以分为保护总体逻辑和各保护逻辑两类。保护总体逻辑负责判断是否触发保护、处理触发的保护、记录保护历史和配置保护参数。各保护逻辑则定义具体的保护行为,包括保护类型和相关函数。
保护总体逻辑的功能包括判断是否触发保护、处理触发的保护、记录保护历史和配置保护参数。各保护逻辑的功能则包括保护类型设定和相关函数。保护类型设定可以包括立即停止驱动、停止后延时重启、停止后条件重启和其他自定义动作。相关函数包括check
函数、recover
函数和user defined action
函数,分别用于检测是否满足保护触发条件、定义重启或恢复逻辑以及实现用户自定义的保护动作。 - 通讯:与DMA配合,设计编码和对应功能。
- 测试:含单元测试、模块测试、整体测试,分别在电脑用gcc或板上完成各项测试。
电力电子代码的三层架构
传统嵌入式代码的四层架构
一般来说,电力电子代码和一般的嵌入式代码一样,往往分为三层, app
bsp
hal
三层,分别是应用层、中间层、硬件层。
嵌入式论坛有这样一段话:https://www.embeddedrelated.com/thread/17476/concepts-around-hal-bsp-os-composition
In summary:
- OS: can be used by any module, it may need HAL functions
- BSP: uses HAL and OS
- HAL: uses OS and vendor files
- Application : this is your business logic, and should not call HAL functions anymore, but rather use the BSP layer (and OS of course).
分层架构核心要点
- 层次划分:
- Application Layer:业务逻辑,调用BSP和OS。
- BSP Layer:硬件抽象,调用HAL和OS。
- HAL Layer:硬件驱动,调用OS和供应商库。
- OS Layer:系统服务,被所有层调用。
- 依赖关系:
- Application → BSP + OS
- BSP → HAL + OS
- HAL → OS + Vendor Libs
- OS → 无依赖
- 设计原则:
- Top-Bottom:基于应用需求设计API,避免过度实
- 解耦:分离业务逻辑与底层实现,提升可维护性和可移植性。
- 优点:
- 可维护性:层次清晰,修改底层不影响上层。
- 可移植性:更换硬件或OS只需修改底层。
- 简化开发:按需实现,避免冗余。
- 适用场景:
- 嵌入式系统,多硬件平台支持。
- 长期维护和扩展的项目。
示例:UART驱动
- HAL:实现
uart_send_bytes
,使用OS消息队列。- BSP:提供
debug_print
,调用HAL发送数据。- Application:调用
debug_print
,不直接操作硬件。
电力电子代码的三层架构(没有OS)
电力电子代码常写在如 STM32
和 C2000
相关MCU或DSP上,往往官方的 HAL
库或 device
库基本完成了大部分底层有关内容,且 CubeMx
和 sysconfig
完成了大部分 setup
等初始化代码。(这里必须指出的是,本人强烈推荐把 sysconfig
生成的代码单独复制并保存在其它位置,因为 sysconfig
不支持生成多对文件,且不利于自己加修改。这也是TI官方论坛建议的使用方式)
- App Layer:业务逻辑,调用BSP。
- BSP Layer:硬件抽象,调用HAL。
- HAL Layer:硬件驱动,调用供应商库。
src
│
├─ main.c
│
├─app
│ ├─ project_app.c
│ ├─ project_app.h
│ ├─ project_app_global.c
│ ├─ project_app_global.h
│ │
│ ├─control
│ │ │ project_control.c
│ │ │ project_control.h
│ │ │
│ │ └─pid
│ │ pid.c
│ │ pid.h
│ │
│ ├─fsm
│ │ │ fsm_core.c
│ │ │ fsm_core.h
│ │ │
│ │ └─stateSuite
│ │ fsm_state_config.c
│ │ fsm_state_debug.c
│ │ fsm_state_fault.c
│ │ fsm_state_idle.c
│ │ fsm_state_run.c
│ │ fsm_state_upgrade.c
│ │ fsm_transition.c
│ │ state_suite.c
│ │ state_suite.h
│ │ state_suite_api.h
│ │
│ └─safety
│ │ ReadMe.md
│ │ safety_core.c
│ │ safety_core.h
│ │
│ ├─configManager
│ │ safety_config_manager.c
│ │ safety_config_manager.h
│ │
│ ├─logManager
│ │ safety_log_manager.c
│ │ safety_log_manager.h
│ │
│ └─safetySuite
│ safety_suite.c
│ safety_suite.h
│ safety_suite_none.c
│ safety_suite_none.h
│
├─bsp
│ │ project_bsp.c
│ └─ project_bsp.h
│
└─hal
project_hal.c
project_hal.h
project_hal_adc.c
project_hal_asysctl.c
project_hal_board.h
project_hal_can.c
project_hal_dac.c
project_hal_dma.c
project_hal_epwm.c
project_hal_epwm.h
project_hal_gpio.c
project_hal_i2c.c
project_hal_interrupt.c
project_hal_sci.c
project_hal_sync.c
project_hal_timer.c
如上文件树所示,hal层包括所有底层内容,bsp层包括对hal的调用封装,app层包括定时器中断函数、全局变量、控制、状态机、保护逻辑,main.c包括程序入口main()。
由于电力电子领域的供应商(如ST、TI)已经对HAL层进行了高度封装,且关键外设(如PWM)的差异较大,BSP层实际上很难与HAL层完全分离。因此,通常会将硬件初始化、外设配置、硬件事件处理等函数放在 src/hal
中,而不直接使用供应商提供的库。这也导致在电力电子代码中,BSP层的原始定义(Board Support Package)常常被忽视,转而将其视为一个中间层。在这种架构下,BSP层通常包含大量应用代码,而App层则仅保留定时器中断等核心逻辑。这也是我个人习惯的实现方式。
在这种习惯下,文件树为:
src
│ ReadMe.md # 项目总说明文档
│ main.c # 程序入口,初始化系统并启动主循环
│
├─app # 应用层,存放业务逻辑代码
│ project_app.c # 应用层主逻辑实现
│ project_app.h # 应用层头文件,定义接口和数据结构
│
├─bsp # 中间层
│ │ project_bsp.c # BSP层核心实现
│ │ project_bsp.h # BSP层头文件
│ │ project_bsp_global.c # BSP层全局变量
│ │ project_bsp_global.h # BSP层全局变量
│ │
│ ├─control # 控制算法相关代码
│ │ │ project_control.c # 控制逻辑实现
│ │ │ project_control.h # 控制逻辑头文件
│ │ │
│ │ └─pid # PID控制算法实现
│ │ pid.c # PID算法核心实现
│ │ pid.h # PID算法头文件
│ │ ReadMe.md # PID算法说明文档
│ │
│ ├─fsm # 有限状态机(FSM)相关代码
│ │ │ fsm_core.c # 状态机核心逻辑实现
│ │ │ fsm_core.h # 状态机核心逻辑头文件
│ │ │ ReadMe.md # 状态机说明文档
│ │ │
│ │ └─stateSuite # 状态机具体状态实现
│ │ fsm_state_config.c # 配置状态实现
│ │ fsm_state_debug.c # 调试状态实现
│ │ fsm_state_fault.c # 故障状态实现
│ │ fsm_state_idle.c # 空闲状态实现
│ │ fsm_state_run.c # 运行状态实现
│ │ fsm_state_upgrade.c # 升级状态实现
│ │ fsm_transition.c # 状态转换逻辑实现
│ │ state_suite.c # 状态机套件核心实现
│ │ state_suite.h # 状态机套件头文件
│ │ state_suite_api.h # 状态机套件对外接口
│ │
│ └─safety # 安全相关代码
│ │ ReadMe.md # 安全模块说明文档
│ │ safety_core.c # 安全核心逻辑实现
│ │ safety_core.h # 安全核心逻辑头文件
│ │
│ ├─configManager # 安全配置管理
│ │ safety_config_manager.c # 安全配置管理实现
│ │ safety_config_manager.h # 安全配置管理头文件
│ │
│ ├─logManager # 安全日志管理
│ │ safety_log_manager.c # 安全日志管理实现
│ │ safety_log_manager.h # 安全日志管理头文件
│ │
│ └─safetySuite # 安全套件
│ safety_suite.c # 安全套件核心实现
│ safety_suite.h # 安全套件头文件
│ safety_suite_none.c # 空安全套件实现(占位)
│ safety_suite_none.h # 空安全套件头文件
│
└─hal # 硬件抽象层,与硬件直接交互的代码
project_hal.c # HAL层核心实现
project_hal.h # HAL层头文件
project_hal_adc.c # ADC外设驱动实现
project_hal_asysctl.c # 系统控制外设驱动实现
project_hal_board.h # 硬件板级配置头文件
project_hal_can.c # CAN外设驱动实现
project_hal_dac.c # DAC外设驱动实现
project_hal_dma.c # DMA外设驱动实现
project_hal_epwm.c # EPWM外设驱动实现
project_hal_epwm.h # EPWM外设驱动头文件
project_hal_gpio.c # GPIO外设驱动实现
project_hal_i2c.c # I2C外设驱动实现
project_hal_interrupt.c # 中断处理实现
project_hal_sci.c # SCI外设驱动实现
project_hal_sync.c # 同步外设驱动实现
project_hal_timer.c # 定时器外设驱动实现
ReadMe.md # HAL层说明文档
Eva2026年6月硕士毕业,正在找工作^^有兴趣招我的可以通过评论与我联系^^