编程技术分享

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

0%

简介:USB可调电源,输入防倒灌防反接,输出防倒灌,支持USB PD3.0,BC1.2等,DC 5V~27V输入,输出电压2V ~ 34V连续可调,大于5A的带载能力,限流10mA~8A连续可调

好的,根据您提供的嵌入式产品图片和项目需求描述,我将从一个高级嵌入式软件开发工程师的角度,详细阐述该项目的代码设计架构,并提供相应的C代码实现,同时还会介绍项目中采用的经过实践验证的技术和方法。
关注微信公众号,提前获取相关推文

一、系统架构设计

为了实现一个可靠、高效、可扩展的USB可调电源系统,我将采用以下分层架构:

  1. 硬件抽象层 (HAL):

    • 目标: 将硬件操作与上层应用隔离,提供统一的硬件访问接口。
    • 模块:
      • ADC (Analog-to-Digital Converter): 处理电压、电流等模拟信号的采集。
      • DAC (Digital-to-Analog Converter): 控制输出电压。
      • GPIO (General Purpose Input/Output): 控制LED指示灯、按键等。
      • I2C/SPI: 访问外部传感器、存储器等。
      • PWM (Pulse-Width Modulation): 实现开关电源控制。
      • USB (Universal Serial Bus): 处理USB PD和BC1.2协议。
      • Timer: 实现定时任务和PWM控制。
      • 保护电路控制: 控制防倒灌,防反接等保护电路的开启与关闭。
  2. 驱动层 (Driver Layer):

    • 目标: 实现特定硬件设备的驱动逻辑,提供更高层次的抽象。
    • 模块:
      • ADC Driver: 读取电压、电流值,进行校准和滤波处理。
      • DAC Driver: 设置输出电压,根据需求进行微调。
      • Power Control Driver: 控制电源模块,实现限流,过压保护等功能。
      • USB PD Driver: 实现USB PD协议的协商和通信。
      • BC1.2 Driver: 实现BC1.2协议的设备充电识别。
      • Display Driver: 控制LCD显示,刷新显示内容。
      • Keypad Driver: 处理按键事件。
      • Storage Driver: 读写配置参数到Flash或EEPROM。
  3. 核心逻辑层 (Core Logic Layer):

    • 目标: 实现系统的核心功能,如电源控制、参数设置、显示更新、保护逻辑等。
    • 模块:
      • Power Management Module: 实现电源的启动、停止、过载保护、短路保护等。
      • Voltage/Current Control Module: 根据用户设置调整输出电压和电流。
      • Protection Module: 检测输入过压、过流、输出过压、过流、过温等异常情况,采取保护措施。
      • Parameter Setting Module: 读取、修改、保存参数。
      • Display Management Module: 控制显示更新,提供用户友好的界面。
      • Communication Management Module: 处理USB PD等通信协议。
      • Calibration Module: 对ADC和DAC进行校准。
  4. 应用层 (Application Layer):

    • 目标: 实现用户交互界面,提供用户操作和监控功能。
    • 模块:
      • Main Task: 系统主循环,处理各种事件。
      • UI Task: 刷新显示,响应用户输入。

二、代码设计原则

  • 模块化: 将系统划分为独立模块,降低模块之间的耦合,提高代码可维护性。
  • 可读性: 代码风格统一,注释清晰,避免使用过于复杂的代码逻辑。
  • 可移植性: 避免使用特定硬件相关的代码,使用HAL层进行硬件抽象。
  • 可扩展性: 方便添加新的功能模块,满足未来需求。
  • 鲁棒性: 考虑各种异常情况,进行错误处理和保护。

三、具体C代码实现

以下代码示例仅为部分模块的实现,为了便于理解,已简化代码细节,并添加了详细的注释。

1. HAL层 (hal.h):

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
#ifndef HAL_H
#define HAL_H

#include <stdint.h>
#include <stdbool.h>

// ADC functions
typedef struct {
uint16_t (*read_channel)(uint8_t channel); // 读取ADC通道的电压值
} adc_hal_t;

extern adc_hal_t adc_hal;

// DAC functions
typedef struct {
bool (*set_voltage)(uint16_t voltage); // 设置DAC输出电压
} dac_hal_t;

extern dac_hal_t dac_hal;

// GPIO functions
typedef struct {
void (*set_pin_output)(uint8_t pin, bool value); // 设置GPIO引脚输出
bool (*read_pin_input)(uint8_t pin); // 读取GPIO引脚输入
} gpio_hal_t;

