编程技术分享

分享编程知识,探讨技术创新

0%

简介:两个DCDC模块,分别为MPPT(用于太阳能最大功率点跟踪、简单的扰动观察法)和24/12的DCDC;控制使用stm32f4的最小系统板,项目简单,新手第一次接触电力电子,有许多问题希望各位大佬指正。

好的,作为一名高级嵌入式软件开发工程师,我非常乐意为您详细解析并构建这个太阳能MPPT和24V转12V双DCDC嵌入式系统的代码架构,并提供相应的C代码示例。考虑到您是电力电子新手,我会尽量以清晰易懂的方式进行讲解,并强调实践验证的技术和方法。
关注微信公众号,提前获取相关推文

项目概述与需求分析

首先,让我们明确项目的核心需求:

  1. 太阳能MPPT (最大功率点跟踪) DC-DC 模块:

    • 功能:自动调整DC-DC转换器的占空比,使得太阳能电池板始终工作在最大功率点,从而最大化能量采集效率。
    • 算法:采用“扰动观察法”(P&O),这是一种简单且广泛应用的MPPT算法。
    • 控制:通过STM32F4微控制器生成PWM信号来控制DC-DC转换器。
  2. 24V转12V DC-DC 模块:

    • 功能:将来自MPPT DC-DC模块(假设输出电压在24V左右)的电压稳定转换为12V,为负载供电。
    • 控制:可能采用更简单的电压反馈控制,例如PID控制或简单的开关控制,以保持12V输出稳定。
    • 控制:同样由STM32F4微控制器控制。
  3. STM32F4 微控制器:

    • 核心:作为整个系统的控制中心,负责MPPT算法的实现、PWM信号的生成、传感器数据采集、系统状态监控和可能的通信功能。
    • 资源:利用STM32F4的ADC、定时器、GPIO等外设。
  4. 系统目标:

    • 可靠性:系统必须稳定运行,能够长时间在户外环境下工作。
    • 高效性:最大化太阳能利用率,降低能量损耗。
    • 可扩展性:软件架构应易于扩展和维护,方便后续添加新功能或优化现有功能。

系统架构设计

为了实现可靠、高效、可扩展的系统,我们采用分层架构的设计思想。分层架构将系统分解为多个独立的层,每一层都有明确的职责,层与层之间通过清晰的接口进行通信。这有助于提高代码的可维护性、可重用性和可测试性。

系统软件架构图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
+---------------------+
| 应用层 (Application Layer) |
| - 系统监控与显示 |
| - 通信接口 (可选) |
+---------------------+
| 服务层 (Service Layer) |
| - MPPT 控制服务 |
| - 24V-12V DC-DC 控制服务 |
| - 传感器数据处理服务 |
| - PWM 生成服务 |
+---------------------+
| 硬件抽象层 (HAL - Hardware Abstraction Layer) |
| - ADC 驱动 |
| - 定时器/PWM 驱动 |
| - GPIO 驱动 |
| - 串口/I2C/SPI 驱动 (可选) |
+---------------------+
| 硬件层 (Hardware Layer) |
| - STM32F4 微控制器 |
| - MPPT DC-DC 硬件 |
| - 24V-12V DC-DC 硬件|
| - 传感器 |
+---------------------+

