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.

DRV8306: Artifacts in DRV output

Part Number: DRV8306

Tool/software:

Hello TI Community,

I'm currently working on a BLDC motor control project using the DRV8306. The motor has hall sensors for feedback.

However, I'm facing some issues:

  • The output waveform is distorted; it's not a clean trapezoidal shape.

  • The motor heats up after a short time of operation and emits a noticeable high-pitched whine.

I'm suspecting there might be a misconfiguration in either hardware or software.

I'll be attaching the following for your reference:

  1. Code that handles the hall sensor reading and commutation logic

  2. Schematic of the custom board connected to the DRV8306

  3. Osciloscope images of the output phases and hall sensor readings.

I have tried a different motor with the same specs, and the noise goes away on a proprietary board that came with the motor. On both the only signals I'm providing from the MCU is the PWM and Enable signal.

Unfortunately I only have a two-channel osciloscope, so I couldn't see all the hall sensors and phases on the same image. It would be highly appreciated if someone could enlighten me on some possible causes. Thanks in advance for your help!

Phase A and hall A:

phase A

Phase B and hall B:

Phase C and hall C

PWM Wave sent to the DRV:

Code:

#include <msp430.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>

#define ACLK		32768					// Frequência do ACLK 32,768 KHz
#define SMCLK		24000000				// Frequência do SMCLK 24 MHz


const uint8_t tb_div[][3] =	{	{1, 0, 0}, {2, 0, 1}, {3, 0, 2}, {4, 0, 3}, {5, 0, 4}, {6, 0, 5}, {7, 0, 6}, {8, 0, 7},
								{10, 1, 4}, {12, 1, 5}, {14, 1, 6}, {16, 1, 7}, {20, 2, 4}, {24, 2, 5}, {28, 2, 6},
								{32, 2, 7}, {40, 3, 4}, {48, 3, 5}, {56, 3, 6}, {64, 3, 7}, {0, 0, 0}};


bool blower_init(uint16_t pwm_frq);
void blower_set_dty (uint16_t dty);

