This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] BOOSTXL-DRV8323RS:1个 PWM 和放大器;梯形控制3相 BLDC

Guru**** 2392225 points
Other Parts Discussed in Thread: DRV8323, DRV8353

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/1463985/boostxl-drv8323rs-1xpwm-trapezoidal-control-3-phase-bldc

器件型号:BOOSTXL-DRV8323RS
主题中讨论的其他器件:DRV8323DRV8353

工具与软件:

您好!

我尝试在1xPWM 模式下使用 DRV8323驱动器并使用霍尔效应传感器来运行三相 BLDC 电机。 我还使用 Nucleo WB55RG 板来生成20kHz PWM 信号。

电机正在旋转、但存在可闻噪声、仅占空比降低50%。 此外、电机转速不随占空比的变化而变化。

INHC= HIGH

INLC = HIGH
INHA = PWM
INLA、INHB、INLB =霍尔传感器
ENABLE = HIGH

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jay:

    今天是美国的假日、但我们的目标是在一周结束前提供回复。

    此致、

    Anthony Lodi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jay:

    是否使用 INHC 控制方向? 否则、它应该被接至低电平。

    可闻噪声 有时可能源于不均匀的换向或低分辨率 PWM 信号。 您是否使用了20kHz 以外的任何其他 PWM 频率?

    您是否已确认 霍尔传感器换向信号与电机相位完全对齐? 您还可以检查电源线上的电压或电流纹波?

    对于占空比问题、您是否已确认 Nucleo 板实际上正在更新占空比?

    此致、

    Yara

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yara、

    我已将 INHC 引脚设置为高电平以控制电机方向、而霍尔传感器直接连接到电机驱动器。 占空比也在正确更新。

    但是、我怀疑我的 SPI 通信可能存在问题。 电机驱动器是需要使用 SPI 显式设置为1xPWM 模式、还是默认情况下处于1xPWM 模式?

    感谢您的帮助!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jay:

    感谢您提供更多信息!

    PWM 模式的默认 SPI 设置为6x PWM

    因此、如果您尝试在不配置 SPI 寄存器的情况下实现1xPWM、则很可能出现问题、修复后请告知您的结果。

    此致、

    Yara

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yara、

    我认为我的 SPI 配置有一个问题、因为当我尝试读回控制寄存器0x02时、它会发送一个数据:0x0000并且读取:0。 这是我的 SPI 配置

    SPI:

    static void MX_SPI1_Init(void)
    {
      hspi1.Instance = SPI1;
      hspi1.Init.Mode = SPI_MODE_MASTER;
      hspi1.Init.Direction = SPI_DIRECTION_2LINES;
      hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
      hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
      hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
      hspi1.Init.NSS = SPI_NSS_SOFT;
      hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
      hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
      hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
      hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
      hspi1.Init.CRCPolynomial = 7;
      hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
      hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
      if (HAL_SPI_Init(&hspi1) != HAL_OK)
      {
        Error_Handler();
      }
    
    }

    写入 SPI:

    void DRV8323_writeSpi(uint16_t regAdr, uint16_t regVal)
    {
        uint16_t controlword = ((regAdr << 11) | regVal);  // Create control word
    
        char debugMsg[50];
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
        HAL_StatusTypeDef status = HAL_SPI_Transmit(&hspi1, (uint8_t*)(&controlword), 1, 20);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
    
        HAL_Delay(90);  
        snprintf(debugMsg, sizeof(debugMsg), "Write Status: %d, Data: 0x%04X\r\n", status, controlword);
        HAL_UART_Transmit(&huart1, (uint8_t*)debugMsg, strlen(debugMsg), 1000);
    }

    读取 SPI:

    uint16_t DRV8323_readSpi(uint16_t regAdr)
    {
        uint16_t controlword =  (0x8000 | (regAdr << 11));  // Read command + address
        uint16_t recbuff = 0xbeef;
    
        char debugMsg[50];
    
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
        HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)(&controlword), (uint8_t*)(&recbuff), 1, 20);
     
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
    
        HAL_Delay(100);  
    
        snprintf(debugMsg, sizeof(debugMsg), "Read Status: %d, Received Data: 0x%04X\r\n", status, recbuff);
        HAL_UART_Transmit(&huart1, (uint8_t*)debugMsg, strlen(debugMsg), 1000);
    
        return (0x7FF & recbuff);  // Masking the lower 11 bits
    }
    
    

    配置电机:

    void configureMotorDriver(){

    uint16_t address = 0x02;//示例寄存器地址

    uint16_t value = 0x80;//基本值(以十六进制表示的默认寄存器配置)

    DRV8323_writeSpi (地址、值);//将配置写入电机驱动器

    }




  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jay:

    您是否能够读取所有寄存器? 当您执行该操作时、它会读回这些寄存器的默认值吗?

    如果能够从所有寄存器读回默认值、那是一个很好的开始! 如果您无法执行此操作、则可能会出现地址格式设置或访问地址方式方面的问题。

    使用地址0x02是测试写入 SPI 函数的好地址、因为该寄存器的默认值仅为0x0000。

    以下是我们通常用于通过 SPI 与器件通信的一些代码:

    void Config_evm_spi(void)
    {
        //Pin Config
        EALLOW;
        // SPI_MOSI
        GPIO_SetupPinOptions(16, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
        // SPI_MISO
        GPIO_SetupPinOptions(17, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
        // SPI_CS
        GPIO_SetupPinOptions(56, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
        // SPI_CLK
        GPIO_SetupPinOptions(57, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
    
        GPIO_SetupPinMux(16, GPIO_MUX_CPU1, 1);
        GPIO_SetupPinMux(17, GPIO_MUX_CPU1, 1);
        GPIO_SetupPinMux(56, GPIO_MUX_CPU1, 1);
        GPIO_SetupPinMux(57, GPIO_MUX_CPU1, 1);
        EDIS;
    
        EALLOW;
        ClkCfgRegs.LOSPCP.all = 0;
        EDIS;
    
        // Initialize SPI FIFO registers
        SpiaRegs.SPIFFTX.all=0xE040;
        SpiaRegs.SPIFFRX.all=0x2044;
        SpiaRegs.SPIFFCT.all=0x0;
    
        //SPI Settings
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;     //SPI Reset On
        SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;    //SCLK Active High
        SpiaRegs.SPICCR.bit.SPICHAR = 0x7;      //16-bit SPI char
        SpiaRegs.SPICCR.bit.SPILBK = 0;
    
        SpiaRegs.SPICTL.bit.OVERRUNINTENA = 0;  //No overrun interrupt
        SpiaRegs.SPICTL.bit.CLK_PHASE = 0;      //Phase 0
        SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;   //Master mode
        SpiaRegs.SPICTL.bit.TALK = 1;           //nSCS enabled
        SpiaRegs.SPICTL.bit.SPIINTENA = 0;      //TX/RX Interrupt Disabled
    
        SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = ((25000000 / 1000000) - 1);              //Set baud rate to 1MHz
        SpiaRegs.SPIPRI.bit.FREE = 1;           //Set so breakpoints don't disturb transmission
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;   //Exit SPI reset
    
    }
    
    Uint16 spi_xmit(Uint16 spiFrame)
    {
        SpiaRegs.SPITXBUF=spiFrame;
    
        //Wait for RX flag to indicate SPI frame completion
        while(SpiaRegs.SPIFFRX.bit.RXFFST != 1)
        {
        }
    
        return SpiaRegs.SPIRXBUF;
    }
    
    Uint16 spi_write(Uint16 addr, Uint16 data)
    {
        int i;
        Uint16 p_addr;
        Uint16 p_data;
        Uint16 commandword;
        Uint16 dummy;
    
        //8-bit header
        p_addr = spi_parity_calc(addr);
        commandword = ((addr << 1) & 0x7E)  | (p_addr << 0);
        SpiaRegs.SPITXBUF=commandword<<8; //transmit header
        dummy = SpiaRegs.SPIRXBUF;
    
    
        p_data = spi_parity_calc(data);
    
        //8 bit data1
        commandword = (p_data << 7) | ((data & 0x7F00) >> 8); //P + D14:D8
        SpiaRegs.SPITXBUF=commandword<<8; //transmit data
    
        //8 bit data2
        commandword = (data & 0x00FF);            //D7:D0
        SpiaRegs.SPITXBUF=commandword<<8;      //transmit data
        dummy = SpiaRegs.SPIRXBUF;
    
        while(SpiaRegs.SPIFFRX.bit.RXFFST != 3); //wait for 2 words to receive in FIFO
    
        return SpiaRegs.SPIRXBUF; //return last word
    }
    
    Uint16 spi_read(Uint16 addr)
    {
    
        Uint16 p_addr;
        Uint16 p_data;
        Uint16 commandword;
        Uint16 data, data1, data2;
        Uint16 dummy = 0xFF;
    
        //8-bit header
        p_addr = spi_parity_calc(addr);
        commandword = 0x80 | ((addr & 0x3F) << 1)  | (p_addr << 0);
        SpiaRegs.SPITXBUF=commandword<<8; //transmit header
        dummy = SpiaRegs.SPIRXBUF;
    
        p_data = spi_parity_calc(dummy);
    
    
        //8 bit data1
        commandword = ((p_data << 7) | dummy);
        SpiaRegs.SPITXBUF=commandword<<8; //transmit dummy
        data1 = SpiaRegs.SPIRXBUF;
    
        //8 bit data2
        commandword = 0xFF;
        SpiaRegs.SPITXBUF=commandword<<8;      //transmit dummy
        data2 = SpiaRegs.SPIRXBUF;
    
        while(SpiaRegs.SPIFFRX.bit.RXFFST != 3); //wait for 3 words to receive in FIFO
    
        dummy = SpiaRegs.SPIRXBUF;
        data1 = SpiaRegs.SPIRXBUF;          //read D14:D8
        data2 = SpiaRegs.SPIRXBUF;          //read D7:D0
    
        //while(SpiaRegs.SPIFFRX.bit.RXFFST != 3); //wait for 3 words to receive in FIFO
        data = (data1 << 8) | (data2); //concatenate D14:D0
        return data; //return D14:D0
    }
    
    bool spi_parity_calc(Uint16 word)   //calculates parity of word
    {
        uint16_t p = 0;
        while(word)
        {
           p ^= (word & 1);
           word >>= 1;
        }
        return(p);  //returns 0 or 1 for parity
    }

    您可以忽略奇偶校验位、因为 DRV8323具有一个。

    让我知道您的寄存器读取的结果。

    此致、

    Yara

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yara、

    即使我成功地在1xPWM 模式下写入 SPI 寄存器、该问题也不会解决、同时我使用示波器检查电机的相电压和电流。

    电机规格- 43V 250W BLDC



    单相电压 A  
    两相电压 B
    三相电压 C


    相电流 A

    相电流 B

    相电流 C

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jay:

    我无法访问 Google Drive。 请随时发布图像或附加 PDF、以便我查看您尝试分享的内容。

    此致、

    Yara

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yara、

    我附上了一个 PDF 文件、其中包含示波器上的输出测量结果

    感谢您的支持

    e2e.ti.com/.../7183.PHASE-VOLTAGE-_2600_-CURRENT.pdf

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jay:

    我认为您的波形没有任何不正确的地方。

    您的栅极驱动器设置是什么? 比如死区时间和 IDRIVE?

    此致、

    Yara

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yara、

    我没有配置死区时间、IDRIVE 处于默认配置

    感谢您的支持

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jay:

    这可能是您的问题产生的原因。 我认为 EVM 上的 MOSFET 的 Qgd 为26nC、这意味着使用默认 IDRIVE (恰好是最高 IDRIVE 设置)可能会在输出端产生大量振铃、甚至会损坏驱动器或 MOSFET

    以下是一个很好的常见问题解答、说明了 Qgd 和开关时间之间的关系、以及如何计算要使用的理想 IDRIVE 设置:

    https://e2e.ti.com/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/796378/faq-selecting-the-best-idrive-setting-and-why-this-is-essential

    和下面的内容讨论了如何避免损坏(其中提到了 DRV8353、但仍然适用于该器件):

    https://e2e.ti.com/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/1236302/faq-drv8353rs-evm-how-to-avoid-damaging-your-drv8353rx-evm-with-too-high-idrive

    请使用这些资源计算适当的 IDRIVE 设置并进行相应的调整。  

    如果您可以在更改 IDRIVE 设置之前和之后提供 GHx 至 SHx、SHx 至 GND 和 GLx 至 GND 的放大图、那会非常好!

    此致、

    Yara