time-nuts@lists.febo.com

Discussion of precise time and frequency measurement

View all threads

Re: [time-nuts] A Simple PIC Divider

HM
Hal Murray
Mon, Aug 7, 2006 1:09 AM

Right, this is essentially what my (and any other) PIC divider does.
Simple, isn't it?

And those 8-pin PICs are too cute to pass up.

Yup.  I saw the light when I was trying to work out a 1/2 second delay with
something like a 555.  I couldn't quite get what I wanted.  Simple in
software.  Saves board space too.

DigiKey sells the PICKit 2 for $35.  I haven't used it.  It's USB powered.
Looks like it may have a small board for programming so you can program chips
if you include a socket on your board.  Another approach is to include a
programming header on your board.

The older version (PICKIt 1?) had an 8/14 pin socket and could program a few
of the low cost chips. They were the PIC16F630/676 and PCI12F629/675.  The
630/676 have 14 pins.  The 629/675 have 8 pins.  One of each pair had a 10
bit A/D.

I don't think any of those chips has a serial port.  You would have to do
(heroic) bit-banging if you needed that.

The other series of low cost small CPUs I've worked with is the AVR parts
from Atmel.  The ATSTK500 is $80 at Digikey.  It programs most (all?) of the
AVR parts.  It uses a wall wart and serial cable.

Both vendors offer free Windows software.  With a bit of poking around you
can find versions of GCC or assemblers that support the chips you are
interested in.  I'm not sure about programming from non-Windows systems.

--
The suespammers.org mail server is located in California.  So are all my
other mailboxes.  Please do not send unsolicited bulk e-mail or unsolicited
commercial e-mail to my suespammers.org address or any of my other addresses.
These are my opinions, not necessarily my employer's.  I hate spam.

> Right, this is essentially what my (and any other) PIC divider does. > Simple, isn't it? > And those 8-pin PICs are too cute to pass up. Yup. I saw the light when I was trying to work out a 1/2 second delay with something like a 555. I couldn't quite get what I wanted. Simple in software. Saves board space too. DigiKey sells the PICKit 2 for $35. I haven't used it. It's USB powered. Looks like it may have a small board for programming so you can program chips if you include a socket on your board. Another approach is to include a programming header on your board. The older version (PICKIt 1?) had an 8/14 pin socket and could program a few of the low cost chips. They were the PIC16F630/676 and PCI12F629/675. The 630/676 have 14 pins. The 629/675 have 8 pins. One of each pair had a 10 bit A/D. I don't think any of those chips has a serial port. You would have to do (heroic) bit-banging if you needed that. The other series of low cost small CPUs I've worked with is the AVR parts from Atmel. The ATSTK500 is $80 at Digikey. It programs most (all?) of the AVR parts. It uses a wall wart and serial cable. Both vendors offer free Windows software. With a bit of poking around you can find versions of GCC or assemblers that support the chips you are interested in. I'm not sure about programming from non-Windows systems. -- The suespammers.org mail server is located in California. So are all my other mailboxes. Please do not send unsolicited bulk e-mail or unsolicited commercial e-mail to my suespammers.org address or any of my other addresses. These are my opinions, not necessarily my employer's. I hate spam.
CH
Chuck Harris
Mon, Aug 7, 2006 2:10 AM

Hal Murray wrote:

Right, this is essentially what my (and any other) PIC divider does.
Simple, isn't it?

And those 8-pin PICs are too cute to pass up.

Yup.  I saw the light when I was trying to work out a 1/2 second delay with
something like a 555.  I couldn't quite get what I wanted.  Simple in
software.  Saves board space too.

They can be fun for making an adjustable 555 replacement too.  Take one of the
ADC's and connect it to a voltage divider, and play away!

DigiKey sells the PICKit 2 for $35.  I haven't used it.  It's USB powered.
Looks like it may have a small board for programming so you can program chips
if you include a socket on your board.  Another approach is to include a
programming header on your board.

