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
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??
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.
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; Arduino Playground - HomePage
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?
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.
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.
#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;
}