各层职责详细说明:

  1. 硬件层 (Hardware Layer):

    • 这是系统的物理基础,包括STM32F4微控制器、MPPT DC-DC转换器、24V-12V DC-DC转换器、电压/电流/温度传感器等硬件组件。
  2. 硬件抽象层 (HAL - Hardware Abstraction Layer):

    • HAL层是软件与硬件之间的桥梁。它提供了一组标准化的接口,用于访问和控制底层的硬件资源。
    • 目的:
      • 硬件隔离: 上层软件不需要直接了解底层的硬件细节,只需要调用HAL层提供的通用接口即可。这使得代码更具移植性,当更换硬件平台时,只需要修改HAL层代码,上层应用代码基本不需要改动。
      • 简化硬件操作: HAL层封装了复杂的硬件操作细节,向上层软件提供简单易用的API,例如 HAL_ADC_GetValue(), HAL_TIM_PWM_SetDutyCycle(), HAL_GPIO_SetOutputPin() 等。
    • 包含的驱动程序:
      • ADC 驱动: 初始化ADC外设,读取电压、电流、温度传感器的模拟信号。
      • 定时器/PWM 驱动: 初始化定时器外设,生成PWM信号用于控制DC-DC转换器的开关。
      • GPIO 驱动: 配置和控制GPIO引脚,例如控制使能信号、指示灯等。
      • 串口/I2C/SPI 驱动 (可选): 如果需要通信功能(例如通过串口进行调试或数据传输),则需要相应的驱动。
  3. 服务层 (Service Layer):

    • 服务层构建在HAL层之上,提供更高级别的功能服务,供应用层调用。
    • 目的:
      • 封装业务逻辑: 将系统的核心业务逻辑(例如 MPPT 算法、DC-DC 控制算法、传感器数据处理)封装在服务层中,使得应用层代码更简洁、更专注于用户界面和系统流程。
      • 提供模块化服务: 每个服务模块负责特定的功能,例如 MPPT 控制服务负责实现 MPPT 算法,传感器数据处理服务负责读取和处理传感器数据。
      • 提高代码可重用性: 服务层的功能模块可以在不同的应用场景中重用。
    • 包含的服务模块:
      • MPPT 控制服务:
        • 实现扰动观察法(P&O)MPPT算法。
        • 定期读取太阳能电池板的电压和电流数据。
        • 根据P&O算法调整PWM占空比。
        • 提供接口供应用层启动、停止和查询MPPT状态。
      • 24V-12V DC-DC 控制服务:
        • 实现24V转12V的电压稳定控制(例如PID控制或简单开关控制)。
        • 读取12V输出电压反馈。
        • 调整PWM占空比以维持12V输出稳定。
        • 提供接口供应用层启动、停止和查询DC-DC状态。
      • 传感器数据处理服务:
        • 读取ADC采集的原始传感器数据。
        • 对传感器数据进行滤波、校准和单位转换。
        • 提供接口供其他服务模块或应用层获取处理后的传感器数据。
      • PWM 生成服务:
        • 封装PWM信号的生成和控制逻辑。
        • 接受来自MPPT控制服务和24V-12V DC-DC控制服务的占空比参数。
        • 调用HAL层的定时器/PWM驱动,生成相应的PWM信号。
  4. 应用层 (Application Layer):

    • 应用层是系统的最高层,负责实现用户界面的交互、系统监控、数据显示、通信等高级功能。
    • 目的:
      • 实现用户交互: 如果系统有用户界面(例如LCD显示屏或上位机软件),应用层负责处理用户输入和显示系统状态。
      • 系统监控与管理: 监控系统运行状态,处理报警事件,记录系统日志。
      • 数据通信 (可选): 如果需要通过串口、网络等方式与外部设备通信,应用层负责实现通信协议和数据传输。
    • 包含的模块:
      • 系统监控与显示模块:
        • 定期从服务层获取系统状态数据(例如太阳能电压、电流、输出电压、温度等)。
        • 将系统状态数据在LCD显示屏上显示,或通过串口发送到上位机。
        • 监控系统异常状态(例如过压、过流、过温),并进行报警处理。
      • 通信接口模块 (可选):
        • 实现串口、I2C、SPI、CAN等通信协议。
        • 与外部设备进行数据交换和控制。

代码实现 (C语言)

接下来,我将提供关键模块的C代码示例。为了代码的完整性和可运行性,我将使用STM32 HAL库,并假设您已经配置好了STM32F4的开发环境。

1. HAL层驱动代码 (示例 - ADC和PWM):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// --- adc.c ---
#include "adc.h"
#include "stm32f4xx_hal.h"

ADC_HandleTypeDef hadc1; // ADC句柄

