Go Down

### Topic: How can I generate 8MHz clock using timers or PWM with my Arduino Leonardo? (Read 3794 times)previous topic - next topic

#### xRamon

##### Jan 24, 2014, 10:42 pmLast Edit: Jan 27, 2014, 05:07 pm by xRamon Reason: 1
Hi, I'm trying to generate 8MHz clock from the arduino to connect it to an OV7670 camera sensor on XCLK pin. I'm trying to do it using the timer 1, but the maximum frequency I get is approximately 41kHz?
Here is my code:
Code: [Select]
`const int led=10;/*Input Frequency -> CLK=16MHzTimer Resolution = (1 / (Input Frequency / Prescale)) = (Prescale / Input Frequency)Prescaler Value | Resolution at 16MHz              1 |  62.5nS              8 |  0.6uS             64 |  4uS            256 |  16uS           1024 |  64uSTarget Timer Count = (1 / (Target Frequency*2)) / (Prescale / Input Frequency) - 1                   = (Target Period / 2) / Timer Resolution - 1If: Target Period = 125nsec.  ->  Target frequency = 8MHzWith prescaler = 1Target Timer Count = (125nS/2)/62.5nS - 1 = 0*/#define TMR1 0    //for 8MHzISR(TIMER1_COMPA_vect) {  digitalWrite(led, digitalRead(led)^1);};void setup() {  pinMode(led, OUTPUT);//*********************************************************************    //TIMER1 (16 bits) in mode CTC  TCCR1B |= (1 << CS10);  //selecting prescaler 0b001 (Tclk/1)  TCCR1B &= ~((1<<CS12) | (1<<CS11));    // turn off CS12 and CS11 bits  TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode  TCCR1A &= ~((1<<WGM11) | (1<<WGM10));    OCR1A = TMR1;    TIMSK1 |= (1 << OCIE1A); // Enable CTC interrupt  sei();    //Enable global interrupts//*********************************************************************}void loop(){}`

I'm guessing that the instruction in the interrupt routine is taking too long.
Thanks.

#### AWOL

You're trying to generate an output frequency half the clock frequency of the controller, using an interrupt.
That simply cannot work.

#### xRamon

And how can I do it then?
Or do you mean that it can not be done?
Can I configure the PWM to get that frequency?

#### lxguru

looked at http://forum.arduino.cc/index.php/topic,22384.0.html
code that should set pin 3 to 1MHz - it uses timer2 and the normal analogWrite function for pins 3 and 11 won't be available if you do this. This may help.

#define PWMout 3

void setup ()
{
TCCR2A = 0xB3 ; // fast PWM with programmed TOP val
TCCR2B = 0x09 ; // divide by 1 prescale
TCNT2  = 0x00 ;
OCR2A  = 0x0F ; // TOP = 15, cycles every 16 clocks
OCR2B  = 0x07 ; // COMP for pin3
pinMode (PWMout, OUTPUT) ;

...
}

#### xRamon

Well Ixguru thanks for the TIP! I checked out the datasheet and configured the TIMER1 in TOP mode and Toggle mode .
Here I post my code. It works super OK!!!

Code: [Select]
`#include <avr/interrupt.h>#include <avr/io.h>/*Input Frequency -> CLK=16MHzTimer Resolution = (1 / (Input Frequency / Prescale)) = (Prescale / Input Frequency)Prescaler Value | Resolution at 16MHz               1 |  62.5nS               8 |  0.6uS              64 |  4uS             256 |  16uS            1024 |  64uSTarget Timer Count = (1 / (Target Frequency * 2)) / (Prescale / Input Frequency) - 1                   = (Target Period / 2) / Timer Resolution - 1If: Target Period = 125nseg.  ->  Target frequency = 8MHzWith prescaler = 1Target Timer Count = (125nS/2)/62.5nS - 1 = 0*/#define TMR1 0    //for 8MHz: TMR1 = 0 , for 10kHz: TMR1 = 799 void setup() {  // put your setup code here, to run once:  pinMode(9, OUTPUT);//*********************************************************************    //TIMER1 (16 bits) in mode TOP  TCCR1B |= (1 << CS10);  //selecting prescaler 0b001 (Tclk/1)  TCCR1B &= ~((1<<CS12) | (1<<CS11));    // turn off CS12 and CS11 bits  TCCR1A |= ((1<<WGM11) | (1<<WGM10));  //Configure timer 1 for TOP mode (with TOP = OCR1A)  TCCR1B |= ((1<<WGM13) | (1<<WGM12));  TCCR1A |= (1 << COM1A0); // Enable timer 1 Compare Output channel A in toggle mode   TCCR1A &= ~(1 << COM1A1);  TCNT1 = 0;    OCR1A = TMR1;  //*********************************************************************}void loop() {}`

#### lxguru

Thanks for sharing out your code - spirit of open source . Basically to use Fast PWM mode, setting TOP value 0. How did you verify you got the desired clock? by using arduinoscope? curious.

#### xRamon

#6
##### Jan 28, 2014, 06:26 amLast Edit: Jan 28, 2014, 06:40 am by xRamon Reason: 1
I'm using an oscilloscope. That's how i verified the frequency.

Go Up