The older version (PICKIt 1?) had an 8/14 pin socket and could program a few
of the low cost chips. They were the PIC16F630/676 and PCI12F629/675.  The
630/676 have 14 pins.  The 629/675 have 8 pins.  One of each pair had a 10
bit A/D.

I don't think any of those chips has a serial port.  You would have to do
(heroic) bit-banging if you needed that.

If you get the CCS C compiler, it has a library function that will allow you
to program a serial port onto any pin.  Works nicely.  It's a great compiler,
by the way.  Costs a bit over $100 these days.  It is available for both
'doze, and linux.

-Chuck Harris

Hal Murray wrote: >> Right, this is essentially what my (and any other) PIC divider does. >> Simple, isn't it? > >> And those 8-pin PICs are too cute to pass up. > > Yup. I saw the light when I was trying to work out a 1/2 second delay with > something like a 555. I couldn't quite get what I wanted. Simple in > software. Saves board space too. They can be fun for making an adjustable 555 replacement too. Take one of the ADC's and connect it to a voltage divider, and play away! > > > DigiKey sells the PICKit 2 for $35. I haven't used it. It's USB powered. > Looks like it may have a small board for programming so you can program chips > if you include a socket on your board. Another approach is to include a > programming header on your board. > > The older version (PICKIt 1?) had an 8/14 pin socket and could program a few > of the low cost chips. They were the PIC16F630/676 and PCI12F629/675. The > 630/676 have 14 pins. The 629/675 have 8 pins. One of each pair had a 10 > bit A/D. > > I don't think any of those chips has a serial port. You would have to do > (heroic) bit-banging if you needed that. If you get the CCS C compiler, it has a library function that will allow you to program a serial port onto any pin. Works nicely. It's a great compiler, by the way. Costs a bit over $100 these days. It is available for both 'doze, and linux. -Chuck Harris
TV
Tom Van Baak
Mon, Aug 7, 2006 2:40 AM

I don't think any of those chips has a serial port.  You would have to do
(heroic) bit-banging if you needed that.

True, although simple, robust, and free code samples
for this are all over the web. Or as Chuck mentioned,
serial support is included in various PIC compilers.

One caution, though. Most high-level languages are
not compatible with the fixed instruction loop count
code technique used in the pic divider.

/tvb

> I don't think any of those chips has a serial port. You would have to do > (heroic) bit-banging if you needed that. True, although simple, robust, and free code samples for this are all over the web. Or as Chuck mentioned, serial support is included in various PIC compilers. One caution, though. Most high-level languages are not compatible with the fixed instruction loop count code technique used in the pic divider. /tvb
CH
Chuck Harris
Mon, Aug 7, 2006 3:51 AM

Hi Tom,

The CCS C compiler does just fine.  When you use the delay function,
it is smart enough to know when it is better to insert a few NOP
instructions (and other time wasters), and when it is better to toss
in a loop.  The code it generates is generally better than I can do
myself using assembly, and I have been programming in assembler, off
and on, for more than 25 years.  There just aren't that many different
ways to do things with a risc processor.

If I wanted to divide a 10MHz clock down to 100KHz, I could do something
like:

#include <12F629.h>

#use delay(clock=10000000)
main()
{
while(1){
delay_us(5);
output_toggle(PIN_A0);
}
}

Or, if I wanted a 1PPS output, I would just have to change the delay_us(5)
instruction to delay_ms(500).

If you look at the resulting code, you will find it is as lean and bare as
you would code by hand.

A buck for a 10 MHz to 1PPS divide chain in an 8 pin dip is kind of hard
to beat (that could be a really bad pun!).

-Chuck

Tom Van Baak wrote:

I don't think any of those chips has a serial port.  You would have to do
(heroic) bit-banging if you needed that.

True, although simple, robust, and free code samples
for this are all over the web. Or as Chuck mentioned,
serial support is included in various PIC compilers.

One caution, though. Most high-level languages are
not compatible with the fixed instruction loop count
code technique used in the pic divider.

/tvb


time-nuts mailing list
time-nuts@febo.com
https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts

