【本文发布于https://blog.csdn.net/Stack_/article/details/157063794,未经允许不得转载,转载须注明出处】



一、硬件


在这里插入图片描述

IIC通讯只有在单电阻模式下才会启用。

如果CFG1下拉10K电阻,CFG2、CFG3和MCU连接,插上充电器瞬间就输出9V了而且IIC功能是不可用的,也就是说要使用IIC功能则CFG1下拉电阻必须是手册中列出的电阻值,否则会进入“IO电平配置”模式。

这就存在一个问题:单电阻模式没有5V输出的配置,在开始进行IIC通信的时候就已经输出9V或以上电压了。如有必要,添加一个PMOS进行控制电压输出

CC1 CC2无需5.1K下拉,CH224内部已集成。

在这里插入图片描述



二、读取Source端即充电器端信息


在这里插入图片描述

这是PowerZ读取到的信息,开头2字节是信息头,后面每4个字节对应一个PDO,对应CH224A的0x60~0x8F寄存器,均为小端字节序



1、Header [CH224的0x60、0x61寄存器]


在这里插入图片描述


在这里插入图片描述

这里我们重点关注bit[14:12],知道有多少个PDO就知道后面有多少字节有效数据


2、PDOx [CH224的0x62-0x65、0x66-0x69、…]


在这里插入图片描述

每个PDO高两位指示该档位是固定电压还是PPS

在这里插入图片描述

固定电压则按此格式进行解析

在这里插入图片描述

PPS则按此格式进行解析

在这里插入图片描述

按以上协议解析PowerZ读取到的数据,和PowerZ解析的结果是吻合的



三、单片机读取与控制


IIC通信就是通用的时序,这个没什么好讲的。



在这里插入图片描述

将所有寄存器值读出,0x60寄存器开始可以看到有2字节Header和7个PDO



在这里插入图片描述

解析Source信息



读取到有效的PDO之后向0x0A和0x53写数据即可调整输出电压



附:代码


1、I2C驱动

#ifndef __BSP__SOFT_I2C__H__
#define __BSP__SOFT_I2C__H__

#include "public.h"


typedef enum {
    SOFTI2C_WRITE = 0,
    SOFTI2C_READ
} softi2c_cmdtype;   



void task_soft_i2c_init(void);

void SOFTI2C_Start(void);
void SOFTI2C_Stop(void);
void SOFTI2C_ACK(void);
void SOFTI2C_NACK(void);
uint8_t SOFTI2C_WaitACK(void);
void SOFTI2C_SendByte(uint8_t _1byte);
void SOFTI2C_ReadByte(uint8_t *_1byte);

void SOFTI2C_ReadWrite(uint8_t dev_addr, softi2c_cmdtype cmd, uint8_t reg_addr, uint8_t *bytes, uint8_t bytes_num);

#endif




#include "bsp_soft_i2c.h"


#define SOFTI2C_SCL_PORT              PORT5
#define SOFTI2C_SCL_PIN               PIN0

#define SOFTI2C_SDA_PORT              PORT5
#define SOFTI2C_SDA_PIN               PIN1


#define SOFTI2C_SCL_RESET()             PORT_ClrBit(SOFTI2C_SCL_PORT, SOFTI2C_SCL_PIN)
#define SOFTI2C_SCL_SET()               PORT_SetBit(SOFTI2C_SCL_PORT, SOFTI2C_SCL_PIN)

#define SOFTI2C_SDA_RESET()             PORT_ClrBit(SOFTI2C_SDA_PORT, SOFTI2C_SDA_PIN)
#define SOFTI2C_SDA_SET()               PORT_SetBit(SOFTI2C_SDA_PORT, SOFTI2C_SDA_PIN)


void SOFTI2C_SDA_PIN_MODE_IN(void)
{
  PORT_Init(SOFTI2C_SDA_PORT, SOFTI2C_SDA_PIN, INPUT);
}
void SOFTI2C_SDA_PIN_MODE_OUT(void)
{
  PORT_Init(SOFTI2C_SDA_PORT, SOFTI2C_SDA_PIN, OPENDRAIN_OUTPUT);
}

