• 1
    回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

【DigiKey评估版专场】电压输出测试

阅读说明书了解到TPS65273V 是一款4.5V-18V 宽输入、3.5A/3.5A 双通道同步降压转换器,支持 I2C 可编程输出电压(0.68V-1.95V,10mV 步长),兼具电流均流、软启动、过流 / 过热保护等功能。使用电路板如图所示。

最初上电,通过Vin输入8V电压,可以直接在J18处测量得电压为0.99V,在J31处测得电压为1.09V,符合说明书中提到的输出电压值。

因为没有USB-to-GPIO这个工具,这几天便在网上搜索如何可以控制寄存器进行改变输出电压的控制方法。

寻找到一个方法如下,但是在实践过程中,没有实现调整的功能,现将电路和程序放在论坛上,请懂的朋友给指点下,该如何进行排查。

 

I2C 软件寄存器控制

1. 硬件设置

VIN=8V

JP1接高电平EN1使能,万用表测试约6.69V

JP2接高电平EN2使能,万用表测试约6.69V

JP7 ADDR 接GND 地址为0x60

JP8接GND

SCL、SDA 电路图上接上拉10K电阻,(但是很多地方说这个地方需要接 4.7K 电阻)

使用STM32F103ZET6做虚拟I2C

JP15中9SCL -- PB6   10SDA ---PB7  5VCC--3.3=3.3V  6GND---GND

以上为电路连接。

/*****************************************************************************

 * TPS65273V 输出 1.5V 最终程序 (I2C 地址 0x60, ADDR 接地)

 * LED 慢闪表示配置成功, 若电压仍为 0.99V, 请断开 FB1 外部电阻

 *****************************************************************************/

#include "stm32f10x.h"
#include <stdint.h>

/* 宏定义 ----------------------------------------------------------------*/
#define TPS65276V_ADDR      0x60    // 7位地址,ADDR=GND
#define TPS65276V_WRITE     (TPS65276V_ADDR << 1)      // 0xC0
#define TPS65276V_READ      ((TPS65276V_ADDR << 1) | 1) // 0xC1

/* 寄存器地址 */
#define REG_VOUT1_SEL       0x00
#define REG_VOUT1_COM       0x02
#define REG_SYS_STATUS      0x04
#define REG_VOUT2_SEL       0x01
#define REG_VOUT2_COM       0x03

/* 输出电压值*/
#define Out1mV  1500
#define Out2mV  1600

/* 延时函数(简单循环) */
static void delay_us(uint32_t us)
{
    uint32_t i;
    for (i = 0; i < us * 8; i++)   // 72MHz 下约 8 个循环 / us
        __NOP();
}
static void delay_ms(uint32_t ms)
{
    while (ms--)
        delay_us(1000);
}

/* I2C 底层操作函数 ------------------------------------------------*/
/**
 * @brief I2C1 初始化(时钟 100kHz)
 */
void I2C1_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    I2C_InitTypeDef I2C_InitStructure;

    /* 使能时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

    /* PB6 (SCL) 和 PB7 (SDA) 配置为复用开漏输出 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* I2C 配置 */
    I2C_DeInit(I2C1);
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x00;        // 作为主机,从机地址无关
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = 100000;       // 100kHz
    I2C_Init(I2C1, &I2C_InitStructure);
    I2C_Cmd(I2C1, ENABLE);
}

/**
 * @brief I2C 发送一个字节数据到设备(写寄存器)
 * @param dev_addr  设备写地址(8位)
 * @param reg       寄存器地址
 * @param data      要写入的数据
 * @retval 0 成功,1 失败
 */
uint8_t I2C1_WriteReg(uint8_t dev_addr, uint8_t reg, uint8_t data)
{
    /* 发送 START 条件 */
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  // EV5

    /* 发送设备地址 + 写位 */
    I2C_Send7bitAddress(I2C1, dev_addr, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); // EV6

    /* 发送寄存器地址 */
    I2C_SendData(I2C1, reg);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // EV8

    /* 发送数据 */
    I2C_SendData(I2C1, data);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // EV8

    /* 发送 STOP 条件 */
    I2C_GenerateSTOP(I2C1, ENABLE);
    return 0;
}

/**
 * @brief I2C 从设备读取一个字节(读寄存器)
 * @param dev_addr  设备读地址(8位)
 * @param reg       寄存器地址
 * @param pData     读出数据的存储指针
 * @retval 0 成功,1 失败
 */
