/* * IR Decoder * Decode and respond to RC5 IR remote control commands, using a TSOP38238SS1V receiver IC * Copyright: Next Gen Industries Pvt Ltd. 2015-16 * */ #include <msp430G2131.h> #define REL_ON BIT0 // REL_ON LED on P1.0 #define SW4 BIT1 // SW4 on P1.1 #define IRDATA BIT2 // IR receiver on P1.2 #define SW3 BIT3 // SW3 on P1.3 #define SW2 BIT4 // SW2 on P1.4 #define SW1 BIT5 // SW1 on P1.5 //#define BAT_SENS BIT6 // BATTERY VOLTAGE SENSING #define LGT2_ON BIT7 // LGT2 LED on P1.7 #define EXIT_LGT BIT6 // EXIT_LGT P2.6 #define LGT1_ON BIT7 // LGT1_ON P2.7 #define T_INTERVAL 2400 // Timing between IRDATA samples - should be closer to 1778 with 1MHz clock, but mine runs fast. //#define DEBUG_PIN BIT5 // For Debugging and setting the Pulse capture timing int data = 0, Flag1 = 1; // Hold the incoming IRDATA stream int command = 0; // The command received int address = 0; // The device address received int toggle = 0; // The toggle bit from the IRDATA stream unsigned int avg_buffer[2]; // buffer for 2 ADC samples unsigned int average; // Average of 2 samples void Setup(void); // Function protos void Sample (void); void Average (void); unsigned long Remote_code; unsigned char Remote_cnt; unsigned char Flag; #define Key_recived BIT0 #define bit_process BIT1 #define Zero_wait_flag BIT2 #define first_flag BIT3 void Init_clock(void) { BCSCTL2 = SELM_0 + DIVM_0 + DIVS_0; if (CALBC1_1MHZ != 0xFF) { /* Follow recommended flow. First, clear all DCOx and MODx bits. Then * apply new RSELx values. Finally, apply new DCOx and MODx bit values. */ DCOCTL = 0x00; BCSCTL1 = CALBC1_1MHZ; /* Set DCO to 1MHz */ DCOCTL = CALDCO_1MHZ; } BCSCTL1 |= XT2OFF + DIVA_0; BCSCTL3 = XT2S_0 + LFXT1S_2 + XCAP_1; } void Init_timer0(void) { TAR=0; TACCTL0 = CM_0 + CCIS_0 + OUTMOD_0 + CCIE; /* TA1CCR0, Timer_A Capture/Compare Register 0 */ TACCR0 = 300; /* * TA1CTL, Timer_A3 Control Register * * TASSEL_2 -- SMCLK * ID_0 -- Divider - /1 * MC_1 -- Up Mode */ TACTL = TASSEL_2 + ID_0 + MC_1; } void main(void) { long int i; WDTCTL = WDTPW | WDTHOLD; // disable watchdog Init_clock(); Setup(); __bis_SR_register(GIE); while(1) { //Sample(); //Average(); // if(average < 840)// Battery voltage based Output cutoff // { // P1OUT |= REL_ON; // Relay On // }else if ( average > 920) //{ // P1OUT &= ~REL_ON; // Relay Off //} //if((P1IN & 0x1D) != 0x1D){ /* if((P1IN & SW1) == 0) { if( Flag1 == 1 ){ P2OUT &= ~LGT1_ON; // LGT1 OFF P1OUT &= ~LGT2_ON; // LGT2 OFF P2OUT &= ~EXIT_LGT; // EXIT LGT OFF Flag1 = 0; i = 55999; // Delay for PushButton Debouncing do i--; while (i != 0); }else{ P2OUT |= LGT1_ON; // LGT1 ON P1OUT |= LGT2_ON; // LGT2 ON P2OUT |= EXIT_LGT; // EXIT LGT ON Flag1 = 1; i = 55999; // Delay for PushButton Debouncing do i--; while (i != 0); } }else if( (P1IN & SW2) == 0 ){ P2OUT ^= EXIT_LGT; // toggle the Exit Light LED when the 0 button is pressed i = 55999; // Delay for PushButton Debouncing do i--; while (i != 0); }else if( (P1IN & SW3) == 0 ){ P2OUT ^= LGT1_ON; // toggle the LGT1 LED when the 0 button is pressed i = 99999; // Delay for PushButton Debouncing do i--; while (i != 0); }else if( (P1IN & SW4) == 0 ){ P1OUT ^= LGT2_ON; // toggle the LGT2 LED when the 0 button is pressed i = 55999; // Delay for PushButton Debouncing do i--; while (i != 0); }*/ // __bis_SR_register(LPM0_bits + GIE); // Go to sleep until Port1 interrupt happens } } void check_data_validity(void) { unsigned int i,repeat; TACCTL0 &=~(CCIE); Flag|=Key_recived; P1IFG &= ~IRDATA; // P2.6 IFG cleared P1IE |= IRDATA; // P2.6 interrupt enabled P1IES |= IRDATA; // P2.6 Hi/lo edge if (Remote_cnt>=13) { switch (Remote_code) { // do whatever we want to do with the incoming commands case 1: if (!repeat) P2OUT ^= LGT1_ON; // toggle the LGT2 LED when the 0 button is pressed i = 9999; // Delay for settling do i--; while (i != 0); break; case 2: if (!repeat) P1OUT ^= LGT2_ON; // toggle the LGT2 LED when the 0 button is pressed break; case 3: if (!repeat) P2OUT ^= EXIT_LGT; // toggle the LGT2 LED when the 0 button is pressed break; case 4: if (!repeat){ if( Flag1 == 1 ){ P2OUT &= ~LGT1_ON; // LGT1 OFF P1OUT &= ~LGT2_ON; // LGT2 OFF P2OUT &= ~EXIT_LGT; // EXIT LGT OFF Flag1 = 0; }else{ P2OUT |= LGT1_ON; // LGT1 ON P1OUT |= LGT2_ON; // LGT2 ON P2OUT |= EXIT_LGT; // EXIT LGT ON Flag1 = 1; } } break; } } else { } } //Initialization void Setup(void) { /* * Set the system clock to use the internal DCO. * Not very accurate, so adjust T_INTERVAL to get the timing right. */ DCOCTL = CALDCO_1MHZ; // select DCO approx. 1MHz BCSCTL1 |= CALBC1_1MHZ; BCSCTL2 &= ~SELS; // SMCLK source P1OUT &= ~LGT2_ON; // OFF LGT2 P1OUT &= ~REL_ON; // RELAY OFF // P1OUT |= DEBUG_PIN; // Set all these HIGH P1DIR |= REL_ON | LGT2_ON; // Set all these as outputs P1DIR &= ~IRDATA; // IRDATA is an input P1REN |= SW1 | SW2 | SW3 | SW4; // SET pullup resistor for SWITCH pins P1DIR &= ~SW1; // SW1 is an input P1DIR &= ~SW2; // SW2 is an input P1DIR &= ~SW3; // SW3 is an input P1DIR &= ~SW4; // SW4 is an input // ANALOG INPUT P1SEL = BIT6; ADC10AE0 = BIT6; //SWITCHES INITIALIZATION P1IE |= IRDATA;// + SW1 + SW2 + SW3 + SW4; // enable interrupts, watching IRDATA for a change, AND SWITCH INTERRUPT P1IES |= IRDATA;// + SW1 + SW2 + SW3 + SW4; // watch for falling edge change on IRDATA AND SWITCHES P1REN |= IRDATA; P1OUT |=IRDATA; P1IFG &= ~IRDATA; // P2.6 IFG cleared // P1IES = SW1; // P1IES = SW2; // P1IES = SW3; // P1IES = SW4; // PORT 2 INITIALIZATION P2OUT = 0x00; // OFF EXIT LIGHT // P2OUT &= ~LGT1_ON; // OFF LGT1 P2DIR = 0xFF; // SET AS OUTPUTS P2IE = 0x00; P2SEL = 0x00; } /* //Take ADC Sample void Sample (void) { unsigned volatile int i, temp; ADC10CTL0 = ADC10ON + REFON + ADC10SHT_1 + MSC + ADC10IE + SREF_1 + REF2_5V; ADC10CTL1 = INCH_6 + CONSEQ_2; // Channel A6, repeat single channel mode ADC10DTC1 = 2; // 4 conversions ADC10SA = (unsigned int)avg_buffer; //Start address for DTC i = 4; // Delay for settling do i--; while (i != 0); ADC10CTL0 |= ENC + ADC10SC; // Enable and start conversions // LPM3; // Enter LPM3 while 4 conversions made ADC10CTL0 &= ~ENC; // Clear ENC to stop conversion ADC10CTL0 = 0; // Turn off ADC and reference } //Average ADC Values void Average (void) { unsigned int i; average = 0; for (i = 0; i < 2; i++) { average += avg_buffer[i]; } average = (average >> 1); }*/ #pragma vector = PORT1_VECTOR; void __interrupt Port_1(void) { P1IFG &= ~IRDATA; // P1.4 IFG cleared P1IE &= ~IRDATA; // P1.4 IFG cleared Init_timer0(); Remote_cnt=0; Remote_code=0; Flag|=first_flag; Flag&=~(bit_process); } #pragma vector = TIMERA0_VECTOR; void __interrupt Timer0(void) { //TACCR0 = 890; unsigned char i, Temp_reg1=0,Temp_reg2=0, Pin_Status; for (i=0;i<1;i++) { if (P1IN&IRDATA) Temp_reg1++; else Temp_reg2++; P2OUT |= LGT1_ON; //for tesing purpose if (Temp_reg1>Temp_reg2) Pin_Status=1; else Pin_Status=0; } P2OUT &= ~LGT1_ON;//for testing if (Flag&first_flag) { Flag &=~(first_flag); if (Pin_Status) { check_data_validity(); } else { TACCR0 = 1820; } } else { if (Flag & bit_process) { Flag&=~(bit_process); if (Flag&Zero_wait_flag) { if(Pin_Status) { check_data_validity(); } else { Remote_code=Remote_code<<1; Remote_code|=0x01; Remote_cnt++; } } else { if(Pin_Status) { Remote_code=Remote_code<<1; Remote_cnt++; } else { check_data_validity(); } } Flag&=~Zero_wait_flag; } else { Flag|=bit_process; if (Pin_Status) { Flag|=Zero_wait_flag; } else { Flag&=~Zero_wait_flag; } } } }
the main problem with the coding is as soon as the first pulse is detected when we press second time, its not getting detected and sometimes the microcontroller resets itself without continuing on to the main program.
I am attaching C code for reference. Pls help to sort out the problem.
Thanks,
Kush