#define SOFTI2C_SDA_PIN_GET()               PORT_GetBit(SOFTI2C_SDA_PORT, SOFTI2C_SDA_PIN)





#define SOFTI2C_DELAY_xUS       20   //

/**
  * @brief  延时xus
  * @note
  * @param  None
  * @retval None
  * @author PWH
  * @date   2022/10
  */
void SOFTI2C_DELAY_US(uint32_t us)
{
    while (us)
    {
        us--;
    }
}


/**
  * @brief  起始信号
  * @note   SCL高电平期间,SDA跳变为低。需要保证start前sda和scl均为高
  * @param
  * @retval
  * @author PWH
  * @date   2022/7
  */
void SOFTI2C_Start(void)
{
    SOFTI2C_SDA_PIN_MODE_OUT();
    SOFTI2C_SDA_SET();
    SOFTI2C_SCL_SET();
    SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
    SOFTI2C_SDA_RESET();
    SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
    SOFTI2C_SCL_RESET();
    SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
}
/**
  * @brief  结束信号
  * @note   SCL高电平期间,SDA跳变为高
  * @param
  * @retval
  * @author PWH
  * @date   2022/7
  */
void SOFTI2C_Stop(void)
{
    SOFTI2C_SDA_PIN_MODE_OUT();
    SOFTI2C_SDA_RESET();
    SOFTI2C_SCL_SET();
    SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
    SOFTI2C_SDA_SET();
}
/**
  * @brief  主机发出应答
  * @note   发送完8bit后,第9bit发送前的SCL低电平期间,SDA拉低
  * @param
  * @retval
  * @author PWH
  * @date   2022/7
  */
void SOFTI2C_ACK(void)
{
    SOFTI2C_SDA_PIN_MODE_OUT();
    SOFTI2C_SDA_RESET();
    SOFTI2C_SCL_SET();
    SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
    SOFTI2C_SCL_RESET();
    SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
}
/**
  * @brief  主机发出非应答
  * @note   发送完8bit后,第9bit发送前的SCL低电平期间,SDA拉高
  * @param
  * @retval
  * @author PWH
  * @date   2022/7
  */
void SOFTI2C_NACK(void)
{
    SOFTI2C_SDA_PIN_MODE_OUT();
    SOFTI2C_SDA_SET();
    SOFTI2C_SCL_SET();
    SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
    SOFTI2C_SCL_RESET();
    SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
}
/**
  * @brief  等待从机应答
  * @note   每发送一个字节后,再产生一个scl低电平让从机把应答信号放到sda上
  * @param
  * @retval
  * @author PWH
  * @date   2022/7
  */
uint8_t SOFTI2C_WaitACK(void)
{
    uint8_t ack;

    SOFTI2C_SDA_PIN_MODE_IN();
    SOFTI2C_SCL_SET();
    ack = SOFTI2C_SDA_PIN_GET() ? 0 : 1;   //从机拉低sda应答
    SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
    SOFTI2C_SCL_RESET();
    SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
    return ack;
}
/**
  * @brief
  * @note
  * @param
  * @retval
  * @author PWH
  * @date   2022/7
  */
void SOFTI2C_SendByte(uint8_t _1byte)
{
    uint8_t i;

    SOFTI2C_SDA_PIN_MODE_OUT();
    for (i = 0; i < 8; i++)
    {
        if (_1byte & 0x80)
            SOFTI2C_SDA_SET();
        else
            SOFTI2C_SDA_RESET();
        SOFTI2C_SCL_SET();
        SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
        _1byte <<= 1;
        SOFTI2C_SCL_RESET();   //时钟低电平期间才允许数据变化
        SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
    }
}
/**
  * @brief
  * @note
  * @param
  * @retval
  * @author PWH
  * @date   2022/7
  */
