Go Down

Topic: Clock generator with arduino (Read 14152 times) previous topic - next topic

Mr_arduino

Hello, I am interstead in generating a 8mhz clock output using my arduino uno how do I divide the arduino uno 16mhz clock and output to a pin?

simonfrfr

#1
May 09, 2012, 03:36 am Last Edit: May 09, 2012, 03:41 am by simonfrfr Reason: 1
Code: [Select]

//
// Use of timer2 to generate a signal for a particular frequency on pin 11
//
//

const int freqOutputPin = 11;   // OC2A output pin for ATmega328 boards
//const int freqOutputPin = 10; // OC2A output for Mega boards

// Constants are computed at compile time

// If you change the prescale value, it affects CS22, CS21, and CS20
// For a given prescale value, the eight-bit number that you
// load into OCR2A determines the frequency according to the
// following formulas:
//
// With no prescaling, an ocr2val of 3 causes the output pin to
// toggle the value every four CPU clock cycles. That is, the
// period is equal to eight slock cycles.
//
// With F_CPU = 16 MHz, the result is 2 MHz.
//
// Note that the prescale value is just for printing; changing it here
// does not change the clock division ratio for the timer!  To change
// the timer prescale division, use different bits for CS22:0 below
const int prescale  = 1;
const int ocr2aval  = 3;
// The following are scaled for convenient printing
//

// Period in microseconds
const float period    = 2.0 * prescale * (ocr2aval+1) / (F_CPU/1.0e6);

// Frequency in Hz
const float freq      = 1.0e6 / period;

void setup()
{
   pinMode(freqOutputPin, OUTPUT);
   Serial.begin(9600);

   // Set Timer 2 CTC mode with no prescaling.  OC2A toggles on compare match
   //
   // WGM22:0 = 010: CTC Mode, toggle OC
   // WGM2 bits 1 and 0 are in TCCR2A,
   // WGM2 bit 2 is in TCCR2B
   // COM2A0 sets OC2A (arduino pin 11 on Uno or Duemilanove) to toggle on compare match
   //
   TCCR2A = ((1 << WGM21) | (1 << COM2A0));

   // Set Timer 2  No prescaling  (i.e. prescale division = 1)
   //
   // CS22:0 = 001: Use CPU clock with no prescaling
   // CS2 bits 2:0 are all in TCCR2B
   TCCR2B = (1 << CS20);

   // Make sure Compare-match register A interrupt for timer2 is disabled
   TIMSK2 = 0;
   // This value determines the output frequency
   OCR2A = ocr2aval;

   Serial.print("Period    = ");
   Serial.print(period);
   Serial.println(" microseconds");
   Serial.print("Frequency = ");
   Serial.print(freq);
   Serial.println(" Hz");
}


void loop()
{
   // Do (almost) anything you want here.  Just don't do analogWrite to
   // pins controlled by Timer 2.  In fact, don't do anything that messes
   // with the registers in Timer 2.
}


Try Figuring it out from here, Regards Simon

simonfrfr

Code: [Select]
//
//
// Use of timer2 to generate a signal for a particular frequency on pin 11
//
//

const int freqOutputPin = 11;   // OC2A output pin for ATmega328 boards
//const int freqOutputPin = 10; // OC2A output for Mega boards

// Constants are computed at compile time

// If you change the prescale value, it affects CS22, CS21, and CS20
// For a given prescale value, the eight-bit number that you
// load into OCR2A determines the frequency according to the
// following formulas:
//
// With no prescaling, an ocr2val of 3 causes the output pin to
// toggle the value every four CPU clock cycles. That is, the
// period is equal to eight slock cycles.
//
// With F_CPU = 16 MHz, the result is 2 MHz.
//
// Note that the prescale value is just for printing; changing it here
// does not change the clock division ratio for the timer!  To change
// the timer prescale division, use different bits for CS22:0 below
const int prescale  = 1;
const int ocr2aval  = 3;
// The following are scaled for convenient printing
//

// Period in microseconds
const float period    = 5.0 * prescale * (ocr2aval+1) / (F_CPU/1.0e6);

// Frequency in Hz
const float freq      = 1.0e6 / period;

void setup()
{
    pinMode(freqOutputPin, OUTPUT);
    Serial.begin(9600);

    // Set Timer 2 CTC mode with no prescaling.  OC2A toggles on compare match
    //
    // WGM22:0 = 010: CTC Mode, toggle OC
    // WGM2 bits 1 and 0 are in TCCR2A,
    // WGM2 bit 2 is in TCCR2B
    // COM2A0 sets OC2A (arduino pin 11 on Uno or Duemilanove) to toggle on compare match
    //
    TCCR2A = ((1 << WGM21) | (1 << COM2A0));

    // Set Timer 2  No prescaling  (i.e. prescale division = 1)
    //
    // CS22:0 = 001: Use CPU clock with no prescaling
    // CS2 bits 2:0 are all in TCCR2B
    TCCR2B = (1 << CS20);

    // Make sure Compare-match register A interrupt for timer2 is disabled
    TIMSK2 = 0;
    // This value determines the output frequency
    OCR2A = ocr2aval;

    Serial.print("Period    = ");
    Serial.print(period);
    Serial.println(" microseconds");
    Serial.print("Frequency = ");
    Serial.print(freq);
    Serial.println(" Hz");
}


void loop()
{
    // Do (almost) anything you want here.  Just don't do analogWrite to
    // pins controlled by Timer 2.  In fact, don't do anything that messes
    // with the registers in Timer 2.
}

Well I decided to do the timer work for you, I tested it out on my Arduino Mega 2560 and I got it to 8MHZ Regards Simon

Mr_arduino

I have my osciloscope set to .05 micro seconds counted 5 divisions did
.00000005 *5 (repical) = 4,000,000 (4mhz) not 8 why is that?

simonfrfr

Could It be that I used the Mega while testing it?

Go Up