extern gpio_hal_t gpio_hal;

// I2C functions
typedef struct {
bool (*write_bytes)(uint8_t addr, const uint8_t *data, uint16_t len); // I2C写入
bool (*read_bytes)(uint8_t addr, uint8_t *data, uint16_t len); // I2C读取
} i2c_hal_t;

extern i2c_hal_t i2c_hal;

// PWM functions
typedef struct {
bool (*set_duty_cycle)(uint8_t channel, uint16_t duty_cycle); // 设置PWM占空比
bool (*set_frequency)(uint8_t channel, uint32_t frequency); // 设置PWM频率
} pwm_hal_t;

extern pwm_hal_t pwm_hal;


// USB functions (Simplified for demonstration)
typedef struct {
bool (*usb_send_data)(uint8_t* data, uint16_t length); // 发送数据
bool (*usb_receive_data)(uint8_t* data, uint16_t* length); // 接收数据
bool (*usb_connect_status)(void); // 连接状态
} usb_hal_t;
extern usb_hal_t usb_hal;

// Timer functions
typedef struct {
void (*start_timer)(uint32_t period_ms, void (*callback)(void)); // 开始定时器
void (*stop_timer)(); // 停止定时器
} timer_hal_t;

extern timer_hal_t timer_hal;


//Protection control fuctions
typedef struct {
void (*set_protection_enable)(bool enable);
bool (*get_protection_enable)(void);
}protection_hal_t;
extern protection_hal_t protection_hal;
#endif

2. HAL层实现 (hal.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
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include "hal.h"
#include "stm32fxxx_hal.h" // Replace with your specific hardware HAL headers

// ADC HAL implementation
uint16_t adc_read_channel_impl(uint8_t channel) {
//Implement using stm32 HAL
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);
return HAL_ADC_GetValue(&hadc1);

}

adc_hal_t adc_hal = {
.read_channel = adc_read_channel_impl
};

// DAC HAL implementation
bool dac_set_voltage_impl(uint16_t voltage) {
HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, voltage);
return true;
}

dac_hal_t dac_hal = {
.set_voltage = dac_set_voltage_impl
};


// GPIO HAL implementation
void gpio_set_pin_output_impl(uint8_t pin, bool value) {
GPIO_PinState state = value ? GPIO_PIN_SET : GPIO_PIN_RESET;
//Implement using stm32 HAL
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, state);
}

bool gpio_read_pin_input_impl(uint8_t pin) {
//Implement using stm32 HAL
return HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_1);
}

gpio_hal_t gpio_hal = {
.set_pin_output = gpio_set_pin_output_impl,
.read_pin_input = gpio_read_pin_input_impl
};


// I2C HAL implementation
bool i2c_write_bytes_impl(uint8_t addr, const uint8_t *data, uint16_t len) {
//Implement using stm32 HAL
HAL_I2C_Master_Transmit(&hi2c1, addr, (uint8_t *)data, len, 100);
return true;
}

bool i2c_read_bytes_impl(uint8_t addr, uint8_t *data, uint16_t len) {
//Implement using stm32 HAL
HAL_I2C_Master_Receive(&hi2c1, addr, data, len, 100);
return true;
}
i2c_hal_t i2c_hal = {
.write_bytes = i2c_write_bytes_impl,
.read_bytes = i2c_read_bytes_impl
};


// PWM HAL implementation
bool pwm_set_duty_cycle_impl(uint8_t channel, uint16_t duty_cycle) {
//Implement using stm32 HAL
TIM_OC_InitTypeDef sConfigOC = {0};
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = duty_cycle;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
return false;
}
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
return true;
}

bool pwm_set_frequency_impl(uint8_t channel, uint32_t frequency) {
//Implement using stm32 HAL

return true;
}
pwm_hal_t pwm_hal = {
.set_duty_cycle = pwm_set_duty_cycle_impl,
.set_frequency = pwm_set_frequency_impl
};


//USB HAL Implementation
bool usb_send_data_impl(uint8_t* data, uint16_t length)
{
//Implement using stm32 HAL
return CDC_Transmit_FS(data, length) == USBD_OK;

}

bool usb_receive_data_impl(uint8_t* data, uint16_t* length)
{
return true;
}