void SOFTI2C_ReadByte(uint8_t *_1byte)
{
    uint8_t i;

    *_1byte = 0;
    SOFTI2C_SDA_PIN_MODE_IN();
    for (i = 0; i < 8; i++)
    {
        SOFTI2C_SCL_SET();
        SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
        *_1byte <<= 1;
        if (SOFTI2C_SDA_PIN_GET())
            *_1byte |= 0x01;
        SOFTI2C_SCL_RESET();
        SOFTI2C_DELAY_US(SOFTI2C_DELAY_xUS);//
    }
}
/**
  * @brief
  * @note
  * @param
  * @retval
  * @author PWH
  * @date   2022/7
  */
void SOFTI2C_ReadWrite(uint8_t dev_addr, softi2c_cmdtype cmd, uint8_t reg_addr, uint8_t *bytes, uint8_t bytes_num)
{
    uint8_t i;

    dev_addr <<= 1;
    
    SOFTI2C_Start();
    SOFTI2C_SendByte(dev_addr & 0xfe); 
    SOFTI2C_WaitACK();
    SOFTI2C_SendByte(reg_addr);    //寄存器地址
    SOFTI2C_WaitACK();
    if (cmd == SOFTI2C_WRITE)
    {
        for (i = 0; i < bytes_num; i++) //发送数据
        {
            SOFTI2C_SendByte(*bytes++);
            SOFTI2C_WaitACK();
        }
    }
    else
    {
        SOFTI2C_Start();
        SOFTI2C_SendByte(dev_addr | 0x01); //器件地址 读
        SOFTI2C_WaitACK();
        for (i = 0; i < bytes_num; i++)
        {
            SOFTI2C_ReadByte(bytes);
            
            if (i == bytes_num - 1) {
                SOFTI2C_NACK();
            }
            else {
                SOFTI2C_ACK();
            }
            bytes++;
        }
    }
    SOFTI2C_Stop();
}




/**
  * @brief  软i2c
  * @note   
  * @param
  * @retval
  * @author PWH
  * @date   2021
  */
void task_soft_i2c_init(void)
{   
    PORT_Init(SOFTI2C_SCL_PORT, SOFTI2C_SCL_PIN, OPENDRAIN_OUTPUT);
    PORT_Init(SOFTI2C_SDA_PORT, SOFTI2C_SDA_PIN, OPENDRAIN_OUTPUT);
    
}

2、CH224读写

#ifndef __BSP__CH224A__H__
#define __BSP__CH224A__H__

#include "public.h"

typedef enum {
  PD_FIXED,
  PD_PPS,
  PD_EPR,
  PD_AVS
} e_PDO_Type;

typedef struct {
  e_PDO_Type PDO_Type; 
  uint16_t VoltageMin;  //fixed固定电压档只有这个值有效,最大电压值忽略
  uint16_t VoltageMax;
  uint16_t CurrentMax;
  uint16_t PowerMax;
} PDO_info_t;

typedef struct {
  uint8_t NumOfPDO;
  uint16_t SupportMaxVoltage;
  PDO_info_t PDO_info[12];
} PD_PDO_Info_t;


extern PD_PDO_Info_t    PD_PDO_Info;

typedef struct
{
    int8_t gear;
    int16_t Voltage;
} UserSet_VoltageCurrent_t;
extern UserSet_VoltageCurrent_t  UserSet_VoltageCurrent;

void ch224a_loop(void);

#endif



#include "bsp_ch224a.h"

#define CH224A_IIC_ADDR       0x23

/**
  * @brief
  * @note
  * @param
  * @retval
  * @author PWH
  * @date   2022/7
  */
static void ch224a_read(uint8_t base_addr, uint8_t num_reg, uint8_t *array)
{
    uint8_t i;

    SOFTI2C_Start();
    SOFTI2C_SendByte((CH224A_IIC_ADDR << 1) | 0x01);
    SOFTI2C_WaitACK();

    for (i = 0; i < num_reg; i++)
    {
        SOFTI2C_ReadByte(array + i);

        if (i == num_reg - 1)
        {
            SOFTI2C_NACK();
        }
        else
        {
            SOFTI2C_ACK();
        }
    }

    SOFTI2C_Stop();
}



