+ Post New Thread
Results 1 to 6 of 6
  1. #1
    Full Member level 3
    Points: 1,834, Level: 9

    Join Date
    Sep 2011
    Posts
    156
    Helped
    1 / 1
    Points
    1,834
    Level
    9

    LED fading with PWM + Interrupt Timer

    Hi all, is that possible to implement timer interrupt to a LED fading PWM function?
    microcontroller: 16F628A
    compiler: MikroC

    Objective:
    LED fade in and out slowly by adjusting the PWM.
    I had developed a code that working in this way
    using timer so slowly increase the PWM duty cycle. However, it did not work out to be what i imagine.

    The reason why i need this is because i need to insert this function into another program which able t change the PIC mode with LED blinking function (using interrupt timer as well).


    My code is as below:
    Code:
    signed int i = 0;
    void InitTimer1() 
    {
        T1CON = 0x31;
        TMR1IF_bit = 0;
        TMR1IE_bit = 1;
        INTCON = 0xC0; //
    }
      void Interrupt() {
        if(TMR1IF_bit)
        {
         
          for(i = 0; i < 256; i += 10) // LED is glowing with delay by using timer
          {
           PWM1_Set_Duty(i);
          TMR1H = 0x4E; // set timer
         TMR1L = 0x20; // set timer
          }
          for(i = 250; i >= 0; i -= 10) // LED is fade out with delay by using timer
          {
           PWM1_Set_Duty(i);
          TMR1H = 0x4E; // set timer
         TMR1L = 0x20; // set timer
          }
          TMR1IF_bit = 0;// reset trigger bit
         }
         }
    
    void main()
    {
    TRISB = 0x00;// B3 PWM output
    PWM1_Init(5000);            // Initialize PWM frequency
    //PWM1_Set_Duty(127);
    PWM1_Start();
    
    while (1) {
    
    
        }
    }

    Thank you.

    •   Alt13th February 2018, 14:43

      advertising

        
       

  2. #2
    Super Moderator
    Points: 54,878, Level: 57
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    11,115
    Helped
    2606 / 2606
    Points
    54,878
    Level
    57

    Re: LED fading with PWM + Interrupt Timer

    Hi,

    Donīt run lengthy loops within an ISR.

    Without textual description and without knowing about your interrrupt interval timing, and the dimming timing...I donīt want to go deeper into your code.
    Donīt make it unnecessary difficult for us to help.

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. Thank you.


    1 members found this post helpful.

    •   Alt13th February 2018, 17:17

      advertising

        
       

  3. #3
    Newbie level 5
    Points: 59, Level: 1

    Join Date
    Jan 2018
    Posts
    10
    Helped
    2 / 2
    Points
    59
    Level
    1

    Re: LED fading with PWM + Interrupt Timer

    Give this code a try:
    Code:
    /*
     * File: main_xc8.c
     * Target: PIC16F628A
     * Compiler: XC8 v1.45
     *
     * Description:
     *  Use the PWM output to fade an LED on and off.
     *
     *                     PIC16F628A
     *             +----------:_:----------+
     *        <> 1 : RA2               RA1 : 18 <>
     *        <> 2 : RA3               RA0 : 17 <>
     *        <> 3 : RA4(*)       OSC1/RA7 : 16 <>
     *    VPP -> 4 : RA5/VPP      OSC2/RA6 : 15 <>
     *    GND -> 5 : VSS               VDD : 14 <- 5v0
     *        <> 6 : RB0           PGD/RB7 : 13 <> PGD
     *        <> 7 : RB1/RX/DT     PGC/RB6 : 12 <> PGC
     *        <> 8 : RB2/RX/CK         RB5 : 11 <>
     *    LED <- 9 : RB3/CCP1      PGM/RB4 : 10 <>
     *             +-----------------------:
     *                      DIP-18
     * Notes:
     *  (*) RA4 is an open drain output. Requires an external pull-up for output.
     */
    #include <xc.h>
    
    
    // PIC16F628A Configuration Bit Settings
    // CONFIG
    #pragma config FOSC = INTOSCIO  // 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 enabled)
    #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 = OFF      // 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)
    
    #define _XTAL_FREQ 4000000ul
    
    #define INTCON_T0IF_MASK    (1<<2)
    #define CCP1_CCP1M_PWM_MODE (0b1100)
    #define T2CON_TMR2ON_MASK   (1<<2)
    
    void Init_PIC(void)
    {
        // Diable all interrupts
        INTCON = 0;
        PIE1   = 0;
        OPTION_REG = 0b11111111;
    
        //Turn off comparitors
        CMCON = 0b00000111;
    
        //Set output default low:
        PORTA = 0;
        PORTB = 0;
    
        //Port A Data Direction
        TRISA = 0b00000000;
    
        //Port B Data Direction
        TRISB = 0b00000000;
    
    }
    //
    // Setup CCP1 output for PWM at 5KHz
    //
    void Init_PWM(void)
    {
        T2CON    = 0;                       // Stop TIMER2
        PR2      = ((_XTAL_FREQ/4)/5000)-1; // Set for 5KHz PWM
        CCP1CON  = 0;                       // Stop PWM
        CCPR1L   = 0;                       // Set duty cycle to 0%
        CCPR1H   = 0;
        CCP1CON  = CCP1_CCP1M_PWM_MODE;     // Select PWM mode
        T2CON    = T2CON_TMR2ON_MASK;       // Turn on TIMER2
    }
    //
    // Setup TIMER0 to assert T0IF every 4096 instruction clock cycles
    //
    void Init_TIMER0(void)
    {
        TMR0 = 0;
        // TIMER0 clock source is the internal instruction cycle clock (_XTAL_FREQ/4)
        // PRESCALER assigned to TIMER0
        // PRESCALE set to 1:16
        OPTION_REG &= 0b11010000;
        OPTION_REG |= 0b00000011;
        INTCON     &= ~INTCON_T0IF_MASK;
    }
    
    void main(void)
    {
        unsigned char FadeDirection;
        Init_PIC();
        Init_PWM();
        Init_TIMER0();
    
        FadeDirection = 1;
        for(;;)
        {
            if (INTCON & INTCON_T0IF_MASK)
            {
                INTCON &= ~INTCON_T0IF_MASK;
                if (CCPR1L >= PR2)
                {
                    FadeDirection = (unsigned char)(0-FadeDirection);
                }
                CCPR1L += FadeDirection;
            }
        }
    }
    I tried to write this code to be as portable as possible between XC8 and MikroC.

    All you should need to do is delete the #include <xc.h> and #pragma statements.


    1 members found this post helpful.

    •   Alt14th February 2018, 04:24

      advertising

        
       

  4. #4
    Full Member level 3
    Points: 1,834, Level: 9

    Join Date
    Sep 2011
    Posts
    156
    Helped
    1 / 1
    Points
    1,834
    Level
    9

    Re: LED fading with PWM + Interrupt Timer

    Quote Originally Posted by KlausST View Post
    Hi,

    Donīt run lengthy loops within an ISR.

    Without textual description and without knowing about your interrrupt interval timing, and the dimming timing...I donīt want to go deeper into your code.
    Donīt make it unnecessary difficult for us to help.

    Klaus
    HI Klaus, thanks for giving advice. sorry for my mistake. the timer value that i set is 360ms.
    actually the timing do not need to be accurate. as long as can see the LED slowly fade in and out.
    i just want to implement interrupt timer to PWM LED fading so that later on i can change state with button.
    what i am trying to do is, the LED is slowly glowing and dimming by setting the PWM. I have no idea how can i do this without the loop.


    Quote Originally Posted by Dan1138 View Post
    Give this code a try:
    Code:
    /*
     * File: main_xc8.c
     * Target: PIC16F628A
     * Compiler: XC8 v1.45
     *
     * Description:
     *  Use the PWM output to fade an LED on and off.
     *
     *                     PIC16F628A
     *             +----------:_:----------+
     *        <> 1 : RA2               RA1 : 18 <>
     *        <> 2 : RA3               RA0 : 17 <>
     *        <> 3 : RA4(*)       OSC1/RA7 : 16 <>
     *    VPP -> 4 : RA5/VPP      OSC2/RA6 : 15 <>
     *    GND -> 5 : VSS               VDD : 14 <- 5v0
     *        <> 6 : RB0           PGD/RB7 : 13 <> PGD
     *        <> 7 : RB1/RX/DT     PGC/RB6 : 12 <> PGC
     *        <> 8 : RB2/RX/CK         RB5 : 11 <>
     *    LED <- 9 : RB3/CCP1      PGM/RB4 : 10 <>
     *             +-----------------------:
     *                      DIP-18
     * Notes:
     *  (*) RA4 is an open drain output. Requires an external pull-up for output.
     */
    #include <xc.h>
    
    
    // PIC16F628A Configuration Bit Settings
    // CONFIG
    #pragma config FOSC = INTOSCIO  // 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 enabled)
    #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 = OFF      // 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)
    
    #define _XTAL_FREQ 4000000ul
    
    #define INTCON_T0IF_MASK    (1<<2)
    #define CCP1_CCP1M_PWM_MODE (0b1100)
    #define T2CON_TMR2ON_MASK   (1<<2)
    
    void Init_PIC(void)
    {
        // Diable all interrupts
        INTCON = 0;
        PIE1   = 0;
        OPTION_REG = 0b11111111;
    
        //Turn off comparitors
        CMCON = 0b00000111;
    
        //Set output default low:
        PORTA = 0;
        PORTB = 0;
    
        //Port A Data Direction
        TRISA = 0b00000000;
    
        //Port B Data Direction
        TRISB = 0b00000000;
    
    }
    //
    // Setup CCP1 output for PWM at 5KHz
    //
    void Init_PWM(void)
    {
        T2CON    = 0;                       // Stop TIMER2
        PR2      = ((_XTAL_FREQ/4)/5000)-1; // Set for 5KHz PWM
        CCP1CON  = 0;                       // Stop PWM
        CCPR1L   = 0;                       // Set duty cycle to 0%
        CCPR1H   = 0;
        CCP1CON  = CCP1_CCP1M_PWM_MODE;     // Select PWM mode
        T2CON    = T2CON_TMR2ON_MASK;       // Turn on TIMER2
    }
    //
    // Setup TIMER0 to assert T0IF every 4096 instruction clock cycles
    //
    void Init_TIMER0(void)
    {
        TMR0 = 0;
        // TIMER0 clock source is the internal instruction cycle clock (_XTAL_FREQ/4)
        // PRESCALER assigned to TIMER0
        // PRESCALE set to 1:16
        OPTION_REG &= 0b11010000;
        OPTION_REG |= 0b00000011;
        INTCON     &= ~INTCON_T0IF_MASK;
    }
    
    void main(void)
    {
        unsigned char FadeDirection;
        Init_PIC();
        Init_PWM();
        Init_TIMER0();
    
        FadeDirection = 1;
        for(;;)
        {
            if (INTCON & INTCON_T0IF_MASK)
            {
                INTCON &= ~INTCON_T0IF_MASK;
                if (CCPR1L >= PR2)
                {
                    FadeDirection = (unsigned char)(0-FadeDirection);
                }
                CCPR1L += FadeDirection;
            }
        }
    }
    I tried to write this code to be as portable as possible between XC8 and MikroC.

    All you should need to do is delete the #include <xc.h> and #pragma statements.
    Hi Dan, thanks for sharing your code.
    I cant compile without the xc.h file. do you mind to share it?
    and is your code is fading between all the LEDs that connect to the PIC output?
    actually what i want is setting the PWM duty cycle by using timer. Is that possible to achieve?
    because my final goal is that i will set my PIC into 3 different mode:
    1st mode: LED blink with 300ms interval
    2nd mode: LED blink with 800ms interval
    3rd mode: LED slowly glow and dim.

    so I need a timer interrupt to change between these 3 mode ( delay is not suitable).
    i already done with first 2 mode. now only left PWM.



  5. #5
    Super Moderator
    Points: 69,545, Level: 64
    Achievements:
    7 years registered
    Awards:
    2nd Helpful Member
    betwixt's Avatar
    Join Date
    Jul 2009
    Location
    Aberdyfi, West Wales, UK
    Posts
    11,367
    Helped
    3762 / 3762
    Points
    69,545
    Level
    64

    Re: LED fading with PWM + Interrupt Timer

    XC8.h is propriety information from Microchip but it's free to download as part of the XC8 compiler package (currently v1.45). However, what Dan1138 is suggesting is you can easily convert it to MikroC format. The XC8.h is just a cross reference list of port names and numbers and bit names and numbers. An equivalent must exist for MikroC so if you can substitute it the program should compile. If you can't find it's equivalent, the real XC8.h file will probably work if you download it.

    Things to remember:
    1. The PWM can be set to maximum for full brightness and minimum for 'off'.
    2. The PWM generator is a hardware device, once you configure it, the PWM comes out and stays running unless you reset or configure it again.
    3. Use a spare timer to generate long delays for "1st Mode and 2nd Mode", alternating between maximum and minimum to blink the LED.
    4. For "3rd Mode" use each delay to step up to maximum PWM then down to minimum again in a loop. At each 'tick' you reconfigure the PWM for the next brightness step.

    Brian.
    PLEASE - no friends requests or private emails, I simply don't have time to reply to them all.
    It's better to share your questions and answers on Edaboard so we can all benefit from each others experiences.


    1 members found this post helpful.

    •   Alt14th February 2018, 15:32

      advertising

        
       

  6. #6
    Newbie level 5
    Points: 59, Level: 1

    Join Date
    Jan 2018
    Posts
    10
    Helped
    2 / 2
    Points
    59
    Level
    1

    Re: LED fading with PWM + Interrupt Timer

    There is a bug in my code.

    This line:
    Code:
                if (CCPR1L >= PR2)
    Should be replaced with this line:
    Code:
                if ((CCPR1L < 1) || (CCPR1L >= PR2))


    1 members found this post helpful.

--[[ ]]--