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.

Dim and Bright for LED



Hi Group,
LED is programmed to switch ON OFF for switch and timer interrupt. Instead of LED switching full ON and full OFF, I want to program LED to ON and OFF by pulse width modulation. For this I planned to use Timer B, because Timer A is already used for automatic OFF of LED. 
Inserted the "for" loop inside ISR of port interrupt and timer interrupt routine. Here is the initializations of timer B. Help me out with this code. Thank you.
======================================================================
#include <msp430x20x3.h>

void main(void)
{
WDTCTL = WDTPW + WDTHOLD;
BCSCTL3 |= LFXT1S_2; 
======
Here input and output Port and timer A initialized
======
======
TBCTL= TBCLGRP | CNTL_0 | MC_0 | TBSSEL_1 | ID_3 | TBCLR; // reset it, first.
TBCCTL0= CCIE; // set the mode.
TBCCR0 = 512-1; // PWM Period
TBCCTL1 = OUTMOD_7; // CCR1 reset/set
TBCTL = TASSEL_1 + MC_1; // ACLK, up mode
IFG1 &= ~OFIFG;
BCSCTL2 = SELM_3 | DIVM_3;
=========

Switch Interrupt routine 1; "For" loop is used for PWM for LED_ON and LED_OFF
=========================
Timer A Interrupt routine; "For" loop is used for PWM for LED_OFF
=========================

  • Shreyas Kumar Krishnappa said:
    TBCTL= TBCLGRP | CNTL_0 | MC_0 | TBSSEL_1 | ID_3 | TBCLR; // reset it, first.

    I'm not sure whether TBCLR will keep the bits you write together with it. They might well be ignored. TO be safe, split this into two instructions.
    Also, for PWM, the timer needs to run in up monde. MC_0 is continuous mode, I think. It shall count up to CCR0 and then start again from 0.

    Shreyas Kumar Krishnappa said:
    TBCTL = TASSEL_1 + MC_1; // ACLK, up mode

    . first, it shoud be TBSSEL_1, not TASSEL_1, then you just overwrite the old settings, clearing ID_3, CNTL_0 and TBCLGRP bits. I don't know why you did set them anyway (except for ID_3).

    Shreyas Kumar Krishnappa said:
    TBCCTL0= CCIE; // set the mode.

    ??? THis enables the CCR0 interrupt which is exedcuted each time TAR counts to CCR0. Which happens every 65536 counts in continuopus mode and every CCR0 counts in up mode. But you don't want an interrupt at all. Just leave the bit clear.

    You don't write anything into TBCCR1. So it keeps its initial value (most likely 0) resulting in SET/RESET happening at the same time. One wins. Always. I don't know which one.

    Also, keep in mind that there is no 100% setting available. There is no TBCCR1 value that will lead to 100% duty cycle. for 0% and 100%, you should switch the TACCR1 to outmode o and set the OUT bit to 0 or 1.

    No need to manually control the LED port pins onvce the PWM is set up. All is done in hardware. You only have to do something if you want to change the duty cycle.

  • Thank you Jens-Michael.

    I did not understand how TACCR1 will control PWM generated from Timer B. I have initialized the output port pin.

    Considering your suggestions, the timer B will look be:

    #include  <msp430x20x3.h>

    BCSCTL3 |= LFXT1S_2;

    Output port, Inout port and other pins are initialized

    TACCR0= xxxxxxx; //xxxxxxx 16-bit number or less than 16-bit number stored here in TACCR0.

    TACTL= MC_1 | TASSEL_1 | ID_3;     // turn it on.

    TACCR1 = OUTMOD_0; // CCR1 reset/set

     

    TBCTL= MC_0 | TBSSEL_1 | ID_3; // reset it, first.

    TBCCR0 = 512-1; // PWM Period

    TBCCTL1 = OUTMOD_7; // CCR1 reset/set

    TBCTL = TBSSEL_1 + MC_1; // ACLK, up mode

    IFG1 &= ~OFIFG;

    BCSCTL2 = SELM_3 | DIVM_3;

    Enable interrupt and LPM3;

    loops starts from here to process service interrupt;

    ===========================

  • Shreyas Kumar Krishnappa said:
    I did not understand how TACCR1 will control PWM generated from Timer B.

    My fault. Should have been TBR not TAR in my last post. (too many TimerA answers to the same problem). Timer B and TimerA are completely independent.
    Of course TBR will count up to TBCCR0 in up mode.

    Sorry that my typo has lead you to a dead end.

    TBCTL= TBCLR; // reset it, first.
    TBCCR0 = 512-1; // PWM Period, 512 TBCLK cycles
    TBCTL = TBSSEL_1 + MC_1; // ACLK, up mode, what about the divider? TBCLK = ACLK?
    TBCCTL1 = OUTMOD_7; // CCR1 reset/set
    IFG1 &= ~OFIFG;
    BCSCTL2 = SELM_3 | DIVM_3;

    With the above setup, noTimerB interrupt will fire. The PWM is running in plain hardware.

**Attention** This is a public forum