This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Control LED brightness using timers and interrupts?

Other Parts Discussed in Thread: MSP430FR5739, MSP430G2553

Hi,

Does anybody knows how can i control led's brightness using timers and interrupts? is there another way of doing that without using PWM?

  • There are two approaches for LED brightness control: current modulation and on-time modulation.

    For current modulation you'll need an adjustable current source. Due to the large offset voltage and the steep current curve, this isn't easy. And the MSP cannot provide any suport. You'd need external hardware for that.

    On-time modulation doesn't give the same result, but almost. Here you switch the LED on for a certain time and leave it off for some time. When the total cycle time is shorter than the brain recognition time, this is converted into a brightness impression. However, the physical brightness is maximum for the ON cycle and zero for the OFF cycle.
    If the cycle time is longer than the recognition threshold, the eye will see flicker. However, this mode is sometimes used to overdrive the LED for higher brightness but keep the rated power below limit (increase visibility, e.g. for bicycle lights).

    Technically, both variants of on-time modulation are PWM.

    Whether you use the PWM hardware support of the MSP timers, or do it with loops and port pin banging in software, it remains PWM.

  • Hi jmc, How about using a digital pot? Sent from my phone

  • Hi


    What i pretend is to "simulate" the pwm (without using the pwm function of the micro).
     By using timers and interrupts, that creates a pwm variation, i want to control the led ibrightness.

    I've searched in the web this code, and i think that this does what i pretend. 

    But i'm having some troubles, doing a similar program in my msp430fr5739 experimenter board.

    #include <msp430g2553.h>

    void main(void){

        WDTCTL = WDT_MDLY_32;                 // Watchdog timer ≈32ms

        IE1 |= WDTIE;                         // enable Watchdog timer interrupts

        P1DIR |= BIT6+BIT0;                   // Green and red LED

        P1SEL |= BIT6;                        // Green LED Pulse width modulation

        TA0CCR0 = 1000;                       // PWM period

        TA0CCR1 = 100;                        // PWM duty cycle, time cycle on vs. off, on 10% initially

        TA0CCTL1 = OUTMOD_7;                  // CCR1 reset/set -- high voltage below count
                                              // and low voltage when past

        TA0CTL = TASSEL_1 + MC_1;             // Timer A control set to submain clock TASSEL_1
                                              // and count up mode MC_1

        _BIS_SR(LPM0_bits + GIE);             // Enter Low power mode 0 with interrupts enabled
    }

    #pragma vector=WDT_VECTOR                 // Watchdog Timer interrupt service routine

      __interrupt void watchdog_timer(void) {

        P1OUT ^= BIT0;                        // Toggle red LED
    }

  • Fernando Quintas said:
    What i pretend is

    I think you mean "intend" - rather than "pretend" ?

    Fernando Quintas said:
    to "simulate" the pwm

    As already noted, it is PWM!

    What it is (PWM) is not affected by how you achieve it (using general-purpose timers or dedicated PWM hardware).

    Fernando Quintas said:
    i'm having some troubles

    What "troubles", exactly, are you having?

    It is impossible to help you to resolve those "troubles" when you don't say what the "troubles" are!!

  • chethu gowda said:
    a digital pot?

    They aren't usually designed for any significant current - are they?

  • I'm sorry for my english.
    The troubles that i'm having are related with the timers.

    I set their duty cycle, but i don't know how can i increase or decrease their duty cycle after. 

  • Fernando Quintas said:
    I set their duty cycle, but i don't know how can i increase or decrease their duty cycle after. 

    Well, when using full hardware support, CCR0 of a timer defines the count cycle (tiemr counts form 0 to CCR0) and the content of CCR1 defines the point at which the output changes state. So changing CCR1 (or one of the other CCRs) changes the duty cycle when using one of the double-action OUTMODEs The second action takes place at the timer rollover on TAR==CCR0. So the output ahs one state for 0..CCRx and then the other state during CCRx..0. So the relation of CCRx to CCR0 gives the duty cycle.

    The hardware-supported software mode lets the timer run from 0 to 65535. You set the moment on which an ouptu shall change by CCRx (including CCR0, this time) and trigger an ISR. Inside the ISR, you change the OUTMODE and increment CCRx for the time the new state shoudl be active before it is changed again. However, this may lead to some problems if you PWM frequency is so high (or one of the high or low times is so short) that the ISR cannot execute fast enough before the time for the next change has already passed. However, it allows different PWM frequenies for each output.

    When you go for the third way, Timer-interrupt controlled manual I/O port pin changes, then you'll also have to fight interupt latencies, execution of other ISRs when you should change the signal etc. Othe rthan that, the method of generating hte itnerrupts ais the same as described in the previous mode: Increment CCRx by the counts until next state change is due. Jsu tthat the state change won't happen automatically but is done by the ISR manually - as soon as it is being executed.

  • Fernando Quintas said:
    how can i control led's brightness using timers and interrupts? is there another way of doing that without using PWM?

    Itt will be PWM anyway, however, it will be a software assisted PWM. For example you run Timer0 in continuous mode, and add the counts required for ON or OFF state  to the relevant CCRx register.

    //--- TACCR0 interrupt service ---------------------------------
    //--- TACCIFG0 will be cleared automatically! ------------------
    #pragma vector=TIMER0_A0_VECTOR
    __interrupt void ccr0_isr(void) {
      if(P1OUT_bit.P0) {
        P1OUT &= ~BIT0;          // switch off LED1
        TACCR0 += 11800;         // OFF time (you may use a variable here)
      } else {
        P1OUT |= BIT0;           // switch ON LED1
        TACCR0 += 200;           // ON time (you may use a variable here)
      }
    }

    I used fixed delays here, but you should use variables instead, in order to change the duty cycle.

  • thanks for the answer, it was very helpful.

  • What if you wanted to control the duty cycle of the generated PWM through an external pot. how would you do that?

  • Shishir Kulkarni said:
    What if you wanted to control the duty cycle of the generated PWM through an external pot. how would you do that?

    Using ADC.

  • Yes, but how do you program the ADC to read this analog input

  • I program it using C programming language, referring to user manual of given part and source code examples.

**Attention** This is a public forum