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.
3 comments:
WELL PLEASE HAVE A LOOK ON MY CODE ARE YOU SAYING THAT I SHOULD I DO.
if((!(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.
I 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
}
Post a Comment