typedef enum
{
    REQ_VOLTAGE_5V = 0,
    REQ_VOLTAGE_9V,
    REQ_VOLTAGE_12V,
    REQ_VOLTAGE_15V,
    REQ_VOLTAGE_20V,
    REQ_VOLTAGE_28V,
    REQ_VOLTAGE_PPS,
    REQ_VOLTAGE_AVS
} e_ADDR_0AH_VAL;
typedef struct
{
    union
    {
        uint32_t PDOx;
        struct
        {
            uint32_t MaximumCurrent_in_10mA_units  : 10; //最大电流   *10mA
            uint32_t Voltage_in_50mV_units : 10; //电压  *50mV
            uint32_t PeakCurrent  : 2; //峰值电流
            uint32_t              : 1;
            uint32_t EPRModeCapable : 1;
            uint32_t UnchunkedExtendedMessagesSupported  : 1;
            uint32_t Dual_Role_Data : 1;
            uint32_t USB_CommunicationsCapable  : 1;
            uint32_t UnconstrainedPower   : 1;
            uint32_t USB_SuspendSupported : 1;
            uint32_t DualRolePower  : 1;
            uint32_t type   : 2;  //00固定电压  11PPS
        } PDO_FixedSupply;
        struct
        {
            uint32_t MaximumCurrent_in_50mA_increments      : 7; //最大电流 *50mA
            uint32_t                    : 1;
            uint32_t MinimumVoltage_in_100mV_increments    : 8;
            uint32_t                    : 1;
            uint32_t MaximumVoltage_in_100mV_increments    : 8; //最大电压 * 100mV
            uint32_t                    : 2;
            uint32_t PPS_PowerLimited  : 1;
            uint32_t SPR_EPR  : 2; //00:SPR  01:EPR
            uint32_t type   : 2;  //00固定电压  11PPS
        } PDO_AugmentedPowerDataObject_SPR; //标准PPS
        struct
        {
            uint32_t PDP_in_1W_increments      : 8;
            uint32_t MinimumVoltage_in_100mV_increments    : 8;
            uint32_t                    : 1;
            uint32_t MaximumVoltage_in_100mV_increments    : 9;
            uint32_t PeakCurrent   : 2;
            uint32_t SPR_EPR  : 2; //00:SPR  01:EPR
            uint32_t type   : 2;  //00固定电压  11PPS
        } PDO_AugmentedPowerDataObject_EPR; //PD3.1
        struct
        {
            uint32_t Maximum_Current_20V    : 10;   //15到20V的电流max,10mA步进,若低于15V则此电流为0
            uint32_t Maximum_Current_15V    : 10;   //9到15V的电流max,10mA步进
            uint32_t                    : 6;
            uint32_t PeakCurrent   : 2; //峰值电流
            uint32_t SPR_EPR  : 2; //00:SPR  01:EPR  02:AVS
            uint32_t type   : 2;  //00固定电压  11PPS 
        } PDO_AugmentedPowerDataObject_AVS; //PD3.2
    } u;
} PDO_x_t;
typedef struct
{
    union
    {
        uint8_t array[6 + 48];
        struct
        {
            struct
            {
                uint8_t BC_Active         : 1;
                uint8_t QC2_Active         : 1;
                uint8_t QC3_Active         : 1;
                uint8_t PD_Active         : 1;
                uint8_t EPR_Active         : 1;
                uint8_t                   : 3;
            } ADDR_09H_R_STATUS;
            uint8_t ADDR_0AH_W_REQ_VOLTAGE;
            uint8_t ADDR_50H_R_MAX_CURRENT;
            uint8_t ADDR_51H_W_AVS_REQ_VOLTAGE_H;
            uint8_t ADDR_52H_W_AVS_REQ_VOLTAGE_L;
            uint8_t ADDR_53H_W_PPS_REQ_VOLTAGE;
            union
            {
                uint16_t SOP;
                struct
                {
                    uint16_t MessageType    : 5;
                    uint16_t PortDataRole   : 1;
                    uint16_t SpecificationRevision  : 2;
                    uint16_t PortPowerRole____CablePlug : 1; //角色:0-SINK   1-SOURCE
                    uint16_t MessageID  : 3;
                    uint16_t NumberOfDataObject : 3;  //PDO数量
                    uint16_t Extended     : 1;
                } PD_Message_SOP;   //Start Of Packet
            } _SOP;
            PDO_x_t PDOx[8];
        } regs;
    } u;
} CH224A_REG_MAP_t;