Hi Tom, The CCS C compiler does just fine. When you use the delay function, it is smart enough to know when it is better to insert a few NOP instructions (and other time wasters), and when it is better to toss in a loop. The code it generates is generally better than I can do myself using assembly, and I have been programming in assembler, off and on, for more than 25 years. There just aren't that many different ways to do things with a risc processor. If I wanted to divide a 10MHz clock down to 100KHz, I could do something like: #include <12F629.h> #use delay(clock=10000000) main() { while(1){ delay_us(5); output_toggle(PIN_A0); } } Or, if I wanted a 1PPS output, I would just have to change the delay_us(5) instruction to delay_ms(500). If you look at the resulting code, you will find it is as lean and bare as you would code by hand. A buck for a 10 MHz to 1PPS divide chain in an 8 pin dip is kind of hard to beat (that could be a really bad pun!). -Chuck Tom Van Baak wrote: >> I don't think any of those chips has a serial port. You would have to do >> (heroic) bit-banging if you needed that. > > True, although simple, robust, and free code samples > for this are all over the web. Or as Chuck mentioned, > serial support is included in various PIC compilers. > > One caution, though. Most high-level languages are > not compatible with the fixed instruction loop count > code technique used in the pic divider. > > /tvb > > > > _______________________________________________ > time-nuts mailing list > time-nuts@febo.com > https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts >
BH
Bill Hawkins
Mon, Aug 7, 2006 6:11 AM

Wait a second - are you saying that the compiler is
smart enough to account for the 'while' and the
'output_toggle' instructions to make the total
execution time for the loop be precisely 50 clock
ticks?

-----Original Message-----
From: Chuck Harris

If I wanted to divide a 10MHz clock down to 100KHz, I could do something
like:

while(1){
	delay_us(5);
	output_toggle(PIN_A0);
}
Wait a second - are you saying that the compiler is smart enough to account for the 'while' and the 'output_toggle' instructions to make the total execution time for the loop be precisely 50 clock ticks? -----Original Message----- From: Chuck Harris If I wanted to divide a 10MHz clock down to 100KHz, I could do something like: while(1){ delay_us(5); output_toggle(PIN_A0); }
R
Rex
Mon, Aug 7, 2006 8:34 AM

On Sun, 6 Aug 2006 19:40:44 -0700, "Tom Van Baak" tvb@leapsecond.com
wrote:

I don't think any of those chips has a serial port.  You would have to do
(heroic) bit-banging if you needed that.

True, although simple, robust, and free code samples
for this are all over the web. Or as Chuck mentioned,
serial support is included in various PIC compilers.

One caution, though. Most high-level languages are
not compatible with the fixed instruction loop count
code technique used in the pic divider.

/tvb

CCS C supports inline assembler with #ASM and #ENDASM directives, so it
should be possible to define the critical stuff exactly. If you needed
serial com you could use the special C functions for that.

I missed why someone would want serial com with the divider function,
though. Is there a good reason?

On Sun, 6 Aug 2006 19:40:44 -0700, "Tom Van Baak" <tvb@leapsecond.com> wrote: >> I don't think any of those chips has a serial port. You would have to do >> (heroic) bit-banging if you needed that. > >True, although simple, robust, and free code samples >for this are all over the web. Or as Chuck mentioned, >serial support is included in various PIC compilers. > >One caution, though. Most high-level languages are >not compatible with the fixed instruction loop count >code technique used in the pic divider. > >/tvb > CCS C supports inline assembler with #ASM and #ENDASM directives, so it should be possible to define the critical stuff exactly. If you needed serial com you could use the special C functions for that. I missed why someone would want serial com with the divider function, though. Is there a good reason?
G
Glenn
Mon, Aug 7, 2006 8:46 AM

Does anyone have a good solution for the 1-2 us delay between the
divider "reset" (or "start") and the first (and later) pulses?

I think this might be a good reason to put a serial port on one of the
pins. Then, you could send the divider "skip x steps" or "add x steps."
I'm not sure if it would matter if the skipped steps were on the high or
low side of the pulse. You could also use this function to compensate
for the temperature dependent TTL->RS232 line driver delay used on 1 PPS
lines sent to things like NTP servers.