int main(void)
{
    uint16_t flag = 0;
    uint16_t lng, dty = 5000,i=0;
    WDTCTL = WDTPW | WDTHOLD;               // Stop watchdog timer

    // S01 - Inicializa��o do Sistema: Clocks e PMM
    WDTCTL = WDTPW | WDTHOLD;                       // P�ra o Watchdog Timer
    FRCTL0 = FRCTLPW | NWAITS_2;                    // Configura 2 wait state para FRAM, pois MCLK ser� configurado em 24 MHz

    P2SEL0 &= ~(BIT7 | BIT6);                       // Configura P2.6 como XOUT e P2.7 como XIN
    P2SEL1 |= (BIT7 | BIT6);                        // P2.6:P2SELx = 10b, P2.7:P2SELx = 10b
    do{
        CSCTL7 &= ~(XT1OFFG | DCOFFG);              // Limpa flags de falha de XT1 e DCO
        SFRIFG1 &= ~OFIFG;                          // Limpa flag de interrup��o por falha de oscilador
    }while (SFRIFG1 & OFIFG);                       // Aguarda at� a flag de falha de oscilador ser limpa

    __bis_SR_register(SCG0);                        // Desabilita FLL

    CSCTL3 |= SELREF__XT1CLK;                       // Define XT1 como refer�ncia de clock para FLL
    CSCTL0 = 0;                                     // Inicializa CSCTL0.MOD = 00000b, pois o FLL ir� ajustar esses bits automaticamente
                                                    // Inicializa CSCTL0.DCO = 000000000b, pois o FLL ir� selecionar o tap do DCO automaticamente
    CSCTL1 &= ~(DCORSEL_7);                         // Primeiramente faz CSTL1.DCOR_SEL = 000b
    CSCTL1 |= DCORSEL_7;                            // Seta CSCTL1.DCOR_SEL = 110b: DCO = 24 MHz
    CSCTL2 = FLLD_0 + 731;                          // Configura CSCTL2.FLLD = 000b, seleciona divisor do FLL loop como fdcoclock + 1
                                                    // Configura CSCTL2.FLLN = 731, desta forma a frequencia do DCO ser� REFO = 32.768 Hz x (731 + 1) = 23.986.176 Hz ~ 24 MHz
    __delay_cycles(3);                              // Espera 3 ciclos de clock
    __bic_SR_register(SCG0);                        // Habilita FLL
    while (CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1));     // Espera FLL locked que ocorre quando CSCTL7.FLLUNLOCK = 00b

    CSCTL4 = SELA__XT1CLK | SELMS__DCOCLKDIV;       // Configura CSCTL4.SELA = 00b, escolhe XT1 como refer�ncia de clock para ACLK. Ent�o ACLK = 32.768 Hz
                                                    // Configura CSCTL4.SELMS = 000b, escolhe DCO como refer�ncia de clock para MCLK e SMCLK
    PM5CTL0 &= ~LOCKLPM5;                           // Desabilita o estado default de alta imp�d�ncia dos pinos de GPIO no power-on

    // S02 - Define regi�o da FRAM sem prote��o
    SYSCFG0 = 0xA51F;                               // SYSCFG0.FRWPPW = 0xA5:
                                                    // SYSCFG0.FRWPOA = 7: Seleciona 7 KB do in�cio da FRAM para DEV (1 KB) e DAT (6 KB) serem usados como RAM
                                                    // SYSCFG0.DFWP = 1:
                                                    // SYSCFG0.PFWP = 1

    P1DIR  = 0x00;                                  // Configura P1DIR conforme coment�rio acima
    P1SEL0 = 0xFF;                                  // Configura P1SEL0 conforme coment�rio acima
    P1SEL1 = 0xFF;                                  // Configura P1SEL1 conforme coment�rio acima
    P1OUT  = 0x00;                                  // Configura P1OUT conforme coment�rio acima
    P1REN  = 0x00;                                  // Configura P1REN conforme coment�rio acima

    P2DIR  = 0x3D;                                  // Configura P2DIR conforme coment�rio acima
    P2SEL0 = 0x01;                                  // Configura P2SEL0 conforme coment�rio acima
    P2SEL1 = 0xC0;                                  // Configura P2SEL1 conforme coment�rio acima
    P2OUT  = 0x00;                                  // Configura P2OUT conforme coment�rio acima
    P2REN  = 0x00;                                  // Configura P2REN conforme coment�rio acima

    P3DIR  = 0x11;                                  // Configura P3DIR conforme coment�rio acima
    P3SEL0 = 0xEE;                                  // Configura P3SEL0 conforme coment�rio acima
    P3SEL1 = 0xEE;                                  // Configura P3SEL1 conforme coment�rio acima
    P3OUT  = 0x00;                                  // Configura P3OUT conforme coment�rio acima
    P3REN  = 0x00;                                  // Configura P3REN conforme coment�rio acima

    P4DIR  = 0x01;                                  // Configura P4DIR conforme coment�rio acima
    P4SEL0 = 0x0C;                                  // Configura P4SEL0 conforme coment�rio acima
    P4SEL1 = 0x00;                                  // Configura P4SEL1 conforme coment�rio acima
    P4OUT  = 0x00;                                  // Configura P4OUT conforme coment�rio acima
    P4REN  = 0x00;                                  // Configura P4REN conforme coment�rio acima

    P5DIR  = 0x00;                                  // Configura P5DIR conforme coment�rio acima
    P5SEL0 = 0x03;                                  // Configura P5SEL0 conforme coment�rio acima
    P5SEL1 = 0x03;                                  // Configura P5SEL1 conforme coment�rio acima
    P5OUT  = 0x00;                                  // Configura P5OUT conforme coment�rio acima
    P5REN  = 0x00;                                  // Configura P5REN conforme coment�rio acima

    P6DIR  = 0x03;                                  // Configura P6DIR conforme coment�rio acima
    P6SEL0 = 0x03;                                  // Configura P6SEL0 conforme coment�rio acima
    P6SEL1 = 0x00;                                  // Configura P6SEL1 conforme coment�rio acima
    P6OUT  = 0x00;                                  // Configura P6OUT conforme coment�rio acima
    P6REN  = 0x00;                                  // Configura P6REN conforme coment�rio acima


    
    PM5CTL0 &= ~LOCKLPM5;                   // Disable the GPIO power-on default high-impedance mode
                                            // to activate previously configured port settings
    TB0CCTL0 = 0x0010;     // Habilita interrupção para CCR0
    TB0CCR0 = 32768 - 1;   // Define período de 32768 para que ocorra
    TB0CTL = 0x0110;       // TBCLGRP = 00b: Cada TBxCLn é armazenado independentemente (sem agrupamento);
                           // CNTL = 00b: Contador de 16 bits;
                           // TBSSEL = 01b: Utiliza ACLK = 32768 Hz como clock source;
                           // ID = 00b: Divide clock source por 1;
                           // MC = 01b: Modo de contagem UP;
                           // TBCLR = 0: Timer clear;
                           // TBIE = 0: Habilita interrupção;
                           // TBIFG = 0: Limpa interrupção pendente




    TB2CTL = 0x01E4;        // TBCLGRP = 00b: Cada TBxCLn é armazenado independentemente (sem agrupamento);
                            // CNTL = 00b: Contador de 16 bits;
                            // TBSSEL = 01b: Utiliza ACLK = 32768 Hz como clock source;
                            // ID = 11b: Divide clock source por 8, fazendo TB1CLK = ACLK / 8 = 4096Hz;
                            // MC = 10b: Modo de contagem CONTINUOS_MODE;
                            // TBCLR = 1: Timer clear;
                            // TBIE = 0: Desabilita interrupção;
                            // TBIFG = 0: Inrrelevante, pois não será utilizado interrupção para o timer
    TB2EX0 = 0x0003;        // TBIDEX = 011b: Divide o clock de 4096 Hz do divisor ID, por 4, obtendo um clock de 1024 Hz.


    TB3CTL = 0x02E6;       // TBCLGRP = 00b: Cada TBxCLn é armazenado independentemente (sem agrupamento);
                           // CNTL = 00b: Contador de 16 bits;
                           // TBSSEL = 10b: Utiliza SMCLK = 24 MHz como clock source;
                           // ID = 11b: Divide clock source por 8;
                           // MC = 10b: Modo de contagem Continuous;
                           // TBCLR = 1: Timer clear;
                           // TBIE = 1: Habilita interrupção;
                           // TBIFG = 0: Limpa interrupção pendente
   TB3EX0 = 0x0002;        // TBIDEX = 010b: Divide o clock de 3 MHz do divisor ID, por 3, obtendo um clock de 1 MHz.

    __enable_interrupt();

    blower_init(3000);


    while(1){
        blower_set_dty(dty);
        __delay_cycles(120000000);
        dty=0;
    }
}


