Software PLL?

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Greetings -

 

The target platform related to this question will probably be a 4808/9 but that MIGHT not be significant. 

 

I've done some searching on the 'net and most of what I've found seems to be targeted at PLDs and such but what I would like to do is constrained by MCU clocks, timer prescalers, and counters that rarely have an up/down option (except for "phase correct" modes which  seem to be absent from AVR-0 devices). 

 

Here is what I would like to do:

 

1. I have a 1 second tick from an internal real-time clock counter OR a 1 second period square-wave from an external RTC.

 

2. I would like to generate 100ms (10Hz) events that are phase-locked to the 1 second period tick/square-wave. 

 

3. I am guessing that I need a timer with variable TOP to generate the 100ms event rate and that the 100ms clock needs to be counted down by 10 to make a 1 second signal that can be phase-compared to the given 1 second signal. So, it sounds like we are already occupying two timer/counters for this (in addition to the internal RTC counter which is occupied, whether in use or not). Maybe the divide by 10 is at a slow enough rate that it can be done in software?

 

With this as a starting point, I am a bit puzzled about how to proceed. I am guessing that rates are slow enough that the phase comparison and the integration for the  loop filter can be implemented totally in software. Does anyone have any ideas or suggestions for an algorithm that might work? For example, do I really need to implement a phase/frequency control loop to improve the initial lock speed? How would the phase comparison work? 

 

Thanks for your suggestions and ideas!

Jim

 

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I did a similar thing many years ago to generate a filtered 100Hz reference from a 50Hz pulse for phase control of triacs.

 

The method I used was a 16bit timer with capture and compare. The compare is used for the DCO.

 


#define PERIOD_COUNT 20  //20 periods within 1 second

uint16_t period = 50MS; //start with what we think is the correct value
uint16_t event;
uint16_t periodCount = 0;
// set timer1 up for free run, toggle output and interrupt on compare

ISR (TIMER1_COMPA_vect)
{
    OCR1A += period;   // that's our DCO - vary period to tweek the frequency
    periodCount++;
    if (periodCount > NUM_PERIODS)
        {
            periodCount = 0;
        }
    
    // the next challenge is to measure the incoming reference
    
    // test the compare int flag to see if we have a compare event
    if (TIFR1 & (1 << ICF1))
        {
            event = ICR1;
            TIFR1 = (1<<ICF1); //clear the flag
    // here's where the fun starts
    // determine the difference between the 'event' and 'period' values
    // note that the var 'period' is now one period ahead of time
    // and also that it is within the correct periodCount
    // once you've determined the absolute error, there's a number of strategies you can employ -
    // if it is a gross error, then apply a fixed correction to 'period'
    // if it is a mild error, maybe use a low pass filter to correct 'period' or just scale the error by a constant (ie error / 8)
    // if it is a minor error, correct by a fixed small amount
    // leave a deadband - if the error is within this range, no correction
        }
}


Some other things to remember - any correction gets multiplied by the number of periods!  

 

Other techniques might be to use a DDS technique for the DCO where you sample at a high frequency. 

 

Is phase jitter a problem? Or is it ok that the average frequency is pretty correct? 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the  suggestion. Will give your code a thorough going-over to see what you did.

 

Phase jitter is not an extreme issue but I'd like it not to be huge, what ever that might mean. 

 

DDS is an interesting idea. Will have to ponder that one for a bit. 

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:

1. I have a 1 second tick from an internal real-time clock counter OR a 1 second period square-wave from an external RTC.

2. I would like to generate 100ms (10Hz) events that are phase-locked to the 1 second period tick/square-wave. 

3. I am guessing that I need a timer with variable TOP to generate the 100ms event rate and that the 100ms clock needs to be counted down by 10 to make a 1 second signal that can be phase-compared to the given 1 second signal. So, it sounds like we are already occupying two timer/counters for this (in addition to the internal RTC counter which is occupied, whether in use or not). Maybe the divide by 10 is at a slow enough rate that it can be done in software?

 

You may be over-thinking this.

If you have an internal timer only, you only need 10 x 100ms interrupts to get the 1sec, and there is no phase-sync needed.

If you have an external 1sec, then a simple edge interrupt can preload your internal timer.

Effectively 9 of the 100ms ticks are set by internal sysclk, and every 10th is defined by the external edge.

 

That needs 1 timer, and 1 edge interrupt.

 

To give some tolerance, you could preload the timer to 50ms on external edge (that avoids a re-sync arriving right when you have an edge, which could result in two edges)

that gives a range of +/-5%, which may be enough ?

 

If you needed a wider dynamic range than that, then all 100ms ticks will need to scale, and here you would capture from the 1s timebase, and use that to re-calibrate the 100ms.

That needs a compare and a capture, and if they are the same timer, you need simple sw to allow for the capture being from relative to N reloads of the previous calibrate value.

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah, sure, the old "relaxation oscillator sync" trick. Of course! 

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Sun. Dec 8, 2019 - 11:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can use the rtc if its already being used. You have two interrupts, an overflow and compare. The overflow period can be set to 1 second, and the compare can be moved up every time through. You can have an array of times to load into cmp, setting it back to the first in the array when an overflow is seen, so you get an interrupt every 100ms. The rtc clock has resolution of 30us, which I imagine is good enough when talking about 100ms.

 

The bigger problem I suspect, is not how to get to a 100ms period but how to get into powerdown and somehow wake up every 100ms. If you lookup the powerdown mode, basically a pin change or the PIT (in RTC) are the options to wake up. So either need an external 100ms signal, or rely on a power of 2 wakeup with the PIT which is difficult unless you move from 10Hz to 8Hz or 16Hz. If you only want standby, then it gets simple again.

 

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for those ideas. Indeed, I have not considered sleep/wake-up. That does throw a bit of goop in the gears.

 

Actually, its a bit more messy than that, even.

 

My sensor wakes it up every (nominal) 10ms. But, that timing can be off by 5% or more.

 

As I think about it, the 100ms ticks would not really be that helpful. The RTC is practically used for much longer intervals, 10s to 100s of seconds. So 0.1 second ticks adds almost nothing to that. So, scratch the whole thing. Sorry for the noise.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Mon. Dec 9, 2019 - 01:35 AM