// 初始化ADC
void HAL_ADC_Init(void) {
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK2_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE; // 连续转换模式
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

if (HAL_ADC_Init(&hadc1) != HAL_OK) {
Error_Handler(); // 错误处理函数
}
}

// 配置ADC通道
void HAL_ADC_ConfigChannel(uint32_t channel) {
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = channel;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
Error_Handler();
}
}

// 启动ADC转换
void HAL_ADC_Start(void) {
HAL_ADC_Start(&hadc1);
}

// 获取ADC值
uint16_t HAL_ADC_GetValue(void) {
HAL_ADC_PollForConversion(&hadc1, 10); // 等待转换完成 (超时10ms)
return HAL_ADC_GetValue(&hadc1);
}

// --- pwm.c ---
#include "pwm.h"
#include "stm32f4xx_hal.h"

TIM_HandleTypeDef htim2; // 定时器句柄

// 初始化PWM
void HAL_PWM_Init(void) {
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};

htim2.Instance = TIM2;
htim2.Init.Prescaler = 100 - 1; // 预分频器,根据实际需求调整
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 1000 - 1; // PWM周期,根据实际需求调整
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK) {
Error_Handler();
}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) {
Error_Handler();
}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) {
Error_Handler();
}

sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0; // 初始占空比为0
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {
Error_Handler();
}
}

// 设置PWM占空比 (0-1000)
void HAL_PWM_SetDutyCycle(uint32_t dutyCycle) {
TIM_OC_InitTypeDef sConfigOC = {0};
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = dutyCycle;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {
Error_Handler();
}
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); // 重新启动PWM输出
}

// 启动PWM输出
void HAL_PWM_Start(void) {
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
}

// 停止PWM输出
void HAL_PWM_Stop(void) {
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
}

2. 服务层代码 (示例 - MPPT控制服务):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// --- mppt_service.c ---
#include "mppt_service.h"
#include "adc.h"
#include "pwm.h"
#include "delay.h" // 简单的延时函数 (需要自行实现)

#define MPPT_SAMPLE_INTERVAL_MS 100 // MPPT采样间隔 (ms)
#define MPPT_STEP_SIZE 5 // 占空比调整步长 (例如 PWM周期 1000, 步长 5 代表 0.5% 变化)

typedef enum {
MPPT_STATE_IDLE,
MPPT_STATE_TRACKING
} MPPT_State_t;

static MPPT_State_t mpptState = MPPT_STATE_IDLE;
static uint16_t lastPower = 0;
static uint16_t currentDutyCycle = 500; // 初始占空比 (例如 50%)

// 初始化MPPT服务
void MPPT_Service_Init(void) {
HAL_ADC_Init();
HAL_PWM_Init();
MPPT_Service_Stop(); // 初始停止MPPT
}

// 启动MPPT服务
void MPPT_Service_Start(void) {
mpptState = MPPT_STATE_TRACKING;
HAL_PWM_Start();
}

// 停止MPPT服务
void MPPT_Service_Stop(void) {
mpptState = MPPT_STATE_IDLE;
HAL_PWM_Stop();
HAL_PWM_SetDutyCycle(0); // 停止PWM输出
}

