PDA

View Full Version : Timing inaccuracy - any ideas?



Optech
- 1st February 2008, 21:37
I have used a 12F675 to create a simple square wave with a duty cycle of 75% - 80% (not crucial) with a variable period which can have a number of possible values ranging from 0.714128 secs to 2.666667 secs. The circuit works as expected but seems to have a problem of accuracy and stability.

The application requires accuracy of better than 0.01% and I would like it to be better than 10 us.

Initially I used the internal timer, not expecting great results. In fact the output (read on a picoscope) was pretty stable down to 0.1%. Then I used an external 8 MHz crystal with inbuilt capacitor which gave slightly worse results. The period fluctuated by 2 or 3 ms.

In both cases the period was about 4 -5 ms lower than the program should have created, which is at least 50x acceptable error.

I have removed some of the code for clarity but the basis of the program is as follows:

DEFINE OSC 8 'Using an 8 MHz resonator
ANSEL=0 'Set to digital operation
TRISIO=%00001011 'Set GP0,1 & 3 to input GP2 to output rest dont care
OPTION_REG.7=0 'Global Weak Pull up (or use WPU=%00000011)
CMCON=7 'comparators off

PAUSE 100
MAIN:
GPIO.2=1
PAUSE 2166 '2.166s
PAUSEUS 667 '0.000667s
GPIO.2=0
PAUSE 500 '0.5s
GOTO MAIN
END

Anyone got any ideas why the timing is so inaccurate?
It's even less precise than the 555 RC circuit I built years ago to do a similar job!

Many thanks.

skimask
- 1st February 2008, 21:49
I have removed some of the code for clarity but the basis of the program is as follows

That's probably the problem right there. You aren't helping us by doing that...

I can think of a few things that'll cause the timing to be off, but not to the tune of 4-5ms (i.e. not accounting for the time spent doing other instructions which also take time to accomplish, oscillator being out of tune, the list goes on).

Optech
- 1st February 2008, 22:01
OK - just to clarify; I removed the code and tested it with the program as you see it - with the same results. (the other code was mostly to do with altering the period using jumpers)

As I understand it, each command takes Fosc/4 except for goto and a few others I haven't used, so I wouldn't have expected an error of more than 1 - 2 us in the main loop.

I had wondered about the oscillator. I have a few 10 MHz oscillators but can't get them until Monday now, so I won't be able to test that theory until then.

skimask
- 1st February 2008, 22:11
As I understand it, each command takes Fosc/4 except for goto and a few others I haven't used, so I wouldn't have expected an error of more than 1 - 2 us in the main loop.

Right, those other commands was what I was wondering about. Each ASSEMBLY instruction only takes .5us...each PBP command, well that's another animal. Each PBP isn't neccessarily one ASSEMBLY instruction.

Resonators - I just Digikey, few random samples of resonators, looks like they're good to about 1% at least, tighter than that usually.

How about just a plain ol' light on/light off loop. How good is that? Forget the nifty stuff, just:

main1:
led = 1
goto main2
main2:
led = 0
goto main1

That should eliminate all timing inconsistencies. Should be an even up 50% duty cycle at an unwavering frequency dependant upon your oscillator. You should get 333.333khz using an 8Mhz oscillator. I don't have my 12F datasheets open right now, don't know how many extra BANK type instructions will be in there, so your freq will probably be lower.

Optech
- 2nd February 2008, 18:05
Thanks for the info I didn't realise the instruction times were for assembly not pbp.

I set up the program as suggested and got a 6.2 KHz frequency readout +/-0.1 Khz.
The duty cycle is 50% +/-2%. (suggests about 27 us per command?)

The trace on the scope is not square; doen't even acheive the full amplitude - almost as though there is a stray capacitance somewhere.

I then tried the same program with the internal RC oscillator with similar results. I've checked and rechecked the circuitboard and all is as it should be.

I returned to the external resonator, and added a 'pause 5' to each half of the main loop and got the following readout on the scope:

Frequency 100.0 Hz
High pulse width 5000 us
Low pulse width 5000 us
Cycle time 10000 us
Duty cycle 50.00%

Not a flicker. Perfect squarewave form. Totally mystified.
Reprogrammed original program (cut down version as above). Same result of flickering up and down +/- 0.1% and being out by 4 ms.

I can't progress this any further due to other commitments for now so I'll wait until I can try another resonator on Monday. Any further suggestions welcome of course.

Many thanks

skimask
- 2nd February 2008, 19:12
I set up the program as suggested and got a 6.2 KHz frequency readout +/-0.1 Khz.
The duty cycle is 50% +/-2%. (suggests about 27 us per command?)
Well, if you would've used that program EXACTLY as I wrote it, you would've seen nothing, since there were no port assignments, no TRISIO statements, no nothing.
So, let's see what you actually did write.
And while you're at it, open up your program's .lst file and look thru the actual PIC assembly code. There you'll see all the instructions that the PIC is actually executing. Take a look at the datasheet, and you'll see that most ASSEMBLY instructions take one cycle, gotos/branches/calls take 2 cycles, and conditional instructions can either take one or two cycles depending on results. That's one way to figure out how fast a loop should be.


The trace on the scope is not square; doen't even acheive the full amplitude - almost as though there is a stray capacitance somewhere.
Then that would tell me that maybe your 'scope's probes and/or the 'scope itself isn't capable of reading higher frequencies, or maybe they need to be cal'd.

Also, are you SURE that your CONFIG bits are being set correctly? You may think you're running 8Mhz external when you're actually running 125Khz on the internal clock, or worse, running on the 37Khz internal R/C clock.

Optech
- 7th February 2008, 09:37
Replacement of the crystal has eliminated the instability, and with a minor adjustment of the pause values I have a sufficiently accurate cycle time for the application, so it looks like a dodgy oscillator was the cause of the problem.

Many thanks for all the advice - it's been an education.