0

I am working on project in which I need to display different colors on RGB led. I am using pwm to drive different colors on LED. My Pic is PIC24FJ64GA004 with which I am working on now. Basic concept of this project is to use switch to controls colors.

Colors on RGB led will be according to days and month in year. For that I am using 7-segment led with switch to count days and month.

Problem at the moment is following code. I am trying to change PWM values by following settings. But instead of changing it it is giving me some thing weird. I need your help guys. Could you please help me with this thing.

 for( counter=0x0000;counter<=0x4571;counter++){ 
//*****Timer2 starting from here*****//
PR2                 = 0x4571;   // Initialize PR2 with 0x4571 = 17777 as PWM cycle
IFS0bits.T2IF       = 0;        // Clear Output Compare interrupt flag
IEC0bits.T2IE       = 1;        // Enable Output Compare interrupts
T2CONbits.TON       = 1;        // Start Timer2 with assumed settings
//**********************************//
//*****For RED LED OC1 choosed with timer 2*****//
OC1CONbits.OCM      = 0;        // Output compare channel is disabled
OC1R                = 0x0000 ; // Initialize Compare Register1 with 50% duty cycle
OC1RS               = counter;  // Initialize Secondary Compare Register1 with 50% duty cycle
OC1CONbits.OCSIDL   = 0;        // Output capture will continue to operate in CPU Idle mode
OC1CONbits.OCFLT    = 0;        // No PWM Fault condition has occurred (this bit is only used when OCM<2:0> = 111)
OC1CONbits.OCTSEL   = 0;        // Timer2 is the clock source for output Compare
OC1CONbits.OCM      = 0x6;      // PWM mode on OC, Fault pin disabled

//*****For Green Led OC2 and OC3 Choosed with timer2 as well*****//

OC2CONbits.OCM      = 0;        // Output compare channel is disabled
OC2R                =0x0000;        // Initialize Compare Register1 with 50% duty cycle
OC2RS               =counter;   // Initialize Secondary Compare Register1 with 50% duty cycle
OC2CONbits.OCSIDL   = 0;        // Output capture will continue to operate in CPU Idle mode
OC2CONbits.OCFLT    = 0;        // No PWM Fault condition has occurred (this bit is only used when OCM<2:0> = 111)
OC2CONbits.OCTSEL   = 0;        // Timer2 is the clock source for output Compare
OC2CONbits.OCM      = 0x6;      // PWM mode on OC, Fault pin disabled


//*****For  Blue Led OC2 and OC3 Choosed with timer2 as well*****//
OC3CONbits.OCM      = 0;        // Output compare channel is disabled
OC3R                = 0x0000;           // Initialize Compare Register1 with 50% duty cycle
OC3RS               = counter;  // Initialize Secondary Compare Register1 with 50% duty cycle
OC3CONbits.OCSIDL   = 0;        // Output capture will continue to operate in CPU Idle mode
OC3CONbits.OCFLT    = 0;        // No PWM Fault condition has occurred (this bit is only used when OCM<2:0> = 111)
OC3CONbits.OCTSEL   = 0;        // Timer2 is the clock source for output Compare
OC3CONbits.OCM      = 0x6;      // PWM mode on OC, Fault pin disabled

  }

But this code is working alright. I put different values as well. It works fine.

   //*****For RED LED OC1 choosed with timer 2*****//
OC1CONbits.OCM      = 0;        // Output compare channel is disabled
OC1R                = 0x22B8;   // Initialize Compare Register1 with 50% duty cycle
OC1RS               = 0x22B8;   // Initialize Secondary Compare Register1 with 50% duty cycle
OC1CONbits.OCSIDL   = 0;        // Output capture will continue to operate in CPU Idle mode
OC1CONbits.OCFLT    = 0;        // No PWM Fault condition has occurred (this bit is only used when OCM<2:0> = 111)
OC1CONbits.OCTSEL   = 0;        // Timer2 is the clock source for output Compare
OC1CONbits.OCM      = 0x6;      // PWM mode on OC, Fault pin disabled

//*****For Green Led OC2 and OC3 Choosed with timer2 as well*****//

