主题中讨论的其他器件: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