While I was looking for a solution to the EMC issue, I thought about turning the regular 122Hz PWM frequency into something more like white noise. The idea was to spread the spectrum of the emmited radiation so that at any one frequency, the signal would be weaker.
It didn’t work. The intended effect was minimal, and it played havoc with the feedback control loop, so the idea has been abandoned. However, it was an interesting exercise and the coding turned out to be remarkably simple.
The PIC 12F683 has a register called PR2 which is used to set the PWM frequency. However, it also affects PWM resolution, so I made the decision to set it to its maximum value, FF hex. This results in a very limited choice of PWM frequencies, 30.5Hz, 122Hz and 488Hz as Timer 2 has a rather coarse prescaler. Nevertheless, 122Hz felt about right, so the decision stood.
The spread spectrum idea would work by randomly altering the value of PR2 between 80 and FF hex on every cycle of the PWM. But how do you generate random numbers in PIC assembly language?
I vaguely remembered that shift registers could be used to generate random numbers and that this technique had been used in some synthesisers to generate white noise. Perhaps it could replace the annoying tone being picked up on my AM radio with a pleasant rushing sound.

Fibonacci Linear Feedback Shift Register
Wikipedia soon came up with the Linear Feedback Shift Register (LFSR) as the solution, and when I saw the word Fibonacci, that was it, my subroutine got that exotic name! All I had to do was Exclusive OR bits 6 and 5 of PR2 together and feed the result into bit zero as the register was shifted left. In addition, bit 7 had to remain set.
The first problem is that PIC Exclusive ORs don’t work like in the diagram. There’s no instruction to Exclusive OR two different bits of the same register. That’s solved by rotating PR2 left and putting the result into W, then exclusive ORing W with the unaffected PR2, like this:
rlf PR2,w
xorwf PR2,w
Now we have to take the result of the Exclusive OR and feed it into bit zero as we shift PR2 to the left. That requires that we copy bit 6 of W into the carry flag. This turned out to be relatively simple.
First, all bits in W other than bit 6 must be cleared. Then bit 6 needs to be copied to the carry flag, like this:
andlw 0×40
addlw 0xFF
Now PR2 can be shifted left and bit 7 set, like this:
rlf PR2,f
bsf PR2,7
And that’s it! Six instructions. PR2 is in the high bank, so we need a couple of ‘banksel’ instructions, and to make it a subroutine a ‘return’ is needed.
Amazingly, it worked first time, and on the AM radio white noise instead of that piercing 122Hz tone. This apparently simple process generates all 127 binary values in a pseudo random sequence.
But the flaws were soon apparent. White noise, sure, but no actual reduction in radio frequency interference. No spreading of the spectrum, just a different sound carried by the carrier. Not to mention the effect that modulating PR2 was having on the battery voltage feedback control loop.
It was a case of ‘nice solution, wrong problem’.