Go Down

Topic: How can I create a 2MHz frequnecy (Read 890 times) previous topic - next topic

ref110

Hello,

I´m new at programming with the Arduino. I work with the Arduino Uno.

I´ve copied this code from the forum:


Code: [Select]

const int freqOutputPin =11; 
const int prescale  = 1;
const int ocr2aval  = 3;

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


const float freq      = 1.0e6 / period;

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


    TCCR2A = ((1 << WGM21) | (1 << COM2A0));


    TCCR2B = (1 << CS20);

   
    TIMSK2 = 0;

    OCR2A = ocr2aval;

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


void loop()
{
   
}


Now I have a problem, because I need SPI for my project, so I need pin 10 to 13 for this.

Can someone change the code that I have a 2MHz output on an other pin.

Or has someone an alternative code for getting a 2MHz output frequency?

Thanks for your answers.

johnwasser

Each timer has two "Output Compare Registers" that output to different pins.  If you use OCR2B instead of OCR2A it the signal will come out on Pin 3 instead of Pin 11.  I think this is how that would be done:


Code: [Select]

const int freqOutputPin =3; 
const int prescale  = 1;
const int ocr2bval  = 3;

const float period    = 2.0 * prescale * (ocr2bval+1) / (F_CPU/1.0e6);


const float freq      = 1.0e6 / period;

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


    TCCR2B = ((1 << WGM21) | (1 << COM2B0));


    TCCR2B = (1 << CS20);  // No prescale

   
    TIMSK2 = 0;

    OCR2B = ocr2bval;

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


void loop()
{
   
}


Now I have a problem, because I need SPI for my project, so I need pin 10 to 13 for this.

Can someone change the code that I have a 2MHz output on an other pin.

Or has someone an alternative code for getting a 2MHz output frequency?

Thanks for your answers.
[/quote]
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

davekw7x

#2
Jul 01, 2011, 06:56 pm Last Edit: Jul 01, 2011, 07:19 pm by davekw7x Reason: 1

I´ve copied this code from the forum:

You're welcome.  (See Footnote.)


Quote from: ref110
Can  someone change the code that I have a 2MHz output on an other pin.


How about Pin 3?
Code: [Select]

const int freqOutputPin = 3;  
const int ocr2aval  = 3;

// These are not needed to generate the code.  They are simply to remind the user
// what the frequency is.  Note that changing the value of "prescale" here does
// not affect the counter operation.  It's just for the printout vlaue
const int prescale  = 1;
const float period    = 2.0 * prescale * (ocr2aval+1) / (F_CPU/1.0e6);
const float freq      = 1.0e6 / period;

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

   // Toggle OC2B on "compare match".
   // Normal count mode with OCRA as "top"
   TCCR2A = ((1 << WGM21) | (1 << COM2B0));

   // Prescale divider value = 1
   // If you want to change the prescale value, look at the ATmega
   // data sheet for the appropriate values of CS22:0
   //
   TCCR2B = (1 << CS20);

   // Not really needed here, since TIMSK is initialized
   // to zero, but for general use, it's probably not
   // a bad idea to make sure timer 2 interrupts are
   // disabled.
   TIMSK2 = 0;
 
   // This is the "top" value at which the counter will reset
   OCR2A = ocr2aval;

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

// Timer 2 Output is directly connected to the designated OCR pin, so
// program intervention is not required to do anything with it.
//
void loop(){
   //
   // Do just about anything you want to here, but if you mess
   // with Timer 2, you may affect the output on its OCR pin.
   //
}


Tested on ATmega 328 Arduino boards.


Regards,

Dave

Footnote:
We contribute to the forum in hopes that people can learn from the code.  Because of the power and versatility of the timer functions on ATmega chips (and, therefore, the complexity), it's hard for most of us to wade through the data sheet.  That's why I sometimes post complete programs.  (And I always test any complete programs that I post.)

If people (even beginners) are really interested, they can go back through the data sheet and, maybe, see why these registers are set up like this.  Maybe the few comments that I put here will help.  There were more comments in http://arduino.cc/forum/index.php/topic,62964.0.html.  Sometimes my propensity for wordiness confuses people, or maybe it just wears them down.

Oh, well...

Go Up