bool usb_connect_status_impl(void)
{
return true;
}
usb_hal_t usb_hal ={
.usb_send_data = usb_send_data_impl,
.usb_receive_data = usb_receive_data_impl,
.usb_connect_status = usb_connect_status_impl,

};

// Timer HAL Implementation
void timer_start_timer_impl(uint32_t period_ms, void (*callback)(void)) {
//Implement using stm32 HAL
// Set timer period and start the timer
timer_callback = callback; // Save callback to be invoked in HAL_TIM_PeriodElapsedCallback
__HAL_TIM_SET_AUTORELOAD(&htim6, period_ms-1);
HAL_TIM_Base_Start_IT(&htim6);
}
void timer_stop_timer_impl()
{
//Implement using stm32 HAL
HAL_TIM_Base_Stop_IT(&htim6);
}
timer_hal_t timer_hal = {
.start_timer = timer_start_timer_impl,
.stop_timer = timer_stop_timer_impl,
};
//Global variables
void (*timer_callback)(void) = NULL;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM6) {
if (timer_callback != NULL) {
timer_callback();
}
}
}

//Protection HAL implementation
void protection_set_enable_impl(bool enable){
//Implement using stm32 HAL
GPIO_PinState state = enable ? GPIO_PIN_SET : GPIO_PIN_RESET;
//Implement using stm32 HAL
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, state);
}
bool protection_get_enable_impl(void){
//Implement using stm32 HAL
return HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);
}

protection_hal_t protection_hal={
.set_protection_enable = protection_set_enable_impl,
.get_protection_enable = protection_get_enable_impl,
};

3. 驱动层 (adc_driver.h)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef ADC_DRIVER_H
#define ADC_DRIVER_H

#include <stdint.h>
#include <stdbool.h>

typedef struct {
float (*read_voltage)(uint8_t channel); // 读取电压值,单位为伏特
float (*read_current)(uint8_t channel); // 读取电流值,单位为安培
bool (*calibrate_adc)(void); // 校准ADC
void (*filter_data)(float *data); //滤波数据
} adc_driver_t;

extern adc_driver_t adc_driver;

#endif

