I tried several things but mainly:
In the end, re-reading the user's guide for the nth time, I noticed a paragraph in which it says that the register holding the current count (TAR) is writable (I was sure until then that is read only) and this was the key: when I want to reset the counter, I just write 0 in this register; just to make sure all is well, I also reset TACTL just to make sure the timer restarts - this may not be needed but it works so I left the code in there. Another thing is stopping the timer in the timer ISR by doing TACTL = MC_0 because I want the timer to shut down after the given time, and not keep counting - this makes the mcu go back to sleep mode.
The final version I ended up with is here: I am sure it can be improved but again, it works now and exactly the way I wanted it so I'll keep it this way.
Next thing: play with external interrupts.
[Edit] Now that I figured out how to reset the timer, I changed the code to use a variable to handle the restart and stop of the timer: reset it to 0 when the button interrupt fires, increment it in the timer ISR and stop the timer after a few iterations. This is much more flexible because a) I can stop the timer at the exact time I want (not being dependent on the timer counter and the clock frequency and dividers) and b) I can reuse the timer for other things, changing the behavior based on the TAIV vector. Next step in developing my little app will use this approach.
This comment has been removed by the author.
ReplyDeleteWELL PLEASE HAVE A LOOK ON MY CODE ARE YOU SAYING THAT I SHOULD I DO.
ReplyDeleteif((!(P2IN & BIT0))&& (value>0))
{
value --;
TA1CCR0 = 105;
TA1CCR2 = wave[value];
TA1CCTL2 = OUTMOD_7;
TA1CTL = TASSEL_2 + MC_1;
P2IFG &=~BIT5;
TACTL = MC_0;
}
I am using msp4630G2553.
ReplyDeleteI want to find the time for which an adc value>511 and interpret this time to blink either red or green led.
This is my code.
#include
unsigned int value=0;
void ConfigureAdc(void);
void main(void)
{
{
int t;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
BCSCTL1 = CALBC1_1MHZ;
BCSCTL2 &= ~(DIVS_3);
P1DIR|=BIT0+BIT6;
P1SEL|=BIT1;
P1SEL |= BIT3;
TACTL=TASSEL_2+ID_0+MC_2;
ConfigureAdc(); // ADC set-up function call
__enable_interrupt(); // Enable interrupts.
while(1)
{
__delay_cycles(1000); ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled// Low Power Mode 0 with interrupts enabled
value = ADC10MEM;
if(value>511)
TA1R=0;
else
{
t=TA1R;
if(t<3000000)
{P1OUT&=~(BIT0+BIT6);
P1OUT|=BIT6;
}
else
{P1OUT&=~(BIT0+BIT6);
P1OUT|=BIT0;
}
}
}
}
}
// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
__bic_SR_register_on_exit(CPUOFF); // Return to active mode
}
// Function containing ADC set-up
void ConfigureAdc(void)
{
ADC10CTL1 = INCH_3 + ADC10DIV_3 ;
ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE;
ADC10AE0 |= BIT3; // ADC input enable P1.3
}