0
\$\begingroup\$

I have an RS485 network connecting several MCU boards where communication happens in 1ms intervals. With the MCU it's therefore easy to create a 1kHz clock with approx 50% duty cycle using the counters. I want to multiply this 1kHz frequency to about 40 MHz needed for the CLKIN of an ADC. What I'm trying to achieve is to keep the ADC running in continuous mode, delivering one sample per ms without the boards drifting apart.

I looked at various PLL ICs but they expect input frequencies in the MHz range.

In case this is impossible or impractical, I will run the ADC in single shot mode, but I'm curious if it's possible at all.

Topology: There are 10 devices on an RS485 bus running at 1 MHz spanning about 10 meters. One of them is the master who initiates communication every 1ms. The other 9 devices derive their 1kHz clock from those communications.

Clock source: The master divides its MCU clock to approx. 1kHz via a counter. In the counter ISR the master initiates the transfer of the sync-byte via the UART.

Clock derivation: After receiving the sync byte from the master, the slaves (in their UART ISR) take a pin - let's call it CLKout - to high. They start a one shot timer who will take CLKout low after about 0.5ms.

If the slaves are a few microseconds out of phase it's no problem.

\$\endgroup\$
8
  • \$\begingroup\$ You'd need a very very steady 1 kHz. Please edit your question and detail the source of the 1 kHz and its accuracy. More detail the better, please. \$\endgroup\$ – TonyM Mar 19 at 14:11
  • 3
    \$\begingroup\$ Could you please describe your topology and the application? Sounds like an XY-problem \$\endgroup\$ – Eugene Sh. Mar 19 at 14:18
  • \$\begingroup\$ I've updated the question ("Edit 1") and hopefully provided the requested details. \$\endgroup\$ – tschaboo Mar 19 at 14:43
  • \$\begingroup\$ If your RS485 is running at 1MHz your slaves have to have a local clock or crystal in order to receive this signal. Can you post a schematic? \$\endgroup\$ – Lior Bilia Mar 19 at 15:06
  • 1
    \$\begingroup\$ You would need some way of synchronizing the ADCs otherwise they'll probably start up +/-500usec not a few microseconds. Also, ADCs can be sensitive to jitter on the input clock, which could negatively affect the accuracy. \$\endgroup\$ – Spehro Pefhany Mar 19 at 16:03
2
\$\begingroup\$

Analog PLL

Forget about it. With 1 ms between each update, you need a very stable VCO that won't drift, which means a VCXO, which means $$$. You should only consider this option if you need ultra low phase noise, which you probably don't, since you mention 1µs drift is acceptable. No need to bother with the extra complication.

Cooperative coordination

The master sends a message that means "Everyone gets ready to sample."

All the boards contain a simple logic gate like AND between the RS485 receiver output and the ADC "trigger sampling input". The micro sets a GPIO to 1, which drives the other input of the AND gate to 1. This means when the RS485 receiver outputs a logic "1", ADC will trigger sampling. Then the master reconfigures its UART output pin to GPIO, outputs a pulse that triggers all ADCs, then configures it back to UART. Once the sampling is done, all boards also reconfigure back to normal UART mode.

This does not need synchronization between the clocks, so you'll get one 40MHz cycle uncertainty between boards.

If the logic gate is too expensive, you can also use a pin change interrupt.

Cheap solution

Each micro has its own free-running clock and ADC sampling.

When the RS482 synchro packet arrives, it is timestamped on the local clock.

Then, linear interpolation between the ADC sample taken before and the ADC sample taken after the synchro packet, to guess what the sample value would have been if it had been sampled at the arrival time of the synchro packet.

Pros: Free, no jitter to mess up the ADC.

Cons: Accuracy could be "meh", and if you are doing more elaborate things than just taking a sample value, you may not have stuff to interpolate.

Dumb and cheap solution

If the ADC is not sampling constantly, then just estimate when it should sample given the arrival times of the previous packets relative to the local clock, and trigger it at the right spot. You'll get an uncertainty of a few clock cycles, but that's less than the 1µs you say you need.

For example, say the master is running at 40 MHz and the slave runs at 39.9998 MHz. If you trigger the ADC every millisecond, that's every 40,000 cycles on the master. The slave would mark the arrival time of packets, do an average with some smoothing, and conclude it should sample every 39,999.8 cycles. You can do that with a PWm timer sending a pulse to trigger the ADC and a bit of code in the timer interrupt.

