简介: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):

#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):

#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)

#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)

#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)

#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)

#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)

#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)

#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)

#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)

#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)

#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)

#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)

#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)

#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)

#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)

#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)

#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)

#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)

#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)

#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(){}
Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