Skip to content

Tutorial — Practice 4: PWM

What you will build

Generate PWM with Timer2 and CCP1 to control brightness or motor speed.

  1. 1

    Calculate PR2 for PWM frequency

    With 20 MHz crystal and Timer2 prescaler = 4, PWM frequency is `Fosc / (4 × prescaler × (PR2 + 1))`. For ~1 kHz with PR2=249: verify on paper first. Record PR2 and prescaler in your report.

    Tip: Theory: /en/pwm/

  2. 2

    Configure Timer2

    Write T2CON (prescaler 1:4 or 1:16 per your calculation), load PR2, and enable Timer2. RC2/CCP1 must be output (`TRISC` bit 2 = 0).
    
    								        MOVLW   D'249'
            MOVWF   PR2
            MOVLW   B'00000101'   ; T2CKPS prescaler, encender TMR2
            MOVWF   T2CON
            BCF     TRISC, 2
    							
  3. 3

    Enable CCP1 in PWM mode

    CCP1CON bits 3:0 = 1100 (PWM). CCP1CON bits 5:4 + CCPR1L set duty (10 bits). Start at 50%: `CCPR1L = PR2 / 2`.
    
    								        MOVLW   B'00001100'
            MOVWF   CCP1CON
            MOVLW   D'124'         ; ~50% si PR2=249
            MOVWF   CCPR1L
    							
  4. 4

    Vary duty cycle in your application

    Connect an LED or motor on RC2. Change `CCPR1L` from keyboard, potentiometer (ADC), or a table. Observe brightness or speed. Adapt the pin if you use CCP2 on another port.
  5. 5

    Measure and document in Proteus

    Use the virtual scope on RC2. Capture frequency and duty. Compare with your theoretical calculations. Include formulas in the report.

Before coding, review PWM / CCP: PR2 calculation, duty cycle, and Timer2 setup.

  1. Calculate PR2 for the target PWM frequency (e.g. ~1 kHz).
  2. Configure T2CON, PR2, and CCP1CON in PWM mode.
  3. Write duty to CCPR1L and CCP1CON bits.
  4. Connect load on RC2/CCP1 and vary duty (potentiometer + ADC optional).

Tutorial hub · Exercises