Search code examples
cpicpwmxc8

Why this simple PWM doesn't work in xc8


I know there are a lot of examples in internet, but what does need this code to work ?

frecuency oscillator = 4mhz

periode = 0.25us

duty_cicle = 250

Prescale = 16

PR2 = 124

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <pic16f88.h>

#pragma config FOSC = HS  // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

void main ()
{
     while (1)
     {
            CCP1CON = 0x2C; /*activate PWM mode*/
            PR2 = 0x7C;    /*124 (DECIMAL)*/
            T2CON = 0X06; /*prescale 16 */
            CCPR1L = 0X3E;

     }    
}

I want to see :

Period of PWM = 2ms

Dutycicle = 1ms

Sincerilly NIN


Solution

  • First off topic: Don't include pic16f88.h, it's included by xc.h.

    Little more off topic: If you use a more modern part (e.g. PIC16f1619), you can use the MPLAB Code Configurator to generate the TMR2 and CCP code for you. It'll also cost less and have more flash/ram. That device is on the curiosity board ($20).

    On Topic: Your first stop is the datasheet.

    The PWM section has the setup for PWM operation.

    Step1: The timer 2 takes Fosc/4 as an input, which is 1mhz in your case. Target frequency is 500Hz. 1e6/500 = 2k. I'd suggest a prescaler of 16, and pr value of 125. This will give you exactly 500Hz.

    Step2: We want a 50% duty cycle. CCP1L floor(125/2) = 62. CCP1X:CCP1Y = 0.5 * 4 = 2.

    Step 3: Clear the tris bit.

    Step4 and 5: Turn it on

    // Step 1
    TMR2ON = 0;
    TOUTPS = 0;
    T2CKPS = 2;
    PR2 = 250U;
    
    // Step 2
    CCP1L = 62U;
    CCP1X = 1;
    CCP1Y = 0;
    
    // Step 3
    TRISB3 = 0;
    
    // Step 4
    TMR2ON = 1;
    
    // Step 5
    CCP1M = 0xC;
    

    Hope that helps.