cheers,
glenn

Does anyone have a good solution for the 1-2 us delay between the divider "reset" (or "start") and the first (and later) pulses? I think this might be a good reason to put a serial port on one of the pins. Then, you could send the divider "skip x steps" or "add x steps." I'm not sure if it would matter if the skipped steps were on the high or low side of the pulse. You could also use this function to compensate for the temperature dependent TTL->RS232 line driver delay used on 1 PPS lines sent to things like NTP servers. cheers, glenn
CH
Chuck Harris
Mon, Aug 7, 2006 12:15 PM

Hi Bill,

No, of course it isn't.  But for a function as critical
as this, surely one would look at the assembly generated.
There will no doubt be need to adjust things a little bit.
It might end up being something more like:

while(1){
delay_us(4);
#asm
NOP
#endasm
output_toggle(PIN_A0);
}

On another note, there are PICs that have hardware divider
chains built in.  The 12F629 is one of them.

-Chuck

Bill Hawkins wrote:

Wait a second - are you saying that the compiler is
smart enough to account for the 'while' and the
'output_toggle' instructions to make the total
execution time for the loop be precisely 50 clock
ticks?

-----Original Message-----
From: Chuck Harris

If I wanted to divide a 10MHz clock down to 100KHz, I could do something
like:

while(1){
	delay_us(5);
	output_toggle(PIN_A0);
}

time-nuts mailing list
time-nuts@febo.com
https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts

Hi Bill, No, of course it isn't. But for a function as critical as this, surely one would look at the assembly generated. There will no doubt be need to adjust things a little bit. It might end up being something more like: while(1){ delay_us(4); #asm NOP #endasm output_toggle(PIN_A0); } On another note, there are PICs that have hardware divider chains built in. The 12F629 is one of them. -Chuck Bill Hawkins wrote: > Wait a second - are you saying that the compiler is > smart enough to account for the 'while' and the > 'output_toggle' instructions to make the total > execution time for the loop be precisely 50 clock > ticks? > > > -----Original Message----- > From: Chuck Harris > > If I wanted to divide a 10MHz clock down to 100KHz, I could do something > like: > > while(1){ > delay_us(5); > output_toggle(PIN_A0); > } > > > _______________________________________________ > time-nuts mailing list > time-nuts@febo.com > https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts >
BC
Brooke Clarke
Mon, Aug 7, 2006 5:37 PM

Hi Glenn:

The PIC uC chips all divide the incoming oscillator signal by 4 to
generate a set of 4 internal clock signals so the actual instruction
frequency is Fin/4.
A 10 MHz input results in a 2.5 Mhz instruction cycle frequency, or 400
ns per instruction.  Any code in the PIC that involves a branch and
doing something is going to take a few instructions so you end up around
a 1 us offset.  But for most things you want an offset so that you are
not measuring on both sides of zero.  It might be possible to change the
SYNC function so that instead of trying to make the code as fast as
possible instead after the sync pulse is detected to wait for .9999996
seconds (or some other time TBD) so as to get closer to the 1 PPS edge.

Another idea would be to make an external circuit that would be put in
series between the 10 Mhz clock and the divider with a button and every
press of the button would remove one cycle of the clock giving  you a
-100 ns step.  This idea could be extended to 10 cycles, 100 cycles,
etc.  Allowing moving the 1 PPS edge.

It happens that I've just started looking at how to move the 1 PPS edge
in the Precision Clock, see:
http://www.pacificsites.com/~brooke/PRC68COM.shtml#PC3
and it looks like the PIC can easily move it in 1 ms steps and I think
that may be good enough.
Rather than instruction counting, like is used in the tvb divider the
clock uses interrupts.  This has a big advantage in that the clock keeps
running all the time, even while it's being set.  That way changing the
time will not effect the 1 PPS edge.

Have Fun,

Brooke Clarke

--
w/Java http://www.PRC68.com
w/o Java http://www.pacificsites.com/~brooke/PRC68COM.shtml
http://www.precisionclock.com

Glenn wrote:

