Need to generate a clock

Hi all,

I hope I am not in the wrong forum :-*.

I am new to Arduino and Atmel chips. I will be using a Mega board to to prototype something - I am looking forward to getting it :).

The sensor I will be connecting to needs a 32,768 KHz clock. I have read the Atmel documentation that states that a crystal may be connected to TOSC1 and TOSC2, prvided that AS2 is set in ASSR. Fine, but then where will the clock (signal) be available ? I don't need a high precision clock here, I can consider dividing the chip clock also.

Thanks for your help.

I have read the Atmel documentation that states that a crystal may be connected to TOSC1 and TOSC2, prvided that AS2 is set in ASSR.

This is talking about clocking the microcontroller

Take a look at "Blink without delay" maybe you can run the interrupt at ~32.768khz

There are Oscillator chips that can do that...

http://cn.ic-on-line.cn/IOL/datasheet/sg-10_574128.pdf

Can you give some information on the sensor - perhaps a link to a datasheet?

That clock can easily be generated with a crystal and a couple of load caps; I have seen certain sensors that required such a clock - they generally have a couple of pins that you hook the crystal and load caps up to.

:slight_smile:

... I don't need a high precision clock here, I can consider dividing the chip clock also.

Would 31,250KHz be close enough?
The ATmega's internal timers can straightforwardly generate that, and make it available on a PWM pin.
It is practical to get even closer using most of the resources of Timer1 or Timer2.

If you are interested, and know how to use a microcontroller, look at the Atmel documentation http://www.atmel.com/dyn/products/product_card_v2.asp?part_id=4720
e.g. ATmega48A/48PA/88A/88PA/168A/168PA/328/328P (555 pages, revision A, updated 1/10/2010) (WARNING, this link will break when the document is updated - you have been warned)

Essentially, you can use a pre-scaler (e.g. read: 16. Timer/Counter0 and Timer/Counter1 Prescalers or 17. 8-bit Timer/Counter2 with PWM and Asynchronous Operation) to divide the clock to the right ball park.
Then Timer1 or Timer2 to give you a nice 50:50 ratio square wave.

If 31,250KHz is close enough, you have the part of the timer available for some other purposes (e.g. PWM or generating waveforms, or timing signals). If you want a more accurate clock, you'll consume almost all of one Timers resources to do it.

Don't use Timer0, as that is used for the Arduino time functions.

HTH
GB

@cr0sh

The sensor is MS5540C from Measurement Specialties.

@gbulmer

The clock frequency can be anywhere between 30 KHz and 35 KHz.

@all

I know that I can use a circuit fo the oscillator. But the final device will be very small, so I have to spare all the space I can. This is why I would like to use the controller to generate the clock. But I don't want tp do it by software, using for example delay().

PWM seems the better pick as far as I understand. If I use Timer2, like gbulmer suggest, to get 31.2 KHz as you suggest, where will the signal be available - I am still struggling withe the documentation ?

Thanks

The spec sheet says the key properties of the clock signal are 50% duty cycle and jitter-free. Using PWM (or a more sophisticated use of ATmega's counter/timers) will give the jitter-free quality needed, but the exact 50% duty isn't actually available from the standard PWM setup. However the datasheet suggests 60/40 to 40/60 are acceptable.

I'd recommend using timer1 at prescale of divide-by-1. On the Mega pins 11 and 12 (rather than 9 and 10) are attached to timer1.

TCCR1B = (TCCR1B & 0xF8) | 1 ;

Will set prescale to divide by one on timer1, then try

analogWrite (11, 128) ;

On a standard Arduino use pins 9 or 10.

But the final device will be very small, so I have to spare all the space I can.

So small you can't afford the few millimeters of space an SMT crystal and caps would take up? You do know these are the same crystals/caps used in digital watches...?

I am not saying your application can't be smaller, but wow - how small of an area are we talking about?

:slight_smile:

[edit]Hmm - that's a pretty small sensor, and it doesn't look like you could easily use an external crystal to generate it; not sure. The part I was looking at before had two xtal lines like the ATMega, not a single clock input line, so it looks like generating it from the ATMega would be the best bet.

:slight_smile:
[/edit]

There is a nice diagram showing the mapping of Arduino pins to the ATmega168 which makes it much easier to read the Atmel documentation and figure out where internal hardware things reaches a pin out.

As far as I can find, no one has done the same diagram for the Arduino Mega :frowning:

You could look at the the Arduino Mega schematic (I realise that is a pretty horrible recommendation, sorry).

The pins which produce PWM signals come from 'Output Compare Units' in the timers, and have pin names which look like 'OCnx', where n is a digit, and is the timer number, and x is A, B or sometimes C, and is one of the outputs from timer n.

So OC3A, OC3B and OC3C are all outputs from Timer3.
Similarly OC1A and OC1B are outputs from Timer1.

The Arduino software sets up sets the timers to count from 0 to 255. The actual rate at which the timer counts is set by a 'prescaler', which divides the 16MHz clock. The prescalers are set to give Timer0 a frequency of around 1Kz (it generates the millis() clock) with a prescale value of 64.

The prescaler for the other timers are also 64, and so set for 0.5KHz (they are set for 'Phase Correct' PWM which runs at 1/2 the rate of the counter).
The calculation is:

  • precaler = clock/64 = 16MHz/64 = 250KHz
  • counter = prescaled clock/256 = 976.6Hz
  • phase-correct PWM = 2 cycles = 488.3Hz

You want roughly 32KHz, so the prescaler needs to be about 65 times smaller, with 64x smaller = 1.

MarkT has shown you how to adjust that for Timer1, and a similar bit of code will work for any other timer (leaving Timer0 alone). You should check the Atmel documentation for the timer you choose as there are a couple of types of prescaler.

As you are okay with a frequency near 32KHz, and don't need it exactly, then that is all there is to do. (It gets a bit more intricate if you want an exact frequency match.)

It is straightforward to get a 50:50 duty cycle from a timer set up to count to the right number. Use analogWrite(pin, value) where value is 1/2 the maximum count. Where the timer is set to count from 0 to 255 (as all are) the 50:50 value is 127. You can see the Arduino pin which matches a specific OCnx pin on the schematic.

This approach completely avoids the need for an external crystal or oscillator. If you are looking to make the whole device very small, this technique is practical on all of the AVR's with timers, which means it would work with Atmel AVR's as small as an 8-pin SOIC. If you use a timer on the Arduino Mega which looks like the timer on your target AVR device, you should be able to get the code very, very close to the production code.

HTH
GB

Thank you all for your posts. I got the board, and is experimenting uploading and checking using printf Serial. printl. For now I concentrate on the SPI signal - I haven't seen yet the SCLK signal on my scope :'(.

Afterwards, I will have my 32KHz working, my sensor needs it.

I will come back when I succeed, hopefully ;).

There is a pin map for the Arduino Mega at http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1245229578 which might be helpful if you want to have some flexibility of which Timer output compare pin to use.

GB

Everything is fine, I have a clock ! 31.37 KHz is fine with what I need. I have done what MarkT suggested.

Thanks