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.

DRV8305: Some problem while driving BLDC motor using DRV8305 and MSP430G2553.

Part Number: DRV8305
Other Parts Discussed in Thread: MSP430G2553,

Hello sir,

I have used DRV8305 and an MSP430G2553 controller to drive BLDC. 

It runs almost perfectly but at some point of time BLDC motor internally make a sound for a second and that time waveform of Phase of U, V and W also get disturbed. This process is repeated but that is not at regular interval. 

In my circuit, I have convert  BLDC's hall sensor's 5V signal to 3.3V by using TXB0104PW.  This is the image of that hall sensor circuit.

Below is code which I have taken from reference code for the one of TI reference design.

***********************************************************************************

// System Configuration
// Device Part Number	: MSP430G2553
// compiler             : Code Composer Studio 5.5.0.00077
// Oscillator Frequency	: 16MHz,  using internal DCO
// PWM generation		: TIMER A1.2, 16MHz, OUTMOD[2:0]= 2,PWM for High Side FETs
//						: TIMER A1.1, 16MHz, OUTMOD[2:0]= 6,PWM For Low side FEts
//
// Position Feedback    : Hall sensors signals
//				HA -> P2.0
//				HB -> P2.7
//				HC -> P2.6

//DRV8305
//SPI Communication		: SDO -> P1.1
//				: SDI -> P1.2
//				: SCLK -> P3.4
//				: SCS ->P3.5

//Fault Control			: EN_GATE -> P3.6
//				: FAULT ->P2.3
****************************************************************************************************/

#include <msp430.h>
#include <stdint.h>
#include "drv8305.h"

void Init_Clocks ();
void Init_IOs (void);
void Init_ADC (void);
void Init_Timer (void);
void Init_COMP_A (void);
void Hall_State_Change_FORWARD(void);
void Hall_State_Change_REVERSE(void);
void A_PWM(void);
void B_PWM(void);
void C_PWM(void);
void A_LOW(void);
void B_LOW(void);
void C_LOW(void);
void A_Z(void);
void B_Z(void);
void C_Z(void);
void Readfault(void);
#define 		PWM_PERIOD				400   //PWM Frequency (Hz) = 16MHz/((2*PWM_PERIOD)-1)
#define 		MAX_DUTYCYCLE				400   //relative to PWM_PERIOD
#define 		MIN_DUTYCYCLE				50    //relative to PWM_PERIOD
#define 		ACCEL_RATE				500   //Ramp up time to full scale duty cycle = (Full scale duty cycle) * ACCEL_RATE * PWM_PERIOD/PWM_Frequency
#define         DEAD_TIME					1     // Dead time from MSP430 = DEAD_TIME* 0.0625 uS (for 16MHz clock)
#define         Block_Rotor_Duration		             30000    //Blocked_rotor shut off time (s) = Block_Rotor_Duration*30000/Timer clock frequency
#define         WantedDutyCycle                               390     //Wanted Duty Cycle
//unsigned int DC_BUS_CURRENT = 0;
//unsigned int DC_Bus_Voltage = 0;
unsigned int SPEED_REF = 0;
//unsigned int Temperature_feedback = 0;
//unsigned int start_count =0;
volatile unsigned int HALL_STATE = 0;
volatile unsigned int softstart_counter = 0;
//unsigned int WantedDutyCycle = 390;
volatile unsigned int CurrentDutyCycle =30;
volatile unsigned int DIRECTION=0  ;
//unsigned int FirstADC_flag =1;
//unsigned int ADC_selection_flag = 1;
//unsigned int ADC_selection_flag_1 =1;
unsigned int Block_Rotor_Counter = 0;
unsigned int Block_Rotor_Counter_1 =0;
unsigned int  addr1, addr2, addr3, addr4;

/*******************************ADC channel selection*******************************************/

#define MEASURE_SPEED()		{	ADC10CTL0 = ADC10SHT_1 + ADC10IE + ADC10ON;             	\
		  	  	  	  	  	  	ADC10CTL1 = INCH_3 + CONSEQ_0 + SHS_0;						\
		  	  	  	  	  	  	ADC10AE0  = BIT3;	}