CH224A_REG_MAP_t    CH224A_REG_MAP;

typedef struct
{
    uint16_t NowGearSupportMaxCurrent;
    uint16_t NowPPS_Voltage;
} CH224A_Data_t;
CH224A_Data_t CH224A_Data;

PD_PDO_Info_t    PD_PDO_Info;


UserSet_VoltageCurrent_t  UserSet_VoltageCurrent;

/**
  * @brief  主循环中调用
  * @note
  * @param
  * @retval
  * @author PWH
  * @date   2022/7
  */
void ch224a_loop(void)
{
    static uint32_t timer = 0;
    uint32_t i = 0;
    uint8_t write[8] = {0};
    static int8_t step = -1;
    char *display = array_display;
    
    switch (step)
    {
        case -1: UserSet_VoltageCurrent.gear = 0; UserSet_VoltageCurrent.Voltage = 5000; step++; break;
        default: break;
    }

    if (UserTimer_Read(&timer) >= 200)
    {
        UserTimer_Reset(&timer);

        SOFTI2C_ReadWrite(CH224A_IIC_ADDR, SOFTI2C_READ, 0x09, &CH224A_REG_MAP.u.array[0], 2);  //I2C状态寄存器 (激活的协议)  +  电压控制寄存器
        SOFTI2C_ReadWrite(CH224A_IIC_ADDR, SOFTI2C_READ, 0x50, &CH224A_REG_MAP.u.array[2], 4);  //
        SOFTI2C_ReadWrite(CH224A_IIC_ADDR, SOFTI2C_READ, 0x60, &CH224A_REG_MAP.u.array[6], 0x8F - 0x60 + 1);

        CH224A_Data.NowGearSupportMaxCurrent = (uint16_t)CH224A_REG_MAP.u.regs.ADDR_50H_R_MAX_CURRENT * 50; //当前 PD 档位下,可用最大电流值,仅在握手 PD 协议时有效
        //当前请求电压:5、9、12、15、20、28、PPS、AVS
        CH224A_Data.NowPPS_Voltage = (CH224A_REG_MAP.u.regs.ADDR_0AH_W_REQ_VOLTAGE == REQ_VOLTAGE_PPS) ? ((uint16_t)CH224A_REG_MAP.u.regs.ADDR_53H_W_PPS_REQ_VOLTAGE * 100) : 0;


        memset(&PD_PDO_Info, 0x00, sizeof(PD_PDO_Info));

        
        //解析从CH224读到的数据
        if (CH224A_REG_MAP.u.regs._SOP.PD_Message_SOP.NumberOfDataObject > 0) //有N个PDO(档位)
        {
            PD_PDO_Info.NumOfPDO = CH224A_REG_MAP.u.regs._SOP.PD_Message_SOP.NumberOfDataObject;

            for (i = 0; i < PD_PDO_Info.NumOfPDO; i++)
            {
                switch (CH224A_REG_MAP.u.regs.PDOx[i].u.PDO_FixedSupply.type) //该PDO是fixed还是pps
                {
                    case 0x00:  //固定电压
                        PD_PDO_Info.PDO_info[i].PDO_Type = PD_FIXED;
                        PD_PDO_Info.PDO_info[i].VoltageMin = (uint16_t)CH224A_REG_MAP.u.regs.PDOx[i].u.PDO_FixedSupply.Voltage_in_50mV_units * 50;
                        PD_PDO_Info.PDO_info[i].CurrentMax = (uint16_t)CH224A_REG_MAP.u.regs.PDOx[i].u.PDO_FixedSupply.MaximumCurrent_in_10mA_units * 10;
                        if (PD_PDO_Info.SupportMaxVoltage < PD_PDO_Info.PDO_info[i].VoltageMin)
                            PD_PDO_Info.SupportMaxVoltage = PD_PDO_Info.PDO_info[i].VoltageMin;
                        break;
                    case 0x03:  //PPS
                        switch (CH224A_REG_MAP.u.regs.PDOx[i].u.PDO_AugmentedPowerDataObject_SPR.SPR_EPR)
                        {
                            case 0: //标准PPS (SPR PPS)
                                PD_PDO_Info.PDO_info[i].PDO_Type = PD_PPS;
                                PD_PDO_Info.PDO_info[i].VoltageMin = (uint16_t)CH224A_REG_MAP.u.regs.PDOx[i].u.PDO_AugmentedPowerDataObject_SPR.MinimumVoltage_in_100mV_increments * 100;
                                PD_PDO_Info.PDO_info[i].VoltageMax = (uint16_t)CH224A_REG_MAP.u.regs.PDOx[i].u.PDO_AugmentedPowerDataObject_SPR.MaximumVoltage_in_100mV_increments * 100;
                                PD_PDO_Info.PDO_info[i].CurrentMax = (uint16_t)CH224A_REG_MAP.u.regs.PDOx[i].u.PDO_AugmentedPowerDataObject_SPR.MaximumCurrent_in_50mA_increments * 50;
                                break;
                            case 1: //EPR AVS
                                PD_PDO_Info.PDO_info[i].PDO_Type = PD_EPR;
                                PD_PDO_Info.PDO_info[i].VoltageMin = (uint16_t)CH224A_REG_MAP.u.regs.PDOx[i].u.PDO_AugmentedPowerDataObject_EPR.MinimumVoltage_in_100mV_increments * 100;
                                PD_PDO_Info.PDO_info[i].VoltageMax = (uint16_t)CH224A_REG_MAP.u.regs.PDOx[i].u.PDO_AugmentedPowerDataObject_EPR.MaximumVoltage_in_100mV_increments * 100;
                                PD_PDO_Info.PDO_info[i].PowerMax = (uint16_t)CH224A_REG_MAP.u.regs.PDOx[i].u.PDO_AugmentedPowerDataObject_EPR.PDP_in_1W_increments;
                                break;
                            case 2: //SPR AVS  (PD3.2新增)
                                PD_PDO_Info.PDO_info[i].PDO_Type = PD_AVS;
                                if (PD_PDO_Info.SupportMaxVoltage > 15000U) {
                                    PD_PDO_Info.PDO_info[i].VoltageMin = 9000U;
                                    PD_PDO_Info.PDO_info[i].VoltageMax = PD_PDO_Info.SupportMaxVoltage;
                                    PD_PDO_Info.PDO_info[i].CurrentMax = (uint16_t)CH224A_REG_MAP.u.regs.PDOx[i].u.PDO_AugmentedPowerDataObject_AVS.Maximum_Current_20V * 10;
                                } else {
                                    PD_PDO_Info.PDO_info[i].VoltageMin = 9000U;
                                    PD_PDO_Info.PDO_info[i].VoltageMax = PD_PDO_Info.SupportMaxVoltage;
                                    PD_PDO_Info.PDO_info[i].CurrentMax = (uint16_t)CH224A_REG_MAP.u.regs.PDOx[i].u.PDO_AugmentedPowerDataObject_AVS.Maximum_Current_15V * 10;
                                }
                                break;
                        }
                        break;
                }
            }
            
            
            //调试输出

            for (i = 0; i < PD_PDO_Info.NumOfPDO; i++)
            {
                switch (PD_PDO_Info.PDO_info[i].PDO_Type)
                {
                    case PD_FIXED:  //固定电压
                        printf(" PDO%d,固定电压%dmV,最大输出电流%dmA \r\n", i,
                               PD_PDO_Info.PDO_info[i].VoltageMin,
                               PD_PDO_Info.PDO_info[i].CurrentMax);
                        break;
                    case PD_PPS:  //PPS
                        printf(" PDO%d,PPS,电压范围:%d - %dmV,最大输出电流%dmA \r\n", i,
                               PD_PDO_Info.PDO_info[i].VoltageMin,
                               PD_PDO_Info.PDO_info[i].VoltageMax,
                               PD_PDO_Info.PDO_info[i].CurrentMax);
                        break;
                    case PD_EPR:
                        printf(" PDO%d,EPR,电压范围:%d - %dmV,最大输出功率%dW \r\n", i,
                               PD_PDO_Info.PDO_info[i].VoltageMin,
                               PD_PDO_Info.PDO_info[i].VoltageMax,
                               PD_PDO_Info.PDO_info[i].PowerMax);
                        break;
                    case PD_AVS:
                        printf(" PDO%d,AVS,电压范围:%d - %dmV,最大输出电流%dmA \r\n", i,
                               PD_PDO_Info.PDO_info[i].VoltageMin,
                               PD_PDO_Info.PDO_info[i].VoltageMax,
                               PD_PDO_Info.PDO_info[i].CurrentMax);
                        break;
                }
            }
            
            if (0 == PD_PDO_Info.NumOfPDO)
                UserSet_VoltageCurrent.Voltage = 5000;

            //debug中修改或者外部指令修改UserSet_VoltageCurrent.Voltage,在这里调整输出电压
            if (UserSet_VoltageCurrent.Voltage <= 5000)
            {
                write[0] = REQ_VOLTAGE_5V;
                SOFTI2C_ReadWrite(CH224A_IIC_ADDR, SOFTI2C_WRITE, 0x0A, write, 1);
            }
            else if (UserSet_VoltageCurrent.Voltage == 9000)
            {
                write[0] = REQ_VOLTAGE_9V;
                SOFTI2C_ReadWrite(CH224A_IIC_ADDR, SOFTI2C_WRITE, 0x0A, write, 1);
            }
            else if (UserSet_VoltageCurrent.Voltage == 12000)
            {
                write[0] = REQ_VOLTAGE_12V;
                SOFTI2C_ReadWrite(CH224A_IIC_ADDR, SOFTI2C_WRITE, 0x0A, write, 1);
            }
            else if (UserSet_VoltageCurrent.Voltage == 15000)
            {
                write[0] = REQ_VOLTAGE_15V;
                SOFTI2C_ReadWrite(CH224A_IIC_ADDR, SOFTI2C_WRITE, 0x0A, write, 1);
            }
            else if (UserSet_VoltageCurrent.Voltage == 20000)
            {
                write[0] = REQ_VOLTAGE_20V;
                SOFTI2C_ReadWrite(CH224A_IIC_ADDR, SOFTI2C_WRITE, 0x0A, write, 1);
            }
            else  //固定电压向0A寄存器请求(↑),PPS向53寄存器请求(↓),然后写0A将档位设定为PPS
            {
                if (UserSet_VoltageCurrent.Voltage > 21000)
                    UserSet_VoltageCurrent.Voltage = 21000;
                write[0] = UserSet_VoltageCurrent.Voltage / 100;
                SOFTI2C_ReadWrite(CH224A_IIC_ADDR, SOFTI2C_WRITE, 0x53, write, 1);  //
                write[0] = REQ_VOLTAGE_PPS;
                SOFTI2C_ReadWrite(CH224A_IIC_ADDR, SOFTI2C_WRITE, 0x0A, write, 1);
            }
            
        }
    }
    
}



Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