The **PR2** register in the **PIC16F877A** is used to set the PWM period, which in turn determines the frequency of the PWM signal. See the following simplified PWM block diagram of the PIC16F877A microcontroller.

To calculate the correct **PR2** value for a given PWM frequency, you need to use the following formula:

**PWM Period Calculation Formula:**

$PWM\ Period = \frac{(PR2 + 1) \times 4 \times T_{OSC} \times (TMR2\ Pre\_Scaler)}{}$Where:**PR2**is the value loaded into the PR2 register.**TOSC**is the oscillator period, calculated as $\frac{1}{FOSC}$, where**FOSC**is the clock frequency (e.g., 16 MHz).**TMR2 Pre_Scaler**is the prescaler value selected for Timer2, which can be 1, 4, or 16.

**Rearranging the formula to solve for PR2**:

$PR2 = \left( \frac{PWM\ Period}{4 \times T_{OSC} \times (TMR2\ Pre\_Scaler)} \right) - 1$#### Example: Calculating PR2 for a 5 kHz PWM Frequency (FOSC = 16 MHz, Prescaler = 4)

$T_{OSC} = \frac{1}{16 \, \text{MHz}} = 62.5 \, \text{ns}$**Determine the oscillator period**:

$PWM\ Period = \frac{1}{5 \, \text{kHz}} = 200 \, \mu \text{s}$**Determine the PWM period for 5 kHz**:

$PR2 = \left( \frac{200 \, \mu \text{s}}{4 \times 62.5 \, \text{ns} \times 4} \right) - 1$**Substitute into the formula**:Simplifying:

$PR2 = \left( \frac{200 \times 10^{-6}}{4 \times 62.5 \times 10^{-9} \times 4} \right) - 1 = \left( \frac{200 \times 10^{-6}}{1000 \times 10^{-9}} \right) - 1$ $PR2 = \left( \frac{200}{1} \right) - 1 = 199$

So, for a 5 kHz PWM frequency with a 16 MHz clock and a Timer2 prescaler of 4, the **PR2** value would be **199**.

**General Steps for Calculating PR2**:

- Decide on the desired PWM frequency.
- Calculate the
**PWM period**as $\frac{1}{\text{PWM Frequency}}$. - Use the formula to find the
**PR2**value, adjusting for your oscillator frequency and Timer2 prescaler.

**Prescaler Choices**:

**Prescaler 1**: Better for higher frequencies.**Prescaler 4 or 16**: Better for lower frequencies.

#### Example PR2 Calculation for Other Frequencies:

- For
**1 kHz**PWM frequency, using a 16 MHz clock and prescaler of 16:**PR2 = 249**.

An example code of generating PWM signal with PIC16F877A is provided in the previous tutorial Comparing PIC16F877A vs ATmega328P PWM capabilities.

**Further Reading:**