uint8_t I2C1_ReadReg(uint8_t dev_addr, uint8_t reg, uint8_t *pData)
{
    /* 发送 START 条件 */
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

    /* 发送设备地址 + 写位(先写寄存器地址) */
    I2C_Send7bitAddress(I2C1, dev_addr & 0xFE, I2C_Direction_Transmitter); // 清除读位
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    /* 发送寄存器地址 */
    I2C_SendData(I2C1, reg);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    /* 重复 START 条件 */
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

    /* 发送设备地址 + 读位 */
    I2C_Send7bitAddress(I2C1, dev_addr, I2C_Direction_Receiver);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    /* 读一个字节,不发送应答 */
    I2C_AcknowledgeConfig(I2C1, DISABLE);  // 读最后一字节前禁止应答
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
    *pData = I2C_ReceiveData(I2C1);
    I2C_AcknowledgeConfig(I2C1, ENABLE);   // 恢复应答

    /* 发送 STOP 条件 */
    I2C_GenerateSTOP(I2C1, ENABLE);
    return 0;
}

uint8_t TPS65276V_CalcVID_FrommV(uint16_t target_mV)
{
    // 计算原始 VID 值:(mV - 680) / 10,带四舍五入(加5后整除10)
    int vid_raw = (target_mV - 680 + 5) / 10;
    
    // 限制范围
    if (vid_raw < 0) vid_raw = 0;
    if (vid_raw > 0x7F) vid_raw = 0x7F;
    
    // 设置 GO 位并返回
    return (uint8_t)(0x80 | vid_raw);
}
/* TPS65276V 相关操作函数 -----------------------------------------*/
/**
 * @brief 设置 Buck1 输出电压为 1.5V
 * @retval 0 成功,1 失败
 */
uint8_t TPS65276V_SetBuck1_Out1(void)
{
    // 1. 可选:配置 Vout1_COM(压摆率、模式)
    //   0x44 = 强制 PWM,10mV/16周期,输出使能
    if (I2C1_WriteReg(TPS65276V_WRITE, REG_VOUT1_COM, 0x44) != 0)
        return 1;
		
		uint8_t Out1 = TPS65276V_CalcVID_FrommV(Out1mV);
    // 2. 计算 VID 代码: (1.5 - 0.68) / 0.01 = 82 = 0x52
    //    GO 位 = 1,最终 0xD2
    if (I2C1_WriteReg(TPS65276V_WRITE, REG_VOUT1_SEL, Out1) != 0)
        return 1;

    // 3. 等待转换完成(简单延时)
    delay_ms(2);

    // 4. 读取状态(可选)
    uint8_t status;
    if (I2C1_ReadReg(TPS65276V_READ, REG_SYS_STATUS, &status) == 0)
    {
        if (status & 0x01) {
            // PGOOD1 正常
        }
    }
    return 0;
}

uint8_t TPS65276V_SetBuck2_Out2(void)
{
    // 1. 可选:配置 Vout1_COM(压摆率、模式)
    //   0x44 = 强制 PWM,10mV/16周期,输出使能
    if (I2C1_WriteReg(TPS65276V_WRITE, REG_VOUT2_COM, 0x44) != 0)
        return 1;
		uint8_t Out2 = TPS65276V_CalcVID_FrommV(Out2mV);
    // 2. 计算 VID 代码: (1.5 - 0.68) / 0.01 = 82 = 0x52
    //    GO 位 = 1,最终 0xD2
    if (I2C1_WriteReg(TPS65276V_WRITE, REG_VOUT2_SEL, Out2) != 0)
        return 1;

    // 3. 等待转换完成(简单延时)
    delay_ms(2);

    // 4. 读取状态(可选)
    uint8_t status;
    if (I2C1_ReadReg(TPS65276V_READ, REG_SYS_STATUS, &status) == 0)
    {
        if (status & 0x01) {
            // PGOOD1 正常
        }
    }
    return 0;
}
/* 主函数 ----------------------------------------------------------*/
int main(void)
{
    /* 系统时钟配置(使用外部晶振,72MHz) */
    SystemInit();     // 标准库提供的系统时钟初始化,默认 72MHz

    /* 初始化 I2C1 */
    I2C1_Init();

    /* 使能 EN1 和 EN2(若用 GPIO 控制,否则悬空即可) */
    // 此处假设 PA0 和 PA1 作为输出控制 EN1 和 EN2
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1);  // 使能芯片

    /* 等待芯片上电稳定 */
    delay_ms(10);

    /* 设置 Buck1 输出电压为 1.5V */
    TPS65276V_SetBuck1_Out1();
		TPS65276V_SetBuck2_Out2();
    
}

/* 需要实现的硬件错误处理函数(由标准外设库要求) */
void assert_failed(uint8_t* file, uint32_t line)
{
    while (1);
}

在本次提供的程序中,可以通过修改

/* 输出电压值*/

#define Out1mV  1500

#define Out2mV  1600

其中的Out1mV和Out2mV来实现输出控制。当前为1.5V。

在输出为1.5V,加1kΩ负载,可以测得输出电流为1.41mA(因为万用表测量有些许误差)。

例如使out1输出为1v,只需要把Out1mV  修改为1000即可。

全部回复(1)
正序查看
倒序查看
05-15 20:44

想录制个视频,有什么好的录制教程吗?

0
回复