Wednesday, June 3, 2009

PWM on a microcontroller, the Hard Way

On a project I had to implement nine PWM outputs for an LED dimming application. Up to eight is easy on an MSP430 - use TimerB outputs TB 1..6 and TimerA outputs TA1,2. But I needed nine. So, I had to do this the hard way, in code. Here's how I did it.

This example "fades up" an LED:
unsigned int onTime = 0; //periodsPerStep;
unsigned int offTime = 0; //PWM_PERIOD - onTime;

#define PWM_PERIOD 0xFF //period for PWM wavelength - 0xFF = 8kHz or so
#define CROSSFADE_STEPS 0xFF //how many intervals of intensity. 16 looks choppy
#define PERIODS_PER_STEP 0x3F//0x7F //how much time to wait at each intensity interval: 0xFF = 6 secs

unsigned int perStepInterval = PWM_PERIOD / CROSSFADE_STEPS;

for (int step = 0; step < CROSSFADE_STEPS; step++)
{
onTime = perStepInterval * step;
offTime = PWM_PERIOD - onTime;

//PWM periods:
for (int periodCounter = 0; periodCounter < PERIODS_PER_STEP; periodCounter++)
{
P1OUT = 0x01;
for (unsigned int counter = 0; counter < onTime; counter++) ; //on interval

P1OUT = 0x00;
for (unsigned int counter = 0; counter < offTime; counter++) ; //off interval
}
}

No comments:

Post a Comment