Accessing clock cycle count on stm32f103

tiger762
Fri Apr 29, 2016 2:46 am
So I have need to take 8000 analog samples per second for a project. I started looking at the possibility of using a GPS module which puts out a 1PPS signal to discipline the MCU. Will schedule a timer for 125 microseconds in the future. First, will calibrate the MCU by seeing how many clock cycles accumulate during the GPS 1-second period. Should be 72 million cycles. If it is in fact N cycles, then I would have the next iteration schedule a timer for (125 * N / 72000000).

The first step is to access the clock cycle count. I found http://stackoverflow.com/questions/1337 … c-on-stm32 and distilled it to the bare necessary code:

#define DEMCR (*((volatile uint32_t *)0xE000EDFC))
#define DWT_CTRL (*(volatile uint32_t *)0xe0001000)
#define CYCCNTENA (1<<0)
#define DWT_CYCCNT ((volatile uint32_t *)0xE0001004)
#define CPU_CYCLES *DWT_CYCCNT

Next, I place in setup() this:

DEMCR |= DEMCR_TRCENA;
*DWT_CYCCNT = 0;
DWT_CTRL |= CYCCNTENA;

Finally, in loop() we have:

x = CPU_CYCLES;
delay (10);
Serial.println (CPU_CYCLES – x);

I get a steady stream of:
720502
720500
720498
……

My GPS modules don’t have an actual 1PPS output but they have a green SMT LED :D I’m thinking that a photocell could trigger a hardware interrupt. The ISR then grabs the CPU clock cycle count to then know what the exact CPU frequency is. If it turns out the CPU runs at 100ppm faster, then I’d scale back all timer requests by 100ppm.


Pito
Sat Apr 30, 2016 4:25 pm
You cannot discipline MCU from GPS 1pps directly.
You may discipline a quality VCXO from GPS, and you may use the VCXO as the clock for MCU.
A GPS 1pps is long term cesium precise (ie 1second in million years), but not short term (ie now). The short term jitter could be 6-100ns based on GPS quality.
That is several MCU clocks per second. So your 1pps might be plus/minus many MCU clocks off, in form of a “noise”. The long term average of this noisy 1ppm is cesium precise (atomic clock).
Disciplining VCXO from a GPS 1pps is not easy, it is kind of a rocket science.. :)
You need a quality voltage controlled crystal oscillator (better when it is ovenised), you feed the 1pps GPS pulses into an integrator with long integr. period (several hours), you feed the voltage from the integrator into VCXO, plus you need some phase comparator feedback loop, etc..

RogerClark
Sat Apr 30, 2016 11:12 pm
@pito

Thats interesting.. I bet most of us think the 1pps is accurate over a 1 second timescale.

I did a bit if googling and found this

http://www.eevblog.com/forum/chat/how-a … ps-signal/

It appears that some GPS units are better than others ( they seem to think Trimble units have the least jitter, but I dont think there was any hard evidence)

I think what the OP really needs is an accurate 8khz clock, then it could be used to trigger an ISR to do the conversion.

However, If the OP needs the level of accuracy that they claim, I wonder if a MCU is the ideal device to accumplish this.
This may be getting into the realm of FPGA or discrete hardware.


Pito
Sat Apr 30, 2016 11:47 pm
OP has to rethink his approach, I think. He also needs to understand all sources of a time jitter – GPS 1pps has got significant jitter, CPU’s clock PLL generator inside the MCU is also quite noisy, ISR creates a jitter too. If he needs something doable and less noisy then a simple external crystal oscillator (ie 10-20MHz) feeding the MCUs clock input (without multiplying by PLL) and locking ADC conversion to an internal timer set to 8Khz period would be a good solution..

RogerClark
Sun May 01, 2016 1:46 am
@pito

Yes. ISR’s have jitter, and the OP would probably have to turn off all the other interrupts.

I suspect they may have to code in assembler, or at least look at the code generated by the compiler, as adding new code, may cause the compiler to add in a load of instructions that effect the timing.

The OP never really said why they need to accurately sample, exactly at 8khz.

And, although not impossible to do in using Arduino with LibMaple etc, it would probably be better to code directly using the HAL


Pito
Sun May 01, 2016 7:22 am
The negative point of “Arduino movement” is – the people (new generation let us say) tend to solve every technical problem with an “arduino” board.. :)

mrburnette
Sun May 01, 2016 1:19 pm
Pito wrote:The negative point of “Arduino movement” is – the people (new generation let us say) tend to solve every technical problem with an “arduino” board.. :)

ddrown
Mon May 02, 2016 12:48 am
tiger762 wrote:
My GPS modules don’t have an actual 1PPS output but they have a green SMT LED :D I’m thinking that a photocell could trigger a hardware interrupt. The ISR then grabs the CPU clock cycle count to then know what the exact CPU frequency is. If it turns out the CPU runs at 100ppm faster, then I’d scale back all timer requests by 100ppm.

ahull
Mon May 02, 2016 2:04 pm
I’m not sure if we are over thinking the problem a bit here. If you simply want to fire the ADC at a regular interval, with good accuracy, and use DMA to get the results, you could do worse than look over the code in the Pig-O-Scope. If you oversample at say 16kHz,32kHz,64kHz or some other multiple, you should get a pretty good approximation of whatever the 8kHz analog signal is that you are attempting to measure. Given that we have managed to drive the ADC at around the 1MHz marker, I’m pretty sure 8kHz will be a breeze.

RogerClark
Mon May 02, 2016 9:29 pm
Andy,

I think what we see as the OP’s big problem is making sure that the samples are taken at exactly 8000.00000000 times per second, and that the time between samples is exactly 1/8000.00000000 of a second.

Having an accurate system clock e.g. to 1 part in 100 million etc seems essential, as does ensuring that nothing stops the ADC being triggered at precisely the right moment.

Thinking about this, also makes me wonder whether the conversion time would also be an issue, as I thought conversion time varied with input voltage, which may cause more jitter than all other factors.


ahull
Mon May 02, 2016 10:34 pm
RogerClark wrote:Andy,

I think what we see as the OP’s big problem is making sure that the samples are taken at exactly 8000.00000000 times per second, and that the time between samples is exactly 1/8000.00000000 of a second.


mrburnette
Mon May 02, 2016 11:03 pm
I have two thoughts:

Summary of variable feedback concept:
4. The load capacitance (CL) of my parallel resonant crystal is rated at 20pF. How do I calculate the value of the load capacitors used in my parallel resonant oscillator circuit?

Use this formula to approximate the value of capacitors needed:

CL=((C1 x C2) / (C1 + C2)) + Cstray

Cstray is the stray capacitance in the circuit, typically 2-5pF. If the oscillation frequency is high, the capacitor values should be increased to lower the frequency. If the frequency is low, the capacitor values should be decreased, thus raising the oscillation frequency. When CL =20pF, C1 and C2 will be approximately 27-33pF each, depending on the amount of stray capacitance.

With a VarCap, I think the uC could perform self-adjustment of the external DC bias circuit (digital programmed resistor) my tracking the leading edge of the GPS PPS. This self-adjustment could be done at startup, or it could be done periodically whenever the uC detected a change in ambient temperature- a simple thermistor and precision resistor should be adequate to track temperature, since exact temperature is not required, simply the delta from the previous capture.

Ray


Leave a Reply

Your email address will not be published. Required fields are marked *