/*
 * Fun��o que calcula a rota��o do motor para libera��o autom�tica
 * Par�metro de entrada:
 * uint16_t fgt_spd: velocidade de v�o, onde 1 = 0.1 Km/h
 * A fun��o retorna o valor de RPM que o motor deve girar para atender a taxa de aplica��o
 */
bool blower_init(uint16_t pwm_frq) {
    uint8_t i = 0;
    uint32_t hig, low;

    P2OUT |= BIT3; // Enable the blower control pin

    while (tb_div[i][0] != 0) { // Loop until the end of the tb_div table
        hig = SMCLK / tb_div[i][0]; // Calculate the highest frequency for the current divider
        low = hig / 65536;          // Calculate the lowest frequency for the current divider

        if (pwm_frq >= low) { // Check if the desired PWM frequency is within range
            uint32_t aux = hig / pwm_frq; // Calculate the period count for the desired frequency

            // Configure TB1
            TB1CCR0 = (uint16_t)aux;      // Set the period
            TB1CCTL1 = OUTMOD_7;          // Set output mode to Reset/Set
            TB1CCR1 = 0;                  // Initialize duty cycle to 0
            TB1CTL = TBCLR | TBSSEL__SMCLK | MC__UP | tb_div[i][1]; // Configure TB1CTL directly

            // Configure TB3
            TB3CCR0 = (uint16_t)aux;      // Set the period
            TB3CCTL1 = OUTMOD_7;          // Set output mode to Reset/Set
            TB3CCR1 = 0;                  // Initialize duty cycle to 0
            TB3CTL = TBCLR | TBSSEL__SMCLK | MC__UP | tb_div[i][1]; // Configure TB3CTL directly

            // Configure TB1EX0 and TB3EX0 for extended divider
            TB1EX0 = tb_div[i][2];
            TB3EX0 = tb_div[i][2];

            return true; // Successfully configured
        }

        i++; // Move to the next divider in the table
    }

    return false; // Failed to configure
}

