Created Tue, 28 Jul 2015 08:06:18 +0000 by Suwandy
Tue, 28 Jul 2015 08:06:18 +0000
Hi guys, I'm using ChipKit Uno32 (PIC32MX320F) with system clock 80MHz. I would like to produce PWM with frequency around 10MHz to 30MHz. Is this possible?
The datasheet show calculation of PWM by this equation:
PWM Period = [ (PR + 1) * TPB * (TMR Prescaller Value) ] PWM Frequency = 1 / PWM Period
I tried using Output Compare Module with PWM mode without fault pin (OCM<2:0> 110) I used Timer3 as clock source, 1:1 prescaller, and set the PR3 = 152. I should get
F = 1 / [ (152 + 1) * (1 / 80MHz) * (1) ] F = 522,875.816 Hz or 522KHz
So far this is true. i used oscilloscope to look the frequency and it's true.
But when i go above 800 KHz, the oscilloscope showed nothing. if i feed PR3 = 100, i still got PWM with 792KHz on oscilloscope. But when i go **lower than 100,**the oscilloscope showed nothing?
how can i produce PWM beyond 1 MHz ? Are there better way to approach this than using OCxR module?
Tue, 28 Jul 2015 14:21:28 +0000
Yes, it should work. I'm not sure why it's not working for you. I think you can technically have a PR value down to 1.
Are you sure your oscilloscope can measure frequencies higher than what you're seeing?
*Brian
Wed, 29 Jul 2015 04:25:52 +0000
After re-check i found the culprit. Register that control Duty Cycleis OCxR and OCxRs. To control Duty Cycle, i have to keep ratio of OCxR / PRx below 1. Apparently i left OCxR static and when i tried with lower PRx value for higher frequency, the OCxR value greather than PRx, making the PWM cannot be executed.
int DutyCycle[9];
void setup() {
pinMode(3,OUTPUT);
T3CON &= ~(1<<15); //turn OFF timer3
T3CON &= ~(1<<4);
T3CON &= ~(1<<5); // 00, 1:1 prescaler
TMR3 = 0; //clear timer3 counter
PR3 = 2; //timer3 Period, PR = (FPB / (PWM Freq * PreScal)) - 1
T3CON |= (1<<15); //turn ON timer3
DutyCycle[0] = 0.1f * PR3; //10%
DutyCycle[1] = 0.2f * PR3; //20%
DutyCycle[2] = 0.3f * PR3; //30%
DutyCycle[3] = 0.4f * PR3; //40%
DutyCycle[4] = 0.5f * PR3; //50% DutyCycle
DutyCycle[5] = 0.6f * PR3; //60%
DutyCycle[6] = 0.7f * PR3; //70%
DutyCycle[7] = 0.8f * PR3; //80%
DutyCycle[8] = 0.9f * PR3; //90%
OC1CON &= ~(1<<15); //turn OFF OutputCompare module
OC1CON &= ~(1<<0);
OC1CON |= (1<<1); // 110, PWM mode, faultPin disabled
OC1CON |= (1<<2);
OC1CON |= (1<<3); //timer3 as clock source
OC1R = DutyCycle[4]; //using 50% DutyCycle
OC1RS = DutyCycle[4]; //using 50% DutyCycle
OC1CON |= (1<<15); //turn ON OutputCompare module
}
void loop() {
}
After setting it dynamic for 50% Duty Cycle, everything running okay down to PRx=2 (around 26.66 MHz).
Questions: