Take the 2-minute tour ×
Arduino Stack Exchange is a question and answer site for developers of open-source hardware and software that is compatible with Arduino. It's 100% free, no registration required.

I need to obtain a PWM frequency of at least 125Khz. I plan to drive a pair of mosfets using this PWM as the driver signal. The below code gives 1Khz frequency. Can I just change the delay values to obtain a lower time period, and thereby a higher frequency?

void setup()
{
  pinMode(13, OUTPUT);
}

void loop()
{
  digitalWrite(13, HIGH);
  delayMicroseconds(100); // Approximately 10% duty cycle @ 1KHz
  digitalWrite(13, LOW);// can i change the delay to 1 and 9 for a totaL T=10micro sec and hence f=100khz?
  delayMicroseconds(900);
}

Update: on looking up the answers provided i stumbled across a few tutorials. I used the code below and it resulted in 125Khz and 1.6 Mhz(measured with a CRO, not simulation). But the code was supposed to provide 250Khz and 8Mhz.

My requirement of 125Khz is satisfied, but just curious to know why the sketch not working as it should

2nd Sketch:

// A sketch that creates an 8MHz, 50% duty cycle PWM and a 250KHz,
// 6bit resolution PWM with varying duty cycle (changes every 5μs
// or about every period.

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
 pinMode(3, OUTPUT); // output pin for OCR2B
 pinMode(5, OUTPUT); // output pin for OCR0B

// Set up the 250KHz output (but cro measures only 125khz)
 TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
 TCCR2B = _BV(WGM22) | _BV(CS20);
 OCR2A = 63;
 OCR2B = 0;

// Set up the 8MHz output
 TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM01) | _BV(WGM00);
 TCCR0B = _BV(WGM02) | _BV(CS00);
 OCR0A = 1;
 OCR0B = 0;


// Make the 250KHz rolling
while (1) {
_delay_us(5);
if ( OCR2B < 63 )
OCR2B += 5;
else
OCR2B = 0;

} }

share|improve this question
    
The rolling part made it difficult to see on my scope, getting rid of that and setting OCR2B to 30 I seem to get a 250Khz waveform. Strange. –  darwinawardee Mar 26 at 16:22

2 Answers 2

It's a bit beyond the normal Arduino capabilites so you need to delve into setting some of the registers for your ATMEGA chip directly. See the "Using the ATmega PWM registers directly" http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM

share|improve this answer
2  
I fully agree with your advice, but I would consider this kind of timer programming perfectly within the "normal Arduino capabilities". –  microtherion Mar 18 at 5:25
1  
microtherion, what I meant was it's outside the "Arduino language" set of functions that will work across many varients of AVR (such as delay, digitalWrite etc.) and instead delving into registers that will likely be specific to a given AVR chip. –  darwinawardee Mar 26 at 14:30

Yes, you can reduce the delay.

From the documentation: "This function works very accurately in the range 3 microseconds and up. We cannot assure that delayMicroseconds will perform precisely for smaller delay-times."

Note that, there are a few cycles between the delays, so as you get shorter timeperiods, you will get less and less accuracy.

You could hand-code the delay, I would imagine you could get up to 1mhz, but with little control over the duty cycle (at that frequency).You would need to disable interrupts, and you could do nothing else at all.

If you want still more, you could set a fuse on the AtMega, and get your native clock speed out on of pin 14 CKO (this shows up as digital pin 8 on the arduino board) - I would expect a 50% duty cycle; you will have NO control over - you can't switch it on or off, or affect the duty cycle. It can be used to run multiple chips off the same clock.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.