chipKIT® Development Platform

Inspired by Arduino™

Changing PWM frequency and bit resolution

Created Wed, 17 Aug 2011 20:34:20 +0000 by Rooster


Rooster

Wed, 17 Aug 2011 20:34:20 +0000

Hi there,

I am trying to change the 8 bit resolution of the PWM pin (4 of the 5 pins) to 12 or 16 bit and at the same time change the frequency of the pin from 500Hz to ~16 KHz. I am sure this should be possible however my programming skills are too limited.

Thanks for the help!


GeneApperson

Wed, 17 Aug 2011 23:35:20 +0000

Obviously, you have to bypass the analogWrite function in the abstraction layer and talk directly to the hardware to do this.

You will need to program one of the timers, and one or more of the output compares to do this.

The Output Compare units in the PIC32 can work from either Timer2 or Timer3. The analogWrite code uses Timer2. If you don't need analogWrite to work, I would use Timer2. If you need analogWrite to work as well, use Timer3.

The Output Compare sets the pin when the timer resets. The timer then counts up from 0. The Output Compare resets the pin when the the value in the timer matches the value in the ouput compare register. The counter continues to count up until the count value matches the value in the period register. The timer then resets and it all starts over again.

The frequency of the resulting PWM signal is determined by the clock speed of the timer, and the value in the period register. The clock speed of the timer is determined by the peripheral bus frequency and the prescaler selected. The peripheral bus frequency is 80Mhz (at least this is the default set by the boot loader). The prescaler can be selected to be 1:1, 1:2, 1:4, up to 1:256. So for example, with a 1:8 prescaler selected, the 80Mhz woud be divided down to 10Mhz and that is the timer clock frequency. i.e. the timer counts up 1 every 100ns.

The value in the period register determines when the counter resets. So, for example if you set the period register to 10000, you would get a reset at 10000*100ns, or every 1 ms. This is a frequency of 1Khz.

To get a 12-bit PWM, you could load the period register with 4096 (2^12). With the 1:8 prescaler, this would give a frequency of about 2.4Khz.

This is the overview of what needs to be done.

Gene Apperson Digilent


GeneApperson

Wed, 17 Aug 2011 23:47:23 +0000

The following code will initialize Timer 2 with the 1:8 prescaler and a period value of 4096

T2CONCLR = T2_ON   //turn the timer off
    T2CON = T2_PS_1_8; //set prescaler
    TMR2 = 0;                 //clear the counter
    PR2 = 4096;              //set the period
    T2CONSET = T2_ON; //turn the timer on

The following code will set output compare 1 to use timer2 and a PWM value that would give a 50% duty cycle.

OC1R = 2048;
    OC1CON = OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE;
    OC1CONSET = OC_ON;

This example code is taken (and slightly modified) from the code I wrote for analogWrite. This is in the file wiring_analog.c in the core files. These statements are all writing directly to the peripheral registers for Timer2 and Output Compare 1.

For more complete details, you should refer to the Timer and Output Compare sections of the PIC32 Family Reference Manual that can be downloaded from the Microchip web site.

Gene Apperson Digilent


caroper

Mon, 06 Feb 2012 23:51:42 +0000

Thanks Gene,

Just what I was searching for, I think this explanation should be on the WIKI. I was looking for 10Khz at 10Bit res, I think this gives me what I needed to do the Math now.

Cheers Chris