/*
#define MEASURE_TEMP()		{	ADC10CTL0 = ADC10SHT_1 + ADC10IE + ADC10ON;       			\
		  	  	  	  	  	  	ADC10CTL1 = INCH_4 + CONSEQ_0  + SHS_0;						\
		  	  	  	  	  	  	ADC10AE0  = BIT4;	}

#define MEASURE_VDC()		{   ADC10CTL0 = ADC10SHT_1 + ADC10IE + ADC10ON;             	\
		 	 	 	 	 	 	ADC10CTL1 = INCH_5 + CONSEQ_0  + SHS_0;						\
		 	 	 	 	 	 	ADC10AE0  = BIT5;	}

#define MEASURE_IDC()		{   ADC10CTL0 = ADC10SHT_1 + ADC10IE + ADC10ON;          		\
		  	  	  	  	  	  	ADC10CTL1 = INCH_6 + CONSEQ_0 + SHS_0;						\
		  	  	  	  	  	  	ADC10AE0  = BIT6;	}
*/
#define CONVERSION_ENABLE()	{   ADC10CTL0 |= ENC + ADC10SC;   }

#define CONVERSION_DISABLE() {  ADC10CTL0 &= ~ENC;								    		\
								ADC10CTL1 = 0;	   }

/*******************************Main************************************************************/
void main()
{
	WDTCTL = WDTPW + WDTHOLD;				// Stop watch-dog timer to prevent time out reset
	Init_Clocks();
	Init_IOs();
	drv8305_init();
	A_Z();
	B_Z();
	C_Z();
	if((P2IN & BIT3) == 0)
	{
		ReadRegister(0x01);
		ReadRegister(0x02);
		ReadRegister(0x03);
		ReadRegister(0x04);
		//Readfault();
	}
	P3OUT |= BIT6;
	Init_ADC();
//	Init_COMP_A ();
	Init_Timer();
	WDTCTL = WDTPW + WDTHOLD;				// Stop watch-dog timer to prevent time out reset
	__delay_cycles(1000000);
	HALL_STATE = (P2IN & BIT0) + ((P2IN & BIT6)>>4) + ((P2IN & BIT7)>>6);
	//DIRECTION =  (P3IN & BIT0);
	DIRECTION=0;
	P3OUT |= BIT1;

	while(1)
		{
			if(DIRECTION == 1)
			{
				Hall_State_Change_FORWARD();
			}
			else
			{
				Hall_State_Change_REVERSE();
			}


			if(softstart_counter == ACCEL_RATE)
			{
				softstart_counter = 0;

				if((P3IN & BIT0) == 1)
				{
					if ( CurrentDutyCycle < WantedDutyCycle )
					{
						CurrentDutyCycle++;
					}
				}
				if((P3IN & BIT0)==0)
				{
					if (CurrentDutyCycle >= 10)
					{
						CurrentDutyCycle--;
					}
				}
			}

		}
}

/**************************Initializing ADC***********************************************/
void Init_ADC(void)
{
    ADC10CTL0 = ADC10SHT_0 + ADC10ON + ADC10IE; // ADC10ON, interrupt enabled
    ADC10CTL1 = INCH_3;                         //
}

/**************************Initializing GPIOs***********************************************/
void Init_IOs (void)

{
	//Hall Sensor inputs

	P2SEL &= ~(BIT0+BIT6+BIT7);						//GPIO - Hall sensors
	P2DIR &= ~(BIT0+BIT6+BIT7);						//Inputs - Hall sensors

	//PWM outputs

	P2SEL |= (BIT1+BIT2+BIT4+BIT5);					//GPIO-PWM
	P2DIR |= (BIT1+BIT2+BIT4+BIT5);					//Output-PWM
	P3SEL |= (BIT2+BIT3);							//GPIO-PWM
	P3DIR |= (BIT2+BIT3);							//OutputPWM

	//P3SEL |= BIT7;
	//P3DIR |= BIT7;									//CAOUT

	P3SEL &= ~(BIT7);
	P3DIR |= BIT7;									//LED1


	//DRV8305
	P2SEL &= ~(BIT3);								//GPIO - FAULT
	P2DIR &= ~(BIT3);								//Inputs - FAULT
	//P3SEL |= (BIT6);								//GPIO-EN_GATE

	P3DIR |= (BIT6);								//Output - EN_GATE
//	P3OUT |= BIT6;
	//DRV8305-SPI communication
	P1DIR |= BIT7;									//GPIO-SDI
	P1OUT &= ~BIT7;									//Output-SDI
	P1DIR &= ~BIT6;									//SDO
	P3DIR |= BIT4;	//SCLK
	P3OUT &= ~BIT4;
	P3DIR |= BIT5;	//nSCS
	P3OUT |= BIT5;

	//Indications
	P3SEL &= ~ (BIT1);								//GPIO-LED3
	P3DIR |= (BIT1);								//Output-LED3

	//Direction Control
	P3SEL &= ~(BIT0);								//GPIO - DIR
	P3DIR &= ~(BIT0);								//Input - DIR

	//Enable edge interrupt for Hall sensor ports
	P2IES |= (BIT0)+(BIT6)+(BIT7);					// EDGE DETECTION   High = Falling Edge, Low = Rising Edge
	P2IFG &= (~BIT0)+(~BIT6)+(~BIT7); 				// Pin 2.0, 2.6, and 2.7 IFG cleared
	P2IE |=  (BIT0)+(BIT6)+(BIT7) ; 				// Enable Interrupt on Input Pin 2.2, 2.3, and 2.4
	__enable_interrupt();

}

