Problem with setting Prescaler of timer0 for PWM frequency

Hello Everyone! I m designing DC-DC buck converter. I want to get 62Khz PWM frequency from timer0 of arduino uno. But the code i have constructed according to the site; http://playground.arduino.cc/Main/TimerPWMCheatsheet

isn't working. My code is;

int pwm_1 = 6;
int pwm_2 = 5;
void setup() {
TCCR0B = TCCR0B & 0b11111100 | 0x01;

}

void loop() {
  analogWrite(pwm_2,100);
  analogWrite(pwm_1, 200);
}

is there anything I m missing in it?? tthanks in advance.

It looks like you set the prescaler for a frequency of 62,500 Hz and then set the same PWM values over and over and over and over…

Try moving the analogWrite functions into setup(). Leave loop() empty.

aarg: thanks for your responce.

aarg: Try moving the analogWrite functions into setup(). Leave loop() empty.

I have tried but still the problem remains. I m using proteus 7 to check PWM responce and there is a straight line of 0V means no responce. But when I check this code for 0x02 (setting prescaler to 8 ) and higher it starts working properly. Similarly it also works perfectly when I use timer1 and timer2 setting prescaler to 0x01. What you suggest now??

Well, the article suggests:

TCCR0B = TCCR0B & 0b11111000 | <setting>;

but what you have is:

TCCR0B = TCCR0B	& 0b11111100 | 0x01;

The binary constant you’re ANDing with is different. So it’s possible the lower 3 bits are being set to b101 instead of b001.
However, I haven’t researched the timer functions yet.

Would you believe about the statement written in; http://playground.arduino.cc/Main/TimerPWMCheatsheet that is;

If you change TCCR0B, it affects millis() and delay(). They will count time faster or slower than normal if you change the TCCR0B settings. Below is the adjustment factor to maintain consistent behavior of these functions:

Default: delay(1000) or 1000 millis() ~ 1 second

0x01: delay(64000) or 64000 millis() ~ 1 second 0x02: delay(8000) or 8000 millis() ~ 1 second 0x03: is the default 0x04: delay(250) or 250 millis() ~ 1 second 0x05: delay(62) or 62 millis() ~ 1 second (Or 63 if you need to round up. The number is actually 62.5)

isn't it possible that my problem is actually this one mentioned above??

Just a thought, maybe change timer 1 instead, millis() will still work and you can setup an interrupt to work at 62khz

Keep in mind you will want to use port manipulation rather that analogWrite or digitalWrite...using these functions is SLOW and changes the pin outputs 1 at a time. Port manipulation is 10x faster and can write to multiple output pins at the same exact time, which in your case would be a 20x speed increase...or more considering you are using analogWrite()...

HafizAmmar: Would you believe about the statement written in; http://playground.arduino.cc/Main/TimerPWMCheatsheet that is; isn't it possible that my problem is actually this one mentioned above??

Maybe. You didn't mention anything about using millis() until now. So I assumed you had not even got that far. Did you only post a snippet, and not all your code? And what, specifically, is your problem?

Thanks for your suggestion Ps991!

Ps991: Port manipulation is 10x faster and can write to multiple output pins at the same exact time, which in your case would be a 20x speed increase...or more considering you are using analogWrite()...

I am very much new to arduino and even to programming. I dont know about "Port manipulation" even..!! i just only need a 64khz PWM on timer0, from which way; I don't care. So, could you please post a sample scatch of the method you have mentioned?? Thanks.

HafizAmmar: I dont know about "Port manipulation"

Do you think you are above trying to learn then?

Try This Link.

Thanks aarg!

aarg: You didn't mention anything about using millis() until now. So I assumed you had not even got that far.

Actually I m doing a project on Solar pannel. It has different modules and i m writing code in same pattern. DC-DC buck is one of its modules, in which MOSFET is used to step down voltage using PWM of variable duty cycles on its gate drive. for that purpose I first started to generate PWM of specified freq(64khz) which I failed to generate. Now I don't know weather I will use the millis() function or not.

Did you only post a snippet, and not all your code?

In beginning, as I m only checking for PWM generation of required freq. So, this is all the code I have upto now.

Thanks Delta!
I have read the article and modified my code in this manner;

void setup() {
 TCCR0B = TCCR0B & 0b11111000 | 0x01;  
PORTD = B01100000;
}

void loop() {
}

Is this way you were mentioning??

That will set pins 5 and 6 HIGH at the beginning of the sketch. Actually, it just turns on th epullup resistors since the PIND register isn't set nor is there a pinMode call.

If that is the purpose then it's cool. I thought you wanted to change the state of those pins later. In which case you'll be updating that PORTD to turn pins on and off. But since you've left that part of the code out of your post, I have no idea if that's what you're doing or not.

I didn’t test this, but try it

#define PWM_PIN 8 //any pin, pin 8 is: PORT B bit 0
#define FREQUENCY 64000UL

const unsigned long MASTER_CLOCK = 16000000UL;
const int PRESCALER_1 = 1;
const int PRESCALER_8 = 2;
const int PRESCALER_64 = 3;
const int PRESCALER_256 = 4;
const int PRESCALER_1024 = 5;

boolean pwmPinState = false;

void setup() {
  // put your setup code here, to run once:
  
  //Interupt Service Routine and timer setup
  noInterrupts();// kill interrupts until everybody is set up
  //We use Timer 1, its the only 16 bit timer
  TCCR1A = B00000000;//Register A all 0's since we're not toggling any pins
  TCCR1B = B00001000 | PRESCALER_1;//bit 3 set for CTC mode, will call interrupt on counter match
  TIMSK1 = B00000010;//bit 1 set to call the interrupt on an OCR1A match
  //multiply frequency by 2 because each hertz is 1 stage HIGH, 1 stage LOW
  OCR1A  = (MASTER_CLOCK / (FREQUENCY << 1)) - 1UL;//how often to call our interrupt, must subtract 1
  interrupts();//let the show begin
  
  pinMode(PWM_PIN, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  //nothing in here, not even delay, will ruin your interrupt, it will always run at 64khz or whatever frequency
}

ISR(TIMER1_COMPA_vect){
  //Be aware that you may set PORTB to any byte and it will immediately set all of its pins to those states
  if(pwmPinStatus)
    PORTB &= ~_BV (0); // digitalWrite (8, LOW); pin 8 is: PORT B bit 0
  else
    PORTB |= _BV (0); // digitalWrite (8, HIGH);
  pwmPinStatus = !pwmPinStatus;
}