Does anyone have a good solution for the 1-2 us delay between the
divider "reset" (or "start") and the first (and later) pulses?

I think this might be a good reason to put a serial port on one of the
pins. Then, you could send the divider "skip x steps" or "add x steps."
I'm not sure if it would matter if the skipped steps were on the high or
low side of the pulse. You could also use this function to compensate
for the temperature dependent TTL->RS232 line driver delay used on 1 PPS
lines sent to things like NTP servers.

cheers,
glenn


time-nuts mailing list
time-nuts@febo.com
https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts

Hi Glenn: The PIC uC chips all divide the incoming oscillator signal by 4 to generate a set of 4 internal clock signals so the actual instruction frequency is Fin/4. A 10 MHz input results in a 2.5 Mhz instruction cycle frequency, or 400 ns per instruction. Any code in the PIC that involves a branch and doing something is going to take a few instructions so you end up around a 1 us offset. But for most things you want an offset so that you are not measuring on both sides of zero. It might be possible to change the SYNC function so that instead of trying to make the code as fast as possible instead after the sync pulse is detected to wait for .9999996 seconds (or some other time TBD) so as to get closer to the 1 PPS edge. Another idea would be to make an external circuit that would be put in series between the 10 Mhz clock and the divider with a button and every press of the button would remove one cycle of the clock giving you a -100 ns step. This idea could be extended to 10 cycles, 100 cycles, etc. Allowing moving the 1 PPS edge. It happens that I've just started looking at how to move the 1 PPS edge in the Precision Clock, see: http://www.pacificsites.com/~brooke/PRC68COM.shtml#PC3 and it looks like the PIC can easily move it in 1 ms steps and I think that may be good enough. Rather than instruction counting, like is used in the tvb divider the clock uses interrupts. This has a big advantage in that the clock keeps running all the time, even while it's being set. That way changing the time will not effect the 1 PPS edge. Have Fun, Brooke Clarke -- w/Java http://www.PRC68.com w/o Java http://www.pacificsites.com/~brooke/PRC68COM.shtml http://www.precisionclock.com Glenn wrote: >Does anyone have a good solution for the 1-2 us delay between the >divider "reset" (or "start") and the first (and later) pulses? > >I think this might be a good reason to put a serial port on one of the >pins. Then, you could send the divider "skip x steps" or "add x steps." >I'm not sure if it would matter if the skipped steps were on the high or >low side of the pulse. You could also use this function to compensate >for the temperature dependent TTL->RS232 line driver delay used on 1 PPS >lines sent to things like NTP servers. > >cheers, >glenn > > >_______________________________________________ >time-nuts mailing list >time-nuts@febo.com >https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts > > >
RW
Randy Warner
Tue, Aug 8, 2006 7:23 PM

Guys,

First off, what I am about to do is ask a REALLY STUPID question, but
more and more of the GPS stuff I do is drifting towards the precision
timing end of things, so I thought I should ask.

I have been seeing a lot of traffic concerning making 10MHz frequency
dividers using PIC's. While they provide an elegant solution to
providing an accurate 1PPS from a precision source, I have to ask if
there is a reason for going this route? I am just using three HCT40103
down counters hooked to a DS4000 to get what I think is a very stable
1PPS. Am I missing something? I realize 40103's are as old as dirt (I
guess I am showing my 4000 series CMOS days), but the HCT series have
plenty of bandwidth.

Please be gentle....

Randy

Guys, First off, what I am about to do is ask a REALLY STUPID question, but more and more of the GPS stuff I do is drifting towards the precision timing end of things, so I thought I should ask. I have been seeing a lot of traffic concerning making 10MHz frequency dividers using PIC's. While they provide an elegant solution to providing an accurate 1PPS from a precision source, I have to ask if there is a reason for going this route? I am just using three HCT40103 down counters hooked to a DS4000 to get what I think is a very stable 1PPS. Am I missing something? I realize 40103's are as old as dirt (I guess I am showing my 4000 series CMOS days), but the HCT series have plenty of bandwidth. Please be gentle.... Randy