Tipp said:
I'm taking it that what you just said was, instead of letting the built-in PWM take control, it's all software controlled?
Yes, you take a pin HIGH, wait a bit, take it LOW again, wait a bit, and repeat. How long you wait each time determines the mark/space ratio.
The clever bit is doing it on multiple pins independently, 'apparently' at the same time.
One method is to use timer interrupts, and a series of counters in the interrupt routine. Preset the counters for the brightness you want, and turn all the LED's ON, each time the interrupt routine runs it decrements each counter in turn, until they reach zero, then turns that LED OFF. Once the interrupt routine has run the maximum number of times, the original counter values are reset, and it starts again.
But it's a balancing act between number of bits used for the PWM, and the repetition frequency - it's obviously essential that the interrupt routine is faster than the time between interrupts. It's also a problem that you don't have much spare processing power left.
I've done it in the past for two PWM channels feeding motors on a robot, and also done software RS232 to receive radio commands via 433MHz modules, plus IR obstacle detection - all at the same time. But it was a very busy little 16C84, back before the 16F628 came out!.