120 kHz square wave generator

Hi

I'm new to arduino, but I was wondering if I can use my arduino uno to create a 120 kHz square wave signal? I know about the tone() function, but as far as I tell it can't generate a 120 kHz signal.
Any help would be appreciated :).

check how to program timers - google nick gammon timer ==> Gammon Forum : Electronics : Microprocessors : Timers and counters

Also, google "arduino PWM secrets" for info in changing the PWM frequencies.

You can also try something like this

``````void setup(){
pinMode (2, OUTPUT); // D2 as output pin
void loop(){

PORTD = PORTD | B00000100; // D2 high
PORTD = PORTD & B11111011; // D2 low

}
``````

and see what kind of output frequency you can achieve
120KHz is a period of 8.33uS, so you could try adding
delayMicroseconds(3);
after each if its too fast,
or some No-Op commands using assembly instructions

The commands to implement
void loop(){
}
take some time too any may introduce what looks like jitter in the output.

You can get close to 120KHz but not exact, because 120kHz is not an exact divisor of 16MHz. Here is the code I use to generate a square wave of a defined frequency on pin 9 of a Uno:

``````const int ocr1aPin = 9;

// Set the frequency that we will get on pin OCR1A
void setFrequency(uint16_t freq)
{
uint32_t requiredDivisor = (F_CPU/2)/(uint32_t)freq;
uint16_t prescalerVal;
uint8_t prescalerBits;
if (requiredDivisor < 65536UL)
{
prescalerVal = 1;
prescalerBits = 1;
}
else if (requiredDivisor < 8 * 65536UL)
{
prescalerVal = 8;
prescalerBits = 2;
}
else if (requiredDivisor < 64 * 65536UL)
{
prescalerVal = 64;
prescalerBits = 3;
}
else if (requiredDivisor < 256 * 65536UL)
{
prescalerVal = 256;
prescalerBits = 4;
}
else
{
prescalerVal = 1024;
prescalerBits = 5;
}

uint16_t top = ((requiredDivisor + (prescalerVal/2))/prescalerVal) - 1;
TCCR1A = 0;
TCCR1B = (1 << WGM12) | prescalerBits;
TCCR1C = 0;
OCR1A = (top & 0xFF);
}

// Turn the frequency on
void on()
{
TCNT1H = 0;
TCNT1L = 0;
TCCR1A |= (1 << COM1A0);
}

// Turn the frequency off and turn of the IR LED
void off()
{
TCCR1A &= ~(1 << COM1A0);
}

void setup()
{
digitalWrite(ocr1aPin, LOW);
pinMode(ocr1aPin, OUTPUT);
}
``````

Call setFrequency(f) to set the desired frequency f, then call on() to start the signal and off() to stop it.

``````void setFrequency(uint16_t freq)
``````

Bit difficult to express 120kHz in a 16 bit variable.

AWOL:

``````void setFrequency(uint16_t freq)
``````

Bit difficult to express 120kHz in a 16 bit variable.

An excellent observation! Needs to be changed to:

``````void setFrequency(uint32_t freq)
``````

in order to support frequencies >65535 Hz.

Replace the 16MHz crystal with a 12MHz one. Then you could get it exact.