> Tim,
>
> That was a very nice explanation. I have always considered software
> PLLs to be a bit of an enigma, though a future project goal of mine is
> going to require one. In my case, the reference and the incoming
> signal will both be aprox 50 or 60hz sine waves. For the PFD, I was
> planning on multiplying them and filtering the result which would be
> used to drive the NCO.
>
> I was wondering if you would you please elaborate a little more on the
> concept of using the inphase and quadriture outputs and their phase
> rotation and what this does / how / why it works?
>
I always consider software PLLs to be very straightforward -- until I
get caught up in actually making them work. Then I try to act casual
while I'm struggling with them so that when I finally stumble onto the
right combination I look clever...
On using inphase and quadrature outputs:
First, see my opening paragraph -- I missed a detail in that
recommendation, it isn't as powerful as I had thought (d'oh). I'll
explain as I go.
Let's say that you're keeping track of the NCO phase and calling it
'theta', and you're phase locking to a signal -- I'll call it 'line' in
honor of your 50 or 60Hz signal. A multiplying phase detector can be
made by finding
phaseError = sin(theta) * line;
You take this phase error and run it through a loop filter:
frequency = loopFilter.Update(phaseError); // pretend this is C++
Then you calculate the NCO phase:
theta += frequency;
And you're done.
The cool thing is that the variable phaseError will have an average
value that's proportional to the phase, so if your loop settles at all
it will do so at zero average error.
The problem is that if all you know is phaseError then it's average
could be zero for other reasons -- either the NCO frequency is
significantly different from the line frequency, or you're hovering on a
phase error of 180 degrees. Usually the 180 degrees out of phase issue
isn't a big one because it's inherently unstable and eventually your
loop will lock. A large frequency difference can be a bigger problem.
If you do the quadrature thing, then you may calculate
phaseErrorI = sin(theta) * line;
phaseErrorQ = cos(theta) * line;
Now, when you are at 0 degrees phase error phaseErrorI will average to 0
and phaseErrorQ will average to a positive number. With 180 degrees
phase error phaseErrorI will average to 0 and phaseErrorQ will average
to a _negative_ number, so you will be able to distinguish the 180
degree out of phase condition and deal with it.
In addition, if there is a frequency difference between the line
frequency and your NCO frequency then the average values of phaseErrorI
and phaseErrorQ will rotate around each other -- so first phaseErrorI
will be high, then phaseErrorQ, then phaseErrorI will be negative, etc.
You can use the averages of these two phase errors like the output of
a quadrature encoder to track the phase error and determine if it is
rising or falling, which will let you determine if your frequency error
is positive or negative -- which in turn will let you bring your loop
into lock quicker.
Unfortunately (and hence the d'oh), if the frequency error is large then
the average values will both be quite small, and this method won't give
great success. So for this sort of thing you may be better to have a
coarse frequency loop that just counts zero crossings or something to
bring the loop into approximate lock, then allow a simple multiplying
phase detector to take over.
--
Tim Wescott
Wescott Design Services
http://www.wescottdesign.com