Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC18f2580 pwm CCP1

Status
Not open for further replies.

Cantafford

Member
Hello,

Using the CCP1 module of the PIC18f2580 I'm trying to send some PWM pulses on the CCP1 pin. I have put an led on it so I can check the voltage across it(simulation software not hardware).
The program is supposed to do the following:
-when no buttons are pressed no votlage across the LED
-while first is pressed 25% PWM duty cycle
-while second is pressed 50%
- third - 75%
-forth - 100%

I have wrote the following program:
Code:
/*
* File:   pwm.c
* Author: Paul
*
* Created on November 20, 2015, 1:22 PM
*/

#include <stdio.h>
#include <stdlib.h>
#include "pwm.h"

void main()
{
    OSCCON = 0b00101110; // internal freq is 250khz
    T2CON = 0b00000101; // TMR2 prescaler is 4
    PR2 = 56/100; // pr is 0.56
    // int pwm8msb = {0b00000000, 0b00000110, 0b00001100, 0b00010010, 0b00011001}; CCPR1L
    // int pwm2lsb = {0b00, 0b01, 0b10, 0b11, 0b00}; DC1B1 and DC1B0
    int i = 0, j=0;
    TRISCbits.RC2 = 0; // led is here
    TRISB = 1; // buttons are here

    // DC1B1:DC1B0 the two LSbs (bit 1 and bit 0) of the 10-bit PWM duty cycle
    CCP1M3 = 1; // CCP1 configured for PWM mode
    CCP1M2 = 1;
    CCP1M1 = 0;
    CCP1M0 = 0;


    while(1)
    {

         while(PORTBbits.RB0==1 && PORTBbits.RB1 == 1 && PORTBbits.RB2 == 1 && PORTBbits.RB3 == 1) // no voltage%
        {
          CCPR1L = 0b00000000;
          DC1B1 = 0;
          DC1B0 = 0;
        }


         while(PORTBbits.RB0==0 && PORTBbits.RB1 == 1 && PORTBbits.RB2 == 1 && PORTBbits.RB3 == 1) // 25%
        {
          CCPR1L = 0b00000110;
          DC1B1 = 0;
          DC1B0 = 1;
        }

        while(PORTBbits.RB0==1 && PORTBbits.RB1 == 0 && PORTBbits.RB2 == 1 && PORTBbits.RB3 == 1) // 50%
        {
          CCPR1L = 0b00001100;
          DC1B1 = 1;
          DC1B0 = 0;
        }

        while(PORTBbits.RB0==1 && PORTBbits.RB1 == 1 && PORTBbits.RB2 == 0 && PORTBbits.RB3 == 1) // 75%
        {
          CCPR1L = 0b00010010;
          DC1B1 = 1;
          DC1B0 = 1;
        }

         while(PORTBbits.RB0==1 && PORTBbits.RB1 == 1 && PORTBbits.RB2 == 1 && PORTBbits.RB3 == 0) // 100%
        {
          CCPR1L = 0b00011001;
          DC1B1 = 0;
          DC1B0 = 0;
        }

     }
}

This is the header file where the configuration bits are:
Code:
/*
* File:   pwm.h
* Author: Paul
*
* Created on November 20, 2015, 1:20 PM
*/

// PIC18F2580 Configuration Bit Settings

// 'C' source line config statements

#include <xc.h>

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG1H
#pragma config OSC = IRCIO67    // Oscillator Selection bits (Internal oscillator block, port function on RA6 and RA7)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = BOHW     // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3         // Brown-out Reset Voltage bits (VBOR set to 2.1V)

// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = OFF      // MCLR Pin Enable bit (RE3 input pin enabled; MCLR disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON         // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
#pragma config BBSIZ = 1024     // Boot Block Size Select bit (1K words (2K bytes) boot block)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)

#define _XTAL_FREQ 250000

26413ih.png



I have the following problem:
Whenever I push a button I will have some voltage across the LED but no matter what button I press the same voltage will be there. There should be 25, 50, 75 and 100% DC values but only 1 voltage is there for all the presses.
Please let me know what am I doing wrong. Thank you.
 
PR2 is zero.... PR2 can't be zero...

PR2 = 56/100; // This must be a value between 1 and 256 as it has to match the timer 2 ..
What frequency do you need...
125Khz.. prescale of 4 If the PR2 was set to 255 the PWM frequency would be 30hz PR2 = 126 then it would be 61hz..
 
PR2 is zero.... PR2 can't be zero...

PR2 = 56/100; // This must be a value between 1 and 256 as it has to match the timer 2 ..
What frequency do you need...
125Khz.. prescale of 4 If the PR2 was set to 255 the PWM frequency would be 30hz PR2 = 126 then it would be 61hz..

Ok I have modified the PR2 value. For 61hz the led would blink too fast so I choose the following values: Oscillator Freq = 125Khz, PR2 = 2, TMR2 presc = 4. So I obtained a frequency of 2.6 KHz.
I still have the same problem: No matter what switch I press I only see one value of voltage across the LED no matter the duty cycle.
Am I doing something wrong in setting the duty cycle in the code below?

Code:
while(1)
    {

         while(PORTBbits.RB0==1 && PORTBbits.RB1 == 1 && PORTBbits.RB2 == 1 && PORTBbits.RB3 == 1) // no voltage%
        {
          CCPR1L = 0b00000000;
          DC1B1 = 0;
          DC1B0 = 0;
        }


         while(PORTBbits.RB0==0 && PORTBbits.RB1 == 1 && PORTBbits.RB2 == 1 && PORTBbits.RB3 == 1) // 25%
        {
          CCPR1L = 0b00000110;
          DC1B1 = 0;
          DC1B0 = 1;
        }

        while(PORTBbits.RB0==1 && PORTBbits.RB1 == 0 && PORTBbits.RB2 == 1 && PORTBbits.RB3 == 1) // 50%
        {
          CCPR1L = 0b00001100;
          DC1B1 = 1;
          DC1B0 = 0;
        }

        while(PORTBbits.RB0==1 && PORTBbits.RB1 == 1 && PORTBbits.RB2 == 0 && PORTBbits.RB3 == 1) // 75%
        {
          CCPR1L = 0b00010010;
          DC1B1 = 1;
          DC1B0 = 1;
        }

         while(PORTBbits.RB0==1 && PORTBbits.RB1 == 1 && PORTBbits.RB2 == 1 && PORTBbits.RB3 == 0) // 100%
        {
          CCPR1L = 0b00011001;
          DC1B1 = 0;
          DC1B0 = 0;
        }

     }
 
PR2 is the period...... You will only have 2 bit resolution..... 00 ( off) 01(33%) 10(66%) and 11( full on )..

Realistically you need PR2 as high as possible.. Make PR2 higher than 64... then timer2 has quite a count within the time period!!
 
PR2 doesn't determine blink frequency.... The frequency doesn't change only the duty cycle..

If PR2 was 255 that would give 10 bits ( using CCP1CON bits 3&4 ) the CCPR1L is the count of the high part and the rest of timer 2 until it matches PR2

If you set CCPR1L to 127 the timer would start the count and set the pin high until it matches the CCPR1H register ( Automatically loaded via CCPR1L and the other two bits ) Then sets the pin low until it matches PR2...
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top