The Frac-N PLL

Local XO clock -> Fractional-N PLL. Either a separate chip, or in the micro if it has one.

The micro compares arrival times of synchro packets with output of fractional PLL, and adjusts the frequency to match. Make sure your Fractional PLL can be adjusted on the fly without losing lock, and has enough significant digits to be able to match the source frequency accurately enough without having to go bang-bang "too fast... too slow... too fast..."

Pros: will smooth out jitter over several synchro packets, pretty accurate, you can put whatever secret sauce you want in the loop filter to get the result you want

Cons: you need an extra chip and a PLL loop filter in software.

The Frac-N PLL with training wheels

Get a jitter attenuator like the CS2000. SureSiLabs has sexier chips, but you will pay extra for the very high frequency capabilities you won't actually use. CS2000 is simple: costs five bucks, give it a stable local clock, give it your 1kHz clock, set the registers via I2C to "multiply that by 40000" and done. It is also a Fractional-N PLL which means it has the stability of the local XO clock.

On the question of jitter

If you use the solutions that tweak sampling time, you get sampling jitter. That means the samples will be taken at slightly varying intervals. It is up to you to decide how much of it is okay in your application, that depends on the slew rate of your signal, ie how much it will change during the interval where it may be sampled. If it is a 1MHz sine wave, with 1µs timing uncertainty you get a random sample somewhere in the period, so it's completely useless. If it is DC, then jitter is irrelevant.

If you use the Frac-N PLL, you get a bit of jitter on the ADC clock, which will raise its noise floor. How much depends on the amount of jitter, the nature of the ADC, and the number of bits. The CS2000 specs 175 ps RMS max jitter, which is pretty low (caveat: jitter on the local reference clock has to be added to that of course). It's lower than a standard low-cost canned crystal oscillator, and much better than a crystal on a noisy micro. So it should be fine.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you so much for your elaborate answer. Even though I already decided which way to go, I will research all options you gave just out of curiousity and to learn something. \$\endgroup\$ – tschaboo Apr 1 at 22:13
2
\$\begingroup\$

PLL chips that take kilohertz inputs exist. I've used Silicon Labs parts at 4 KHz to generate ~80 MHz outputs. I'm not sure if they make anything where they can guarantee jitter performance all the way to 1000 Hz, but it doesn't sound like that's critical if you're using an MCU as the source clock anyway.

Clock source: The master divides it's MCU clock to approx. 1kHz via a counter.

Why don't you divide down that clock to something more reasonable for the ADC clock and then use the 1 KHz signal as a trigger for the ADC? That way you don't need an exotic PLL that can handle very low frequencies with (hopefully) acceptable jitter performance.

\$\endgroup\$
2
  • \$\begingroup\$ Could you share which SiLabs part you used? I couldn't find any Clock Generator on their homepage that would take a slow clock. \$\endgroup\$ – tschaboo Mar 19 at 14:48
  • \$\begingroup\$ @tschaboo silabs.com/timing/jitter-attenuators \$\endgroup\$ – user1850479 Mar 19 at 14:59
1
\$\begingroup\$

I would put a 40Mhz clock in every ADC board and run the microcontroller and the ADCs with that clock.

It is way easier to make a 1Khz output out of a 40Mhz clock than the other way around. The master can then send a "start sampling message" once each millisecond. It is easy to make the slaves to synchronize their ADC sampling cycle based on this communication event. I assume that, at some point you want to read the 10 sampled ADC values sequentially within this 1mS window. Assuming ADCs of 12 or 16 bits, provided no other data is transmitted over the channel, it appears it's achievable.

As you can take a phase uncertainty of several microseconds, the system on this way will run quite well with a nominal clock uncertainty of 25pS. Adding clock tolerances and other considerations, you may aim to system uncertainties of a few hundred picoseconds.

It's not obvious from the question if the master has also an ADC but if it does, you end up with 10 identical boards. In this way, you could select which one is the master by software or by a hardware pin. In this way, you reduce the complexity of the system and also the cost.

Many other considerations are possible but it is difficult to tell from the information provided.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.