// MPPT 任务 (周期性调用)
void MPPT_Service_Task(void) {
if (mpptState != MPPT_STATE_TRACKING) {
return; // MPPT未启动,直接返回
}

static uint32_t lastSampleTime = 0;
if (HAL_GetTick() - lastSampleTime >= MPPT_SAMPLE_INTERVAL_MS) {
lastSampleTime = HAL_GetTick();

// 1. 读取太阳能电池板电压和电流 (需要根据实际硬件连接配置ADC通道)
HAL_ADC_ConfigChannel(ADC_CHANNEL_0); // 假设电压传感器连接到 ADC通道 0
HAL_ADC_Start();
uint16_t solarVoltageAdc = HAL_ADC_GetValue();
HAL_ADC_ConfigChannel(ADC_CHANNEL_1); // 假设电流传感器连接到 ADC通道 1
HAL_ADC_Start();
uint16_t solarCurrentAdc = HAL_ADC_GetValue();

// 2. 将ADC值转换为实际电压和电流值 (需要根据传感器参数和分压电阻等进行校准)
float solarVoltage = (float)solarVoltageAdc * 3.3f / 4096.0f * 10.0f; // 假设10倍分压
float solarCurrent = (float)solarCurrentAdc * 3.3f / 4096.0f / 0.1f; // 假设 0.1 Ohm 电流采样电阻

// 3. 计算当前功率
uint16_t currentPower = (uint16_t)(solarVoltage * solarCurrent * 1000); // 功率单位 mW

// 4. 扰动观察法 (P&O) 算法
if (currentPower > lastPower) {
// 功率增加,继续朝相同方向扰动
if (currentDutyCycle + MPPT_STEP_SIZE <= 1000) { // 占空比上限判断
currentDutyCycle += MPPT_STEP_SIZE;
}
} else {
// 功率减小,反方向扰动
if (currentDutyCycle - MPPT_STEP_SIZE >= 0) { // 占空比下限判断
currentDutyCycle -= MPPT_STEP_SIZE;
}
}

// 5. 更新PWM占空比
HAL_PWM_SetDutyCycle(currentDutyCycle);

// 6. 更新上一次功率值
lastPower = currentPower;

// --- 调试输出 (可选) ---
// printf("V: %.2fV, I: %.2fA, P: %dmW, Duty: %d\r\n", solarVoltage, solarCurrent, currentPower, currentDutyCycle);
}
}

// 获取MPPT状态
MPPT_State_t MPPT_Service_GetState(void) {
return mpptState;
}

3. 应用层代码 (示例 - main.c):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// --- main.c ---
#include "stm32f4xx_hal.h"
#include "mppt_service.h"
#include "dcdc_service.h" // 假设有 24V-12V DC-DC 控制服务
#include "delay.h" // 简单的延时函数

void SystemClock_Config(void); // 系统时钟配置函数 (需要根据实际硬件配置)
void Error_Handler(void); // 错误处理函数 (需要自行实现)

int main(void) {
HAL_Init(); // HAL库初始化
SystemClock_Config(); // 系统时钟配置

// 初始化外设 (GPIO, ADC, TIM, 串口等) (HAL_GPIO_Init(), HAL_ADC_MspInit(), HAL_TIM_Base_MspInit(), HAL_UART_MspInit() 等)
// ... (需要根据实际硬件连接进行初始化配置) ...

// 初始化服务层模块
MPPT_Service_Init();
DCDC_Service_Init(); // 假设有 24V-12V DC-DC 控制服务

// 启动服务
MPPT_Service_Start();
DCDC_Service_Start(); // 假设有 24V-12V DC-DC 控制服务

while (1) {
// 周期性执行服务层任务
MPPT_Service_Task();
DCDC_Service_Task(); // 假设有 24V-12V DC-DC 控制服务

// 其他应用层任务 (例如系统监控、数据显示、通信等)
// ...

HAL_Delay(1); // 适当延时,降低CPU占用率
}
}

// 系统时钟配置 (示例 - 84MHz HCLK)
void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGESCALING_SCALE2);

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
Error_Handler();
}
}

// 错误处理函数 (示例)
void Error_Handler(void) {
while(1) {
// 错误指示灯闪烁或其他错误处理逻辑
}
}

// 简单的延时函数 (需要自行实现,可以使用 HAL_Delay 或 SysTick 定时器)
void delay_ms(uint32_t ms) {
HAL_Delay(ms); // 使用 HAL库提供的延时函数
}

4. 24V-12V DC-DC 控制服务 (示例 - 简单电压反馈控制):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// --- dcdc_service.c ---
#include "dcdc_service.h"
#include "adc.h"
#include "pwm.h"
#include "delay.h"

#define DCDC_SAMPLE_INTERVAL_MS 50 // DC-DC控制采样间隔 (ms)
#define DCDC_TARGET_VOLTAGE 120 // 目标输出电压 (单位: 0.1V, 例如 120 代表 12.0V)
#define DCDC_STEP_SIZE 5 // 占空比调整步长