void blower_set_dty (uint16_t dty){

	uint32_t aux;			// Vari�vel auxiliar para determinar valor da contagem do per�odo

	if (dty > 0){			// Verifica se o duty � positivo
		if (dty > 10000){	// Se sim, verifica se o duty � maior que 100%
			dty = 10000;	// Se for, limita em 100%
		}
		aux = dty;			// Carrega o valor do duty
		aux *= TB1CCR0;		// Multiplica pelo valor do per�odo
		aux /= 10000;		// Divide o resultado por 100%
		TB1CCR1 = (uint16_t) aux;	// Carrega o valor da contagem do per�odo
        aux = dty;          // Carrega o valor do duty
        aux *= TB3CCR0;     // Multiplica pelo valor do per�odo
        aux /= 10000;       // Divide o resultado por 100%
        TB3CCR1 = (uint16_t) aux;   // Carrega o valor da contagem do per�odo
		P4OUT |= BIT0;		// Habilita o blower
		P3OUT &= ~BIT0;
	}
	else{					// Para o motor
		TB1CCR1 = 0;		// Configura o duty cycle = 0
		TB3CCR1 = 0;
		P4OUT &= ~BIT0;			// Desabilita o blower
		P3OUT |= BIT0;         // Desabilita o blower
	}
}

Video of the noise:

Board Diagram:

Blower_R1.pdf

  • Thanks for your question! The team will aim to provide a response this week.

    Regards,

    Anthony Lodi

  • Hi Daniel,

    Thank you for reaching out.

    I am wondering if you are able to try a lower IDRIVE setting and see if the issue persists. I reviewed your schematic and noticed that you are using the highest IDRIVE setting. I would like to see if this is what is causing the issue.

    Thank you,

    Joseph

  • Hello, Joseph. I'm sorry for the late reply, it took a while to modify the board. Unfortunately, I didn't see any improvements when changing the IDRIVE setting, I tried all 7 settings from the datasheet, I couldn't notice major changes in the waveform.

  • Hi Daniel,

    Thanks for the update. 

    There are two concerning aspects of the initial waveforms you posted.

    First, there is a period of time on all 3 phases where no switching seems to be happening, and the voltage stays constant

    Second, there is no sign of back EMF on your phase C, as seen in your A and B phase (example seen below).

    Another thing that looks incorrect about the waveforms on A and B is that it looks like they are switching before they should:

    Ideally, I would like to see all three phases and halls in the same capture, but I understand the limitation here.

    The next thing I would like to look at is your input waveforms.

    My guess is that the issue may be in software, I reviewed your schematic and I did not see any immediate hardware issues there.

    Input signal waveforms that may help since you only have 2 channels:

    1. Hall x, INHx

    2. INHx, INLx

    Thank you,

    Joseph

  • These are the waves with their respective sensors (the sensor wave is below in the graph). I'm trying to obtain a bigger osciloscope to understand the behavior with all the waves on it.

  • Hi Daniel,

    I realize now that you mentioned before:

    I have tried a different motor with the same specs, and the noise goes away on a proprietary board that came with the motor. On both the only signals I'm providing from the MCU is the PWM and Enable signal.

    Can you provide the same waveforms from the other working board, which does not have the noise present?

    I would like to see this to compare. If the waveforms look good on the other proprietary board, and MCU inputs are the same on both boards, then maybe I can confirm the software is not the issue.

    You also mentioned in the same quote that you tried a different motor.. The noise is present with both motors?

    Thank you,

    Joseph

  • Hi Joseph,

    The waveform on the proprietary board looks really good. The interface is the same as with the DRV, I provide a PWM and enable signal. They all look like this:

    Yes, the noise continues with both motors. It is the same high pitched noise. 

  • Hi Daniel,

    Thanks for the waveform, since the inputs to both boards are the same then we can look deeper into the hardware

    Are you able to remove C25, C26, C27 on your board? Since you seem to be using single ended hall sensors, I'm wondering if these capacitors may be causing an issue

    Thanks,

    Joseph

  • Hi Joseph, 

    I removed the caps and the noise got noticeably better! Thank you for the support. I have performed a few tests for temperature and other mectrics and everything seems great now.

    Best regards!

  • Hi Daniel,

    No problem! I'm glad I could help.

    I will go ahead and close this thread now.

    Thanks again,

    Joseph