主题中讨论的其他器件:DRV8323、 DRV8353
工具与软件:
您好!
我尝试在1xPWM 模式下使用 DRV8323驱动器并使用霍尔效应传感器来运行三相 BLDC 电机。 我还使用 Nucleo WB55RG 板来生成20kHz PWM 信号。
电机正在旋转、但存在可闻噪声、仅占空比降低50%。 此外、电机转速不随占空比的变化而变化。
INHC= HIGH
INLC = HIGH
INHA = PWM
INLA、INHB、INLB =霍尔传感器
ENABLE = HIGH
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.
工具与软件:
您好!
我尝试在1xPWM 模式下使用 DRV8323驱动器并使用霍尔效应传感器来运行三相 BLDC 电机。 我还使用 Nucleo WB55RG 板来生成20kHz PWM 信号。
电机正在旋转、但存在可闻噪声、仅占空比降低50%。 此外、电机转速不随占空比的变化而变化。
INHC= HIGH
INLC = HIGH
INHA = PWM
INLA、INHB、INLB =霍尔传感器
ENABLE = HIGH
您好、Jay:
是否使用 INHC 控制方向? 否则、它应该被接至低电平。
可闻噪声 有时可能源于不均匀的换向或低分辨率 PWM 信号。 您是否使用了20kHz 以外的任何其他 PWM 频率?
您是否已确认 霍尔传感器换向信号与电机相位完全对齐? 您还可以检查电源线上的电压或电流纹波?
对于占空比问题、您是否已确认 Nucleo 板实际上正在更新占空比?
此致、
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、
我附上了一个 PDF 文件、其中包含示波器上的输出测量结果
感谢您的支持
e2e.ti.com/.../7183.PHASE-VOLTAGE-_2600_-CURRENT.pdf
您好、Jay:
这可能是您的问题产生的原因。 我认为 EVM 上的 MOSFET 的 Qgd 为26nC、这意味着使用默认 IDRIVE (恰好是最高 IDRIVE 设置)可能会在输出端产生大量振铃、甚至会损坏驱动器或 MOSFET
以下是一个很好的常见问题解答、说明了 Qgd 和开关时间之间的关系、以及如何计算要使用的理想 IDRIVE 设置:
和下面的内容讨论了如何避免损坏(其中提到了 DRV8353、但仍然适用于该器件):
请使用这些资源计算适当的 IDRIVE 设置并进行相应的调整。
如果您可以在更改 IDRIVE 设置之前和之后提供 GHx 至 SHx、SHx 至 GND 和 GLx 至 GND 的放大图、那会非常好!
此致、
Yara