typedef enum {
DCDC_STATE_IDLE,
DCDC_STATE_REGULATING
} DCDC_State_t;

static DCDC_State_t dcdcState = DCDC_STATE_IDLE;
static uint16_t currentDutyCycle_DCDC = 500; // 初始占空比

// 初始化DC-DC服务
void DCDC_Service_Init(void) {
HAL_ADC_Init();
HAL_PWM_Init(); // 可以复用 PWM 模块,也可以使用不同的定时器通道
DCDC_Service_Stop(); // 初始停止DC-DC
}

// 启动DC-DC服务
void DCDC_Service_Start(void) {
dcdcState = DCDC_STATE_REGULATING;
HAL_PWM_Start(); // 启动 PWM 输出
}

// 停止DC-DC服务
void DCDC_Service_Stop(void) {
dcdcState = DCDC_STATE_IDLE;
HAL_PWM_Stop();
HAL_PWM_SetDutyCycle(0);
}

// DC-DC 任务 (周期性调用)
void DCDC_Service_Task(void) {
if (dcdcState != DCDC_STATE_REGULATING) {
return;
}

static uint32_t lastSampleTime = 0;
if (HAL_GetTick() - lastSampleTime >= DCDC_SAMPLE_INTERVAL_MS) {
lastSampleTime = HAL_GetTick();

// 1. 读取 12V 输出电压 (需要配置 ADC 通道)
HAL_ADC_ConfigChannel(ADC_CHANNEL_2); // 假设 12V 输出电压传感器连接到 ADC通道 2
HAL_ADC_Start();
uint16_t outputVoltageAdc = HAL_ADC_GetValue();

// 2. 将ADC值转换为实际电压值
float outputVoltage = (float)outputVoltageAdc * 3.3f / 4096.0f * 10.0f; // 假设10倍分压

// 3. 简单电压反馈控制 (开关控制)
uint16_t targetVoltage_adc = (uint16_t)(DCDC_TARGET_VOLTAGE * 4096.0f * 0.1f / 3.3f / 10.0f); // 将目标电压转换为 ADC 值范围
if (outputVoltageAdc < targetVoltage_adc - 50) { // 假设阈值 50 ADC 单位
// 输出电压偏低,增加占空比
if (currentDutyCycle_DCDC + DCDC_STEP_SIZE <= 1000) {
currentDutyCycle_DCDC += DCDC_STEP_SIZE;
}
} else if (outputVoltageAdc > targetVoltage_adc + 50) {
// 输出电压偏高,减小占空比
if (currentDutyCycle_DCDC - DCDC_STEP_SIZE >= 0) {
currentDutyCycle_DCDC -= DCDC_STEP_SIZE;
}
}

// 4. 更新 PWM 占空比
HAL_PWM_SetDutyCycle(currentDutyCycle_DCDC);

// --- 调试输出 (可选) ---
// printf("12V Out: %.2fV, Duty: %d\r\n", outputVoltage, currentDutyCycle_DCDC);
}
}

// 获取DC-DC状态
DCDC_State_t DCDC_Service_GetState(void) {
return dcdcState;
}

代码说明:

  • HAL层驱动: adc.cpwm.c 提供了ADC和PWM的HAL层驱动,封装了STM32 HAL库的底层操作,向上层提供简洁的接口。
  • MPPT控制服务: mppt_service.c 实现了扰动观察法MPPT算法。它周期性地读取太阳能电池板的电压和电流,计算功率,并根据P&O算法调整PWM占空比。
  • 24V-12V DC-DC控制服务: dcdc_service.c 实现了一个简单的电压反馈控制,用于稳定12V输出电压。这里使用了开关控制,更高级的控制可以考虑PID控制。
  • 应用层 (main.c): main.c 是主程序入口,负责初始化系统、启动服务层模块,并在主循环中周期性地调用服务层任务。
  • 延时函数: 代码中使用了 delay.hdelay_ms() 延时函数,需要您自行实现,可以使用 HAL_Delay 或 SysTick 定时器。
  • 错误处理: 代码中使用了 Error_Handler() 错误处理函数,您需要根据实际需求实现错误处理逻辑。
  • ADC通道配置: 代码中使用了 ADC_CHANNEL_0, ADC_CHANNEL_1, ADC_CHANNEL_2 等宏定义,您需要根据实际硬件连接配置正确的ADC通道。
  • PWM定时器配置: 代码中使用了 TIM2 定时器,您可以根据实际硬件资源选择合适的定时器,并配置预分频器、周期、通道等参数。
  • 电压电流转换: 代码中将 ADC 值转换为实际电压和电流值时,使用了示例的转换公式和分压电阻、电流采样电阻参数,您需要根据实际硬件电路参数进行校准。
  • 调试输出: 代码中注释掉了一些 printf 调试输出语句,您可以根据需要取消注释进行调试。

