Search code examples
ctimerinterruptcode-composer

Using port interrupts and timers on CCS


I have a problem with LEDs. 2 buttons as input and 3 LEDs and 7 segment display as output. If we will push choosing button once, we can observe “1” at the 7-segment display. When the confirmation button is pressed, Green LED will be turned on 1second later after that the confirmation button is pushed.

If we will push choosing button twice, we can observe “2” at the 7-segment display. When the confirmation button is pressed, Yellow LED will be turned on 2seconds later, after that the confirmation button is pushed.

If we will push choosing button three times, we can observe “3” at the 7-segment display. When the confirmation button is pressed, Red LED will be turned on 3seconds later, after that the confirmation button is pushed.

i have to using port interrupts and timers. I couldn't find how the LEDs will be turned on 1,2 and 3 seconds later. My code is working but when I pressed confirmation button, instantly is turned on and sometimes delayed. I don't understand. And segments delayed, too. Here is my code:

#include <msp430.h>

#define BUTTON1 0x04 //confirmation Button   P1.2
#define BUTTON2 0x02 

#define Yellow (P1OUT |= 0x10)
#define Red (P1OUT |= 0x20)
#define Green (P1OUT |= 0x08)
#define LedOff (P1OUT &= ~0x38)


int counter =0;

int main(void) {
    WDTCTL = WDTPW|WDTHOLD;

    P2SEL &= ~0x40;
    P1DIR |= (BIT5|BIT4|BIT3); // Set the LEDs on P1.5, P1.4, P1.3 as outputs
    P1OUT = 0;


    P2DIR |= (0x01|0x02|0x04|0x08|0x10|0x20|0x40); //segments

    P1OUT = LedOff;
    P2OUT  = ~0x7F;

    P1IE =BUTTON2|BUTTON1; // interrupt enable
    P1IES=BUTTON2|BUTTON1; //interrupt edge select from high to low
    P1IFG=0x00; 

    BCSCTL3 |= LFXT1S_2; 

    TACTL = TASSEL_2|ID_1|MC_3|TAIE|TACLR;
    TACCR0 = 3000;



    _enable_interrupts();//enable all interrupts


    LPM0;
}

#pragma vector=TIMER0_A1_VECTOR

__interrupt void bahar(void){

                             if(P1IFG==BUTTON2){
                                 P2OUT  = ~0x7F;
                                 counter++;
                                        if(counter==1){
                                             P2OUT = 0x06; // 1
                                        }
                                        if (counter == 2) {
                                             P2OUT = 0x5b; // 2
                                             }
                                        if (counter == 3) {
                                                 P2OUT = 0x4F; // 3
                                                 counter =0;
                                        }

                             }

                             if(P1IFG==BUTTON1){
                                 P1OUT =LedOff;
                                 if (counter == 1) {
                                               Green;
                                              }
                                           if (counter == 2) {
                                               Yellow;
                                           }
                                           if (counter == 0) {
                                              Red;
                                           }
                                        //   TACTL |= TACLR;
                                       }
                             P1IFG=0x00; //clear the interrupt flag
}

Solution

  • P1OUT =LedOff; gets substituted by P1OUT =(P1OUT &= ~0x38)

    Furthermore, you are using the timer interrupt to handle user input. This means your button press will set the button interrupt flag, however it is only after your timer times out that this value gets checked. The LED is currently being set in that same routine.

    • You should use the gpio interrupt handler to handle the button interrupts.
    • Your gpio interrupt should start the timer with the desired timeout.
    • Your timer interrupt handler should disable the timer, and turn on the desired LED.