PWM on LPC1225


Lately I am working on a small project: a table-top 4WD platform. For some reasons I decided to use 2 PWM for each motor and each 2 motors to use one 32 bit counter.

The problem was to have access to all 4 PWM outputs: MAT0, MAT1, MAT2 and MAT3 not only 3 of them. Usually using 1, 2 or 3 PWM is simple and pretty straight forward: use MR3 to reset TC:

        LPC_IOCON->PIO0_6 &= ~0x07;
	LPC_IOCON->PIO0_6 |=  0x04;

	LPC_IOCON->PIO0_7 &= ~0x07;
	LPC_IOCON->PIO0_7 |=  0x04;

	LPC_IOCON->PIO0_8 &= ~0x07;
	LPC_IOCON->PIO0_8 |=  0x04;

	LPC_CT32B0->EMR    = (1<<EMC0) | MATCH0 | (1<<EMC1) \
                           | MATCH1 | (1<<EMC2) | MATCH2 | MATCH3;

        LPC_CT32B0->PWMC   = MATCH3 | MATCH0 | MATCH1 | MATCH2;

	/// Set PWM period on MATCH3
	LPC_CT32B0->MR3    = MAXSPEED;

	LPC_CT32B0->MR0    = 0x00;

	/// Set match control register
	LPC_CT32B0->MCR    = 1<<10;

	/// Reset pwm
	LPC_CT32B0->TCR    = 0x02;

	/// Enable pwm
	LPC_CT32B0->TCR    = 0x01;

Then to control the motors can use something like:

	if(speed < 0){
		LPC_CT32B0->MR0 = -speed;

		LPC_CT32B0->MR1 = 0;
	} else {
		LPC_CT32B0->MR1 = speed;

		LPC_CT32B0->MR0 = 0;
	}

The problem is however to be able to control the PWM on MAT3. Since MR3 is used as Match Register to reset TC, changing it will affect all motors.

Since I only need 2 active PWM at any given moment (MAT0 and MAT2 or MAT1 and MAT3) while the other 2 can be “0” logic, I decided to design the code to switch between MR2 and MR3 as match register, and allow this way to control either MAT2 or MAT3.

The problem was now to get MAT3 or MAT2 in “0” when either MAT3 or MAT2 are used as PWM output. This complicated the things a bit more as this will require to switch each of them between PWM and GPIO pins. I end up with something like:

	if(speedF < 0){
 		LPC_CT32B0->MR3    = MAXSPEED;
		LPC_CT32B0->EMR   &= ~(1<<EMC3); 
                LPC_CT32B0->EMR   |= (1<<EMC2) | MATCH2;
                LPC_CT32B0->PWMC  |= MATCH2;
		LPC_CT32B0->PWMC  &=~MATCH3;
		LPC_CT32B0->MCR    = 1<<10; 
 		LPC_CT32B0->TCR    = 0x01;
		PIO0_9_OUT;

		LPC_CT32B0->MR2 = - speed;
		PIO0_9_L;
	} else {
		LPC_CT32B0->EMR  &= ~(1<<EMC);
                LPC_CT32B0->EMR  |= (1<<EMC3) | MATCH3;
                LPC_CT32B0->PWMC |= MATCH3;
		LPC_CT32B0->PWMC &=~MATCH2;
		LPC_CT32B0->MR2   = MAXSPEED;
		LPC_CT32B0->MCR   = 1<<7;
		LPC_CT32B0->TCR   = 0x01;
 		PIO0_8_OUT;

		LPC_CT32B0->MR3    = speed;
		PIO08_L;
	}

It took some thinking but in the end works pretty well. Wish was an easier way to do it though…

(Note to myself: this editor sucks!)

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