编译和运行:

  1. 创建工程: 使用您的STM32F4开发环境 (例如 Keil MDK, STM32CubeIDE) 创建一个新的工程,选择STM32F4系列芯片。
  2. 添加代码文件:adc.c, pwm.c, mppt_service.c, dcdc_service.c, main.c, delay.h (您自己实现的延时函数头文件) 等代码文件添加到工程中。
  3. 配置HAL库: 确保您的工程中包含了STM32F4 HAL库,并根据需要配置HAL库的外设 (例如 ADC, TIM, GPIO)。
  4. 硬件连接: 根据代码中的 ADC 通道配置和 PWM 输出引脚配置,将传感器和 DC-DC 控制电路连接到 STM32F4 开发板的相应引脚。
  5. 编译和下载: 编译工程,生成可执行文件,并将可执行文件下载到 STM32F4 开发板中。
  6. 测试和调试: 连接太阳能电池板和负载,上电运行系统,观察系统运行状态,使用调试工具 (例如串口调试助手、在线调试器) 进行调试和验证。

实践验证和改进方向:

  • 传感器校准: 精确的传感器数据是MPPT和DC-DC控制的基础,务必对电压传感器和电流传感器进行校准,确保测量精度。
  • MPPT算法优化: 扰动观察法虽然简单,但可能存在震荡问题。可以尝试改进的P&O算法,例如变步长P&O、自适应P&O等,或者更高级的MPPT算法,例如增量电导法 (Incremental Conductance)。
  • DC-DC控制优化: 简单的开关控制可能无法实现高精度的电压稳定。可以考虑使用PID控制算法来提高24V-12V DC-DC转换器的输出电压稳定性。
  • 参数调整: MPPT算法和DC-DC控制算法中的参数 (例如采样间隔、步长、PID参数) 需要根据实际系统进行调整,以获得最佳性能。
  • 保护功能: 为了提高系统的可靠性,可以添加过压保护、过流保护、过温保护等功能。
  • 数据记录和监控: 可以将系统运行数据 (例如太阳能电压、电流、功率、输出电压、温度等) 记录下来,方便进行性能分析和故障诊断。也可以通过串口或网络将数据发送到上位机进行远程监控。
  • RTOS (实时操作系统): 如果系统功能变得更复杂,可以考虑引入RTOS,例如 FreeRTOS,来管理任务调度和资源分配,提高系统的实时性和可靠性。

总结:

以上代码示例提供了一个基本的嵌入式太阳能MPPT和24V转12V双DCDC系统的软件架构和C代码框架。作为一个电力电子新手,您可以从这个基础代码开始,逐步学习和实践,不断改进和完善系统功能。 嵌入式系统开发是一个迭代的过程,需要不断地学习、实践、测试和优化。 祝您项目顺利!

请注意: 以上代码示例仅供参考,实际应用中需要根据具体的硬件电路、传感器型号、DC-DC转换器型号以及系统需求进行调整和完善。 在进行电力电子实验时,务必注意安全,避免触电和损坏硬件设备。 如果您在实践过程中遇到任何问题,欢迎随时提出,我会尽力提供帮助。

欢迎关注我的其它发布渠道