MCPWM with LPC175x/176x


For my new “mini Sumo” size robotic platform I am using MCPWM to control the DC brush micro-motors instead of PWM as I am keeping the PWM outputs in case I will want to control some sensors or servos.

I could not find a functional example on how to control DC brush motors using a H bridge, in this case DRV8833, so I thought of putting together some code for reference.

First, to control DRV8833 the data sheet shows the following logic table.

 

DRV8833 logic table

 

The pins used on this project are P1.25, P1.26, P1.28 and P1.29 for MCOA1, MCOB1, MCOA2 and MCOB2 respectively.

Now, to setup the MCPWM:

#define LPCMCPER	500000
#define LPCMCPW		(LPCMCPER/2)
#define LPCMCTIM	0

#define SPEEDDIV	(LPCMCPER/10)

#define MOT1A_PIN	(1<<25)
#define MOT1B_PIN	(1<<26)
#define MOT2A_PIN	(1<<28)
#define MOT2B_PIN	(1<<29)


void motor_setup(void){
  LPC_GPIO1->FIODIR |= MOT1A_PIN | MOT1B_PIN | MOT2A_PIN | MOT2B_PIN;

  LPC_SC->PCONP 	|= 1<<17;		// enable MCPWM
  LPC_SC->PCLKSEL1 	|= (1<<30);		// set clock

  LPC_MCPWM->MCPER1 	= LPCMCPER;
  LPC_MCPWM->MCPW1 	= LPCMCPW;
  LPC_MCPWM->MCTIM1 	= LPCMCTIM;

  LPC_MCPWM->MCPER2 	= LPCMCPER;
  LPC_MCPWM->MCPW2 	= LPCMCPW;
  LPC_MCPWM->MCTIM2 	= LPCMCTIM;

  LPC_MCPWM->MCCON_SET |= MCPWM_CON_RUN(1) | MCPWM_CON_RUN(2);
}

And to control the speed and direction:

void motor_mspeed(int8_t valueL, int8_t valueR){
  motor_speed(0, valueL);
  motor_speed(1, valueR);
}

void motor_speed(int8_t motor, int8_t speed){
  if (speed > 0){
    if (motor == 0){
      LPC_MCPWM->MCCON_CLR  = MCPWM_CON_POLAR(1);
      // MOTA=LOW, MOTB=PWM
      LPC_MCPWM->MCPW1 = speed*SPEEDDIV;
      LPC_PINCON->PINSEL3 &=~MOT1B_NSEL;
      LPC_GPIO1->FIOSET = MOT1B_PIN;
      LPC_PINCON->PINSEL3 |= MOT1A_PSEL;
    } else {
      LPC_MCPWM->MCCON_SET  = MCPWM_CON_POLAR(2);
      // MOTA=LOW, MOTB=PWM
      LPC_MCPWM->MCPW2 = speed*SPEEDDIV;
      LPC_PINCON->PINSEL3 &=~MOT2A_NSEL;
      LPC_GPIO1->FIOSET = MOT2A_PIN;
      LPC_PINCON->PINSEL3 |= MOT2B_PSEL;
    }
  } else if (speed < 0){
    if (motor == 0){
      LPC_MCPWM->MCCON_SET |= MCPWM_CON_POLAR(1);
      // MOTA=PWM, MOTB=LOW
      LPC_MCPWM->MCPW1 = -speed*SPEEDDIV;
      LPC_PINCON->PINSEL3 &=~MOT1A_NSEL;
      LPC_GPIO1->FIOSET = MOT1A_PIN;
      LPC_PINCON->PINSEL3 |= MOT1B_PSEL;
    } else {
      LPC_MCPWM->MCCON_CLR  = MCPWM_CON_POLAR(2);
      // MOTA=PWM, MOTB=LOW
      LPC_MCPWM->MCPW2 = -speed*SPEEDDIV;
      LPC_PINCON->PINSEL3 &=~MOT2B_NSEL;
      LPC_GPIO1->FIOSET = MOT2B_PIN;
      LPC_PINCON->PINSEL3 |= MOT2A_PSEL;
    }
  } else {
    //break
    if (motor == 0){
      // MOTA=LOW, MOTB=LOW
      LPC_MCPWM->MCPW1 = 0;
      LPC_PINCON->PINSEL3 &=~MOT1A_NSEL;
      LPC_GPIO1->FIOCLR = MOT1A_PIN;
      LPC_PINCON->PINSEL3 &=~MOT1B_NSEL;
      LPC_GPIO1->FIOCLR = MOT1B_PIN;
    } else {
      // MOTA=LOW, MOTB=LOW
      LPC_MCPWM->MCPW2 = 0;
      LPC_PINCON->PINSEL3 &=~MOT2A_NSEL;
      LPC_GPIO1->FIOCLR = MOT2A_PIN;
      LPC_PINCON->PINSEL3 &=~MOT2B_NSEL;
      LPC_GPIO1->FIOCLR = MOT2B_PIN;
    }
  }
}

If anyone interested I can go into details ;-)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s