/**************************Initializing Timer***********************************************/
void Init_Timer (void)
{
	TA1CCR0		= PWM_PERIOD;							// Load the Reference Count
	TA1CCTL2	= OUTMOD_2;								//High Side PWM
	TA1CCR2		= 50;
	TA1CCTL1	= OUTMOD_6;								//Low Side PWM
	TA1CCR1		= 50;									//Initialized with zero
	TA1CTL		= TASSEL_2 + MC_3 + TACLR +TAIE ;		//Up-Down Mode , SMCLK , Timer Clear; Timer Interrupt ON

	//TA1CCTL0	= CCIE;

	WDTCTL 		= WDT_MDLY_32;					// approx 2ms interval
	IE1 		|= WDTIE;                       // enable WDT interrupt
	_EINT();                              		// Enable interrupts
}

/**************************Initializing Clock***********************************************/
void Init_Clocks (void)
{
	BCSCTL1		= CALBC1_16MHZ;               	// Set DCO ~ 16 Mhz
	DCOCTL		= CALDCO_16MHZ;
	BCSCTL1 	|= DIVA_1;                    	// ACLK/(0:1,1:2,2:4,3:8)
	BCSCTL3 	|= LFXT1S_2;                  	// LFXT1 = VLO
}



/**************************Port (hall sensor) Interrupt service routine***********************************************/

#pragma vector=PORT2_VECTOR
__interrupt void    Port_2(void)

{
		HALL_STATE = (P2IN & BIT0) + ((P2IN & BIT6)>>4) + ((P2IN & BIT7)>>6);


		if(DIRECTION == 1)
		{
			Hall_State_Change_FORWARD();
		}
		else
		{
			Hall_State_Change_REVERSE();
		}


		P2IES ^= (BIT0)+(BIT6)+(BIT7);      // change the hall interrupt to falling edge to detect both the edges
		P2IFG &= (~BIT0)+(~BIT6)+(~BIT7);	// Clear Interrupt Flag

}

/**************************Timer Interrupt vector***********************************************/
#pragma vector = TIMER1_A1_VECTOR
__interrupt void TIMER1_A1_ISR (void)
{


  switch(__even_in_range(TA1IV,0x0A))
  {
  	  case  TA1IV_NONE: break;              // Vector  0:  No interrupt
      case  TA1IV_TACCR1: break;            // Vector  2:  TACCR1 CCIFG
      case TA1IV_TACCR2: break;             // Vector  4:  TACCR2 CCIFG
      case TA1IV_6: break;                  // Vector  6:  Reserved CCIFG
      case TA1IV_8: break;                  // Vector  8:  Reserved CCIFG
      case TA1IV_TAIFG:              		// Vector 10:  TAIFG


   // 	  	TA1CCR2		= (CurrentDutyCycle);
   // 		TA1CCR1		= CurrentDutyCycle;

    		TA1CCR2		= (CurrentDutyCycle -DEAD_TIME );
    		TA1CCR1		= CurrentDutyCycle;

    		if((P2IN & BIT3) == 0)
    		{						
    			P3OUT &= ~(BIT6);								
    			Readfault();             
    		}


      break;


      default: 	break;
  }
}


/**************************ADC INTERRUPT***********************************************/
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{


	 SPEED_REF = (ADC10MEM>>1);
	 CONVERSION_DISABLE();

  }

/**************************Commutation sequence Forward***********************************************/
void Hall_State_Change_FORWARD(void)
{

			switch (HALL_STATE)
			{
				case 2:
						A_PWM();
						B_LOW();
						C_Z();

				break;

				case 6:
						A_PWM();
						C_LOW();
						B_Z();

					break;

				case 3:
						C_PWM();
						B_LOW();
						A_Z();

						break;
				case 1:
						C_PWM();
						A_LOW();
						B_Z();

						break;

				case 4:
						B_PWM();
						C_LOW();
						A_Z();

						break;

				case 5:
						B_PWM();
						A_LOW();
						C_Z();

						break;


				default:
					A_Z();
					B_Z();
					C_Z();

					break;
			}


}
/**************************Commutation sequence Reverse***********************************************/
void Hall_State_Change_REVERSE(void)
{

			switch (HALL_STATE)
			{
				case 2:
						B_PWM();
						A_LOW();
						C_Z();

				break;

				case 6:
						C_PWM();
						A_LOW();
						B_Z();

					break;

				case 3:
						B_PWM();
						C_LOW();
						A_Z();

						break;
				case 1:
						A_PWM();
						C_LOW();
						B_Z();

						break;

				case 4:
						C_PWM();
						B_LOW();
						A_Z();

						break;

				case 5:
						A_PWM();
						B_LOW();
						C_Z();

						break;


				default:
					A_Z();
					B_Z();
					C_Z();

					break;
			}


}

/**************************Definition of PWM GPIOs***********************************************/

void A_PWM(void)

{
	P3SEL |= BIT3;
	P3SEL |= BIT2;

}


void B_PWM(void)

{
	P2SEL |= BIT4;
	P2SEL |= BIT2;

}

void C_PWM(void)

{
	P2SEL |= BIT5;
	P2SEL |= BIT1;

}

void A_LOW(void)
{
	P3SEL &= ~BIT3;
	P3OUT &= ~BIT3;
	P3SEL &= ~BIT2;
	P3OUT |= BIT2;
}

void B_LOW(void)
{
	P2SEL &= ~BIT4;
	P2OUT &= ~BIT4;
	P2SEL &= ~BIT2;
	P2OUT |= BIT2;
}

void C_LOW(void)
{
	P2SEL &= ~BIT5;
	P2OUT &= ~BIT5;
	P2SEL &= ~BIT1;
	P2OUT |= BIT1;
}

void A_Z(void)
{
	P3SEL &= ~BIT3;
	P3OUT &= ~BIT3;
	P3SEL &= ~BIT2;
	P3OUT &= ~BIT2;
}

void B_Z(void)
{
	P2SEL &= ~BIT4;
	P2OUT &= ~BIT4;
	P2SEL &= ~BIT2;
	P2OUT &= ~BIT2;
}

void C_Z(void)
{
	P2SEL &= ~BIT5;
	P2OUT &= ~BIT5;
	P2SEL &= ~BIT1;
	P2OUT &= ~BIT1;
}

void Readfault(void)
{

	addr1 = ReadRegister(0x01);
	addr2 = ReadRegister(0x02);
	addr3 = ReadRegister(0x03);
	addr4 = ReadRegister(0x04);

}
/**************************End****************************************************************/


So please help me for this. You can point out a error in code also. 

Thank you. 

Best Regards,

DINESH JINJALA

  • Hi Dinesh,

    Have you examined the hall pins when the disturbance occurs? This should help you determine if the disturbance is due to incorrect hall information or an incorrect commutation sequence. If the hall information is correct, the code should be further examined.

    Changing the LED to toggle and monitoring the LED can provide information if the code is running as expected. This can help determine if there is some interaction between the main code and the interrupts.
  • Thank you. 

    Below are some problems which I face while doing experiment with Motor.

    1.  In REVERSE (clockwise) direction It works fine (Very less amount of jerk in a motor) but when I load motor through my hand, It started to make a small sound (Results in displacement from its position). 

    2.  In FORWARD (Anti-clockwise) direction, It starts to make sound from starting.

    Yellow is a graph for the Phase U and blue is a graph for the Phase W.

    3. When I try to measure a hall sensor signals (After those signal converted in 3.3V signal through TXB0104PW), In REVERSE mode also it starts to make sound without no load.  

  • Hi Dinesh,

    It is difficult to determine what is occurring without the hall inputs and the other phase.

    Please focus on the circled area if possible. It appears there may be a missing commutation state.

    What are the halls inputs during this time? Are they switching as expected?

  • Hello Rick Duncan,

    I have an oscilloscope but there are only two probes to measure.

    If I can measure it then definitely I will send it. 

    But I find some improvement after putting 10nF capacitor across 3.3V hall sensor signal. I have replaced C45, C46 and C47 with 10nF. Result for this value is much better than earlier.

     I will check the performance for some hours. After that, I will tell that problem is solved or not. 

    Thanks.