4. 驱动层 (adc_driver.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
#include "adc_driver.h"
#include "hal.h"
#include "filter.h"

// 转换系数,需要根据实际硬件调整
#define ADC_VOLTAGE_COEFF 0.001 // 示例系数,需要根据实际硬件校准
#define ADC_CURRENT_COEFF 0.0001 // 示例系数,需要根据实际硬件校准
#define ADC_FILTER_LEN 10 //示例滤波长度

float adc_voltage_values[ADC_FILTER_LEN] = {0};
float adc_current_values[ADC_FILTER_LEN] = {0};
uint16_t adc_value_index=0;
static float apply_calibration(uint16_t adc_raw, float coeff);

float adc_read_voltage_impl(uint8_t channel) {
uint16_t raw_value = adc_hal.read_channel(channel);
float voltage = apply_calibration(raw_value,ADC_VOLTAGE_COEFF);
adc_voltage_values[adc_value_index] = voltage;
return voltage;
}

float adc_read_current_impl(uint8_t channel) {
uint16_t raw_value = adc_hal.read_channel(channel);
float current = apply_calibration(raw_value,ADC_CURRENT_COEFF);
adc_current_values[adc_value_index] = current;
return current;
}

bool adc_calibrate_adc_impl(void){
//TODO 校准ADC
return true;
}

void adc_filter_data_impl(float *data){
//Implement using filters library
if(data == &adc_voltage_values[0]){
moving_average_filter(adc_voltage_values,ADC_FILTER_LEN,data);
}else if(data == &adc_current_values[0])
{
moving_average_filter(adc_current_values,ADC_FILTER_LEN,data);
}
if(++adc_value_index >= ADC_FILTER_LEN)
{
adc_value_index =0;
}
}
static float apply_calibration(uint16_t adc_raw, float coeff) {
// TODO Implement your ADC calibration
return (float)adc_raw * coeff;
}

adc_driver_t adc_driver = {
.read_voltage = adc_read_voltage_impl,
.read_current = adc_read_current_impl,
.calibrate_adc = adc_calibrate_adc_impl,
.filter_data = adc_filter_data_impl,
};

5. 驱动层 (dac_driver.h)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef DAC_DRIVER_H
#define DAC_DRIVER_H

#include <stdint.h>
#include <stdbool.h>

typedef struct {
bool (*set_output_voltage)(float voltage); // 设置输出电压,单位为伏特
bool (*calibrate_dac)(void); //校准DAC
} dac_driver_t;

extern dac_driver_t dac_driver;

#endif

6. 驱动层 (dac_driver.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
#include "dac_driver.h"
#include "hal.h"

// 转换系数,需要根据实际硬件调整
#define DAC_VOLTAGE_COEFF 100 // 示例系数,需要根据实际硬件校准
#define DAC_OFFSET 0 //偏移量,需要根据实际硬件校准

static uint16_t calculate_dac_value(float voltage);

bool dac_set_output_voltage_impl(float voltage) {
uint16_t dac_value = calculate_dac_value(voltage);
return dac_hal.set_voltage(dac_value);
}
bool dac_calibrate_dac_impl(void){
//TODO 校准DAC
return true;
}

static uint16_t calculate_dac_value(float voltage) {
uint16_t dac_value = (uint16_t)(voltage * DAC_VOLTAGE_COEFF + DAC_OFFSET);
// Ensure the value is within valid DAC range
if(dac_value > 4095) dac_value = 4095;
return dac_value;
}

dac_driver_t dac_driver = {
.set_output_voltage = dac_set_output_voltage_impl,
.calibrate_dac = dac_calibrate_dac_impl
};

7. 驱动层 (usb_pd_driver.h)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef USB_PD_DRIVER_H
#define USB_PD_DRIVER_H

#include <stdint.h>
#include <stdbool.h>

typedef struct {
bool (*negotiate_power)(float voltage, float current); // 请求特定电压和电流
bool (*get_negotiated_power)(float *voltage, float* current); //获取协商后的电压和电流
void (*process_pd_message)(uint8_t *data, uint16_t len);
} usb_pd_driver_t;

extern usb_pd_driver_t usb_pd_driver;

#endif

8. 驱动层 (usb_pd_driver.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
#include "usb_pd_driver.h"
#include "hal.h"
#include <stdio.h>
#include <string.h>

#define PD_REQUEST_MESSAGE_TYPE 0x02 //Example message type
#define PD_RESPONSE_MESSAGE_TYPE 0x03 //Example message type

// 模拟USB PD协议
bool usb_pd_negotiate_power_impl(float voltage, float current) {
// 实现USB PD协议协商过程,包括发送请求和接收响应
printf("Requesting USB PD power: Voltage = %.2fV, Current = %.2fA\n", voltage, current);
uint8_t data[32];
data[0] = PD_REQUEST_MESSAGE_TYPE;
memcpy(&data[1],&voltage, sizeof(float));
memcpy(&data[5], &current, sizeof(float));
return usb_hal.usb_send_data(data,9);
}

bool usb_pd_get_negotiated_power_impl(float *voltage, float* current)
{
// Implement USB PD to retrieve negotiated power
return true;
}
void usb_pd_process_pd_message_impl(uint8_t* data, uint16_t len){
//Process PD message and extract data

if(data[0] == PD_RESPONSE_MESSAGE_TYPE){
float response_voltage;
float response_current;
memcpy(&response_voltage, &data[1], sizeof(float));
memcpy(&response_current, &data[5], sizeof(float));
printf("Received USB PD power: Voltage = %.2fV, Current = %.2fA\n", response_voltage, response_current);

}
}

usb_pd_driver_t usb_pd_driver = {
.negotiate_power = usb_pd_negotiate_power_impl,
.get_negotiated_power = usb_pd_get_negotiated_power_impl,
.process_pd_message = usb_pd_process_pd_message_impl
};

9. 驱动层 (bc12_driver.h)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef BC12_DRIVER_H
#define BC12_DRIVER_H

#include <stdint.h>
#include <stdbool.h>

typedef enum {
BC12_NONE,
BC12_DCP,
BC12_CDP,
BC12_SDP,
} bc12_type_t;

typedef struct {
bc12_type_t (*detect_charger_type)(void);
bool (*enable_charging)(bool enable); //使能或禁用BC1.2充电
} bc12_driver_t;

extern bc12_driver_t bc12_driver;

#endif

10. 驱动层 (bc12_driver.c)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "bc12_driver.h"
#include "hal.h"

// 模拟BC1.2协议
bc12_type_t bc12_detect_charger_type_impl(void) {
//TODO Implement BC1.2 protocol detection
// (模拟检测结果,实际需要读取硬件状态)
return BC12_DCP; // DCP (专用充电端口)
}

bool bc12_enable_charging_impl(bool enable) {
// TODO Implement BC1.2 control
return true;
}

bc12_driver_t bc12_driver = {
.detect_charger_type = bc12_detect_charger_type_impl,
.enable_charging = bc12_enable_charging_impl,
};

11. 核心逻辑层 (power_control.h)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef POWER_CONTROL_H
#define POWER_CONTROL_H

#include <stdint.h>
#include <stdbool.h>

typedef struct {
bool (*set_output_voltage)(float voltage);
bool (*set_output_current)(float current);
bool (*enable_output)(bool enable);
bool (*get_output_status)(void);
} power_control_t;

extern power_control_t power_control;

#endif

12. 核心逻辑层 (power_control.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
#include "power_control.h"
#include "dac_driver.h"
#include "pwm_driver.h"

static bool power_output_enabled = false;
bool power_set_output_voltage_impl(float voltage) {
// TODO Implement output control logic, such as boost or buck
// Set the DAC output voltage
return dac_driver.set_output_voltage(voltage);
}
bool power_set_output_current_impl(float current) {
// TODO Implement current limit logic
return true;
}

bool power_enable_output_impl(bool enable){
// TODO Implement output Enable logic
power_output_enabled = enable;
return true;
}

bool power_get_output_status_impl(void){
return power_output_enabled;
}

power_control_t power_control = {
.set_output_voltage = power_set_output_voltage_impl,
.set_output_current = power_set_output_current_impl,
.enable_output = power_enable_output_impl,
.get_output_status = power_get_output_status_impl,
};

13. 核心逻辑层 (protection.h)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef PROTECTION_H
#define PROTECTION_H

#include <stdint.h>
#include <stdbool.h>

typedef struct {
bool (*check_overvoltage)(float voltage);
bool (*check_overcurrent)(float current);
bool (*check_overtemperature)(float temperature);
bool (*activate_protection)(void);
bool (*reset_protection)(void);
} protection_t;

extern protection_t protection;

#endif

14. 核心逻辑层 (protection.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
#include "protection.h"
#include "hal.h"

// 设定保护阈值 (需要根据实际硬件调整)
#define OVERVOLTAGE_THRESHOLD 28.0f
#define OVERCURRENT_THRESHOLD 8.5f
#define OVERTEMP_THRESHOLD 85.0f

static bool protection_triggered = false;
bool protection_check_overvoltage_impl(float voltage) {
return voltage > OVERVOLTAGE_THRESHOLD;
}

bool protection_check_overcurrent_impl(float current) {
return current > OVERCURRENT_THRESHOLD;
}

bool protection_check_overtemperature_impl(float temperature) {
return temperature > OVERTEMP_THRESHOLD;
}

bool protection_activate_protection_impl(void) {
// Implement protection activation logic, disable output
protection_triggered = true;
protection_hal.set_protection_enable(true);
return true;
}

bool protection_reset_protection_impl(void) {
// Implement protection reset logic, enable output
protection_triggered = false;
protection_hal.set_protection_enable(false);
return true;
}

protection_t protection = {
.check_overvoltage = protection_check_overvoltage_impl,
.check_overcurrent = protection_check_overcurrent_impl,
.check_overtemperature = protection_check_overtemperature_impl,
.activate_protection = protection_activate_protection_impl,
.reset_protection = protection_reset_protection_impl
};

15. 应用层 (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
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
114
#include "main.h"
#include "hal.h"
#include "adc_driver.h"
#include "dac_driver.h"
#include "usb_pd_driver.h"
#include "bc12_driver.h"
#include "power_control.h"
#include "protection.h"
#include "display.h"
#include "keypad.h"
#include <stdio.h>

// Global Variables
float target_voltage = 5.0f;
float target_current = 1.0f;
float measured_voltage = 0.0f;
float measured_current = 0.0f;

void system_init(void);
void read_and_update_values(void);
void check_protection(void);
void usb_pd_task(void);

int main(void) {

system_init();
// Main loop
while (1) {
read_and_update_values();
check_protection();
// UI update task
update_display(measured_voltage,measured_current, target_voltage, target_current, power_control.get_output_status());
// Process input
process_keypad_input();
usb_pd_task();
HAL_Delay(100);
}
}

void system_init(void)
{
// Initialize Peripherals
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_DAC1_Init();
MX_I2C1_Init();
MX_TIM3_Init();
MX_USB_DEVICE_Init();
MX_TIM6_Init();

// Calibrate hardware
adc_driver.calibrate_adc();
dac_driver.calibrate_dac();
timer_hal.start_timer(100,update_display_data);
// Init modules
display_init();
keypad_init();
power_control.enable_output(true);

}
void read_and_update_values()
{
// Read and filter ADC values
measured_voltage = adc_driver.read_voltage(0);
measured_current = adc_driver.read_current(1);
float voltage_filter = 0.0f;
float current_filter = 0.0f;
adc_driver.filter_data(&measured_voltage);
adc_driver.filter_data(&measured_current);
power_control.set_output_voltage(target_voltage);
power_control.set_output_current(target_current);
}

void check_protection(void)
{
// Check protection
if (protection.check_overvoltage(measured_voltage) ||
protection.check_overcurrent(measured_current))
{
if(!protection_triggered)
{
protection.activate_protection();
power_control.enable_output(false);
printf("Protection Triggered!\n");
}
} else {
if(protection_triggered){
protection.reset_protection();
power_control.enable_output(true);
printf("Protection Reset!\n");
}
}
}
void usb_pd_task(void)
{
if(usb_hal.usb_connect_status())
{
uint8_t data[32];
uint16_t length = 0;
if(usb_hal.usb_receive_data(data, &length)){
usb_pd_driver.process_pd_message(data, length);
}
}
}

void Error_Handler(void)
{

while (1)
{
}
}

16. 显示模块 (display.h)

1
2
3
4
5
6
7
8
9
10
#ifndef DISPLAY_H
#define DISPLAY_H
#include <stdint.h>
#include <stdbool.h>

void display_init(void);
void update_display(float voltage, float current, float set_voltage, float set_current,bool power_status);
void update_display_data(void);

#endif

17. 显示模块 (display.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
#include "display.h"
#include "i2c_driver.h"
#include <stdio.h>

#define LCD_ADDR 0x3C // Replace with the I2C address of your LCD display
#define LCD_WIDTH 128
#define LCD_HEIGHT 64
#define FONT_WIDTH 6
#define FONT_HEIGHT 8

// Example: Mock display driver. Replace with your display's implementation.
void display_init(void) {
printf("Display Initialized\n");
}
void update_display_data(void){
//Mock display update timer
}
void update_display(float voltage, float current, float set_voltage, float set_current, bool power_status) {
// Create display message
printf("Measured V: %.2fV\n", voltage);
printf("Measured A: %.2fA\n", current);
printf("Set V: %.2fV\n", set_voltage);
printf("Set A: %.2fA\n", set_current);
printf("Power status:%s\n", power_status ? "On" : "Off");
//Mock display update
}

18. 按键模块 (keypad.h)

1
2
3
4
5
6
7
8
9
10
#ifndef KEYPAD_H
#define KEYPAD_H

#include <stdint.h>
#include <stdbool.h>

void keypad_init(void);
void process_keypad_input(void);

#endif

19. 按键模块 (keypad.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
#include "keypad.h"
#include "hal.h"
#include "main.h"
#include <stdio.h>

#define KEY_VOLTAGE_UP 1
#define KEY_VOLTAGE_DOWN 2
#define KEY_CURRENT_UP 3
#define KEY_CURRENT_DOWN 4

void keypad_init(void) {
printf("Keypad Initialized\n");
}

void process_keypad_input(void) {
if(gpio_hal.read_pin_input(KEY_VOLTAGE_UP)){
target_voltage += 0.1f;
printf("Voltage Up\n");
HAL_Delay(100);
}else if(gpio_hal.read_pin_input(KEY_VOLTAGE_DOWN)){
target_voltage -= 0.1f;
printf("Voltage Down\n");
HAL_Delay(100);
} else if (gpio_hal.read_pin_input(KEY_CURRENT_UP)){
target_current += 0.1f;
printf("Current Up\n");
HAL_Delay(100);
}else if (gpio_hal.read_pin_input(KEY_CURRENT_DOWN))
{
target_current -= 0.1f;
printf("Current Down\n");
HAL_Delay(100);
}
}

20. 滤波库 (filter.h)

1
2
3
4
5
6
7
8
#ifndef FILTER_H
#define FILTER_H

#include <stdint.h>
#include <stdbool.h>

void moving_average_filter(float *data, uint16_t len, float *result);
#endif

21. 滤波库 (filter.c)

#include "filter.h"

void moving_average_filter(float *data, uint16_t len, float

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