OC2CONbits.OCM      = 0;        // Output compare channel is disabled
OC2R                =0x22B8;    // Initialize Compare Register1 with 50% duty cycle
OC2RS               =0x22B8;//0x22B8;   // Initialize Secondary Compare Register1 with 50% duty cycle
OC2CONbits.OCSIDL   = 0;        // Output capture will continue to operate in CPU Idle mode
OC2CONbits.OCFLT    = 0;        // No PWM Fault condition has occurred (this bit is only used when OCM<2:0> = 111)
OC2CONbits.OCTSEL   = 0;        // Timer2 is the clock source for output Compare
OC2CONbits.OCM      = 0x6;      // PWM mode on OC, Fault pin disabled


//*****For  Blue Led OC2 and OC3 Choosed with timer2 as well*****//
OC3CONbits.OCM      = 0;        // Output compare channel is disabled
OC3R                = 0x22B8;   // Initialize Compare Register1 with 50% duty cycle
OC3RS               = 0x22B8;   // Initialize Secondary Compare Register1 with 50% duty cycle
OC3CONbits.OCSIDL   = 0;        // Output capture will continue to operate in CPU Idle mode
OC3CONbits.OCFLT    = 0;        // No PWM Fault condition has occurred (this bit is only used when OCM<2:0> = 111)
OC3CONbits.OCTSEL   = 0;        // Timer2 is the clock source for output Compare
OC3CONbits.OCM      = 0x6;      // PWM mode on OC, Fault pin disabled

//*****Timer1 starting from here*****//
PR1                 = 65535;    // Initialize PR2 cycle
T1CONbits.TCKPS     = 2;        // Setting pre-scaler to 1/64
IFS0bits.T1IF       = 0;        // Clear Output Compare interrupt flag
IEC0bits.T1IE       = 1;        // Enable Output Compare interrupts
T1CONbits.TON       = 1;        // Start Timer1 with assumed settings
//*****Timer2 starting from here*****//
PR2                 = 0x4571;   // Initialize PR2 with 0x4571 = 17777 as PWM cycle
IFS0bits.T2IF       = 0;        // Clear Output Compare interrupt flag
IEC0bits.T2IE       = 1;        // Enable Output Compare interrupts
T2CONbits.TON       = 1;        // Start Timer2 with assumed settings
//**********************************//
user12318
  • 33
  • 6
  • 3
    What is "something weird"? – Throwback1986 Feb 14 '13 at 15:56
  • Can you define more clearly a) what you get on the pins and b) what you expected to see on the pins? – Martin Thompson Feb 14 '13 at 16:03
  • Hi there, I want variable PWM on Pins. As I am using RGB LED with three channels going to different pins of LED. I want LED to show me different colors. – user12318 Feb 14 '13 at 16:08
  • I am getting nothing on Pins at the moment. – user12318 Feb 14 '13 at 16:08
  • 1
    Have you verified that you can set up *one* static PWM on *a* pin? If so, work your up from there incrementally. Once it's working on one pin for a fixed freq/duty cycle, get it working on the other pins. Then (and only then!) begin to experiment with variable PWMs on multiple pins. – Throwback1986 Feb 14 '13 at 16:37
  • Hi there , I have done that already and it is working alrite when I write down following code. But Problem is in loop. When ever I put that loop. It resulted into null or zero result on pins. – user12318 Feb 14 '13 at 16:43
  • I have update my code please see working code. – user12318 Feb 14 '13 at 16:45

1 Answers1

2

You are updating your PWMs each time around the loop.

It's very unlikely that the counter has had time to expire, therefore you keep resetting it before it has chance to "do" a PWM cycle.

At the end of the loop, you need to wait for (at least one of) your PWMs to have expired.

An alternative way might be to set up the next value you want in the loop and have an interrupt service routine copy that to the PWM register when the timer expires. And once that has happened, you can set up the next next value :) You need to take care about how you transfer values between the main loop and the ISR as they are effectively different "thread" contexts.

Martin Thompson
  • 16,395
  • 1
  • 38
  • 56
  • Hi there, Is it possible to give some example. I am new to embedded C and need some direction. I understand your concept but I dont know how to implement. Even small demo will be very useful. thanks in advance – user12318 Feb 15 '13 at 12:24
  • Sorry, I'm not familiar enough with your specific chip to just throw off some code that I think would work... and I haven't time at the moment to create something rigourous. – Martin Thompson Feb 15 '13 at 14:06