Hi,
I am writing a code with MSP430g2452 for an infrared obstacle detector device, in which a ring of IR transmitters and receivers create 360° detection area. I want to use LPM3 sleep mode and therefore I use the ACLK with no dividers. The idea is to to send a transmission pulse to each emitter one after the other. In order to do so, I set a compare interrupt so the when the timer counts to 5 (I need to create about 3 KHz pulses, so (2*5)/32768 gives me 3276Hz), the interrupt is called and I set the transmission flag. If the transmission flag is not set, the system goes to sleep mode and wakes up when the interrupt is called. In this way, i have the system operate constantly with sleep mode breaks between the interrupts. It all works fine with this approach.
But my problem is this: I want to have much more efficient sleep mode in which i activate the system once in every minute or even an hour, send one full circle of transmission pulses and go to sleep again for another hour, rather that just sleep between interrupts.
but how do I do that? can I set 2 compare interrupts? I need the first interrupt for a short time in order to create the 3KHz pulses and a long one to activate the all system once in a certain time. i have been struggling with this for days and so far I failed to succeed so and I will really appreciate any help!
Thanks in advance,
Levi
#include <msp430.h>
int count = 0;
int flag = 0;
#define LED_150_OUT P1DIR |= BIT1;
#define LED_210_OUT P1DIR |= BIT3;
#define LED_270_OUT P1DIR |= BIT4;
#define LED_330_OUT P1DIR |= BIT5;
#define LED_30_OUT P1DIR |= BIT7;
#define LED_90_OUT P2DIR |= BIT0;
#define BRASS_OUT P2DIR |= BIT1;
#define IO_OUT P2DIR |= BIT2;
#define EN_OUT P2DIR |= BIT3;
#define OUT_IN P1DIR &= ~BIT2;
#define TEST_IN P1DIR &= ~BIT6;
#define LED_150_OFF P1OUT &= ~BIT1;
#define LED_210_OFF P1OUT &= ~BIT3;
#define LED_270_OFF P1OUT &= ~BIT4;
#define LED_330_OFF P1OUT &= ~BIT5;
#define LED_30_OFF P1OUT &= ~BIT7;
#define LED_90_OFF P2OUT &= ~BIT0;
#define BRASS_OFF P2OUT &= ~BIT1;
#define IO_OFF P2OUT &= ~BIT2;
#define EN_OFF P2OUT &= ~BIT3;
#define TOG_LED_150 P1OUT ^= BIT1;
#define TOG_LED_210 P1OUT ^= BIT3;
#define TOG_LED_270 P1OUT ^= BIT4;
#define TOG_LED_330 P1OUT ^= BIT5;
#define TOG_LED_30 P1OUT ^= BIT7;
#define TOG_LED_90 P2OUT ^= BIT0;
#define BRASS_ON P2OUT |= BIT1;
#define EN_ON P2OUT |= BIT3;
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
// Set up 32768Hz crystal
BCSCTL1 |= DIVA_0; // divide by 8
BCSCTL3 |= XCAP_3; // select 12pF caps
TA0CCR0 = 5; // set up terminal count for 3276 Hz
TA0CTL = TASSEL_1 + MC_1; // configure and start timer ACLK, Count up
LED_150_OUT // Set P1.1 to output direction
LED_210_OUT // Set P1.3 to output direction
LED_270_OUT // Set P1.4 to output direction
LED_330_OUT // Set P1.5 to output direction
LED_30_OUT // Set P1.7 to output direction
LED_90_OUT; // Set P2.0 to output direction
BRASS_OUT; // Set P2.1 to output direction
IO_OUT; // Set P2.2 to output direction
EN_OUT; // Set P2.3 to output direction
OUT_IN // Set P1.2 to input direction
TEST_IN // Set P1.6 to input direction
LED_150_OFF
LED_210_OFF
LED_270_OFF
LED_330_OFF
LED_30_OFF
LED_90_OFF
BRASS_OFF
IO_OFF
EN_OFF
CCTL0 = CCIE; // CCR0 interrupt enabled
// __enable_interrupt(); // set GIE in SR
while(1)
{
if (flag == 1){
flag = 0;
EN_ON // enable in high
if ((count > 0) && (count <= 2))
TOG_LED_150 // Toggle P1.1
if ((count > 1) && (count <=3 ))
TOG_LED_210 // Toggle P1.3
if ((count > 2) && (count <= 4))
TOG_LED_270 // Toggle P1.4
if ((count > 3) && (count <= 5))
TOG_LED_330 // Toggle P1.5
if ((count > 4) && (count <= 6))
TOG_LED_30 // Toggle P1.7
if ((count > 5) && (count <= 7))
TOG_LED_90 // Toggle P2.0
if (count == 7)
count=0;
if ((P1IN & 0x04) == 0x04)
{ //if P1.2 is high
BRASS_OFF //Buzzer off
}
else {
BRASS_ON //Buzzer on
}
}
//sleep mode
_BIS_SR(LPM3_bits + GIE);
}
}
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer0_A0 (void)
{ // Timer0 A0 interrupt service routine
count++;
flag = 1;
_BIC_SR(LPM3_EXIT); // wake up from low power mode
}