Electronic – How to use IO pins in PIC microcontroller as PWM

picpwm

I am trying to use a PIC18F4520 microcontroller to drive 8 servo motors. For this I need 8 PWM signals, but the PIC unit has only two built in PWM. So, I decided to use some normal I/O pins as PWM, and searched how to do that. I found some hardware based solution like using extra IC's or software based solution as using interrupt based PWM. But why can't I just use this code segment:

while(1)
{
PORTA.RA0=1;
delay_ms(10);
PORTA.RA0=0;
delay_ms(10);
}

The pin is high for 10ms and low for 10 ms.So the cycle period is 20ms. Shouldn't this create a 50Hz signal with 50% duty cycle? Or am I missing something?

Best Answer

The delay() function causes the PIC to loop and prevents any other activity other than interrupt triggered routines. In your example it will turn on RA0 for 10 ms, pause (preventing servicing any other output) and then turn off RA0 for 10 ms with the same inhibiting action. The pause() function should really be hidden from beginners as it encourages this kind of poor programming practice.

Instead you should run a base timer for your PWM outputs and do something like this pseudo code.

while(1) {
  timer += 1;                // increment the timer.
  if (timer > tmax) {
    timer = 0;               // reset
  }
  PORTA.RA0 = (timer < t0ontime);  // Output on until ontime exceeded.
  PORTA.RA1 = (timer < t1ontime);
  PORTA.RA2 = (timer < t2ontime);
  PORTA.RA3 = (timer < t3ontime);
  PORTA.RA4 = (timer < t4ontime);
  PORTA.RA5 = (timer < t5ontime);
  PORTA.RA6 = (timer < t6ontime);
  PORTA.RA7 = (timer < t7ontime);
}

It's been many years since I've used the PIC compiler so this may not work as written, but you get the idea. You should make the timer increment on a fixed timebase rather than the way I've shown it so that it won't vary if you change the chip oscillator, etc.

One other improvement you could make on this code is to avoid starting all the pulses at the same time. This would smooth out the demand on the power supply and may help reduce noise a little.

Related Topic