This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

problem setting timer and Uart RX interruption together MSP430G2553

Other Parts Discussed in Thread: MSP430G2553

Hello,

My problem is that timer interruption blocks uart interruption. while timer interruption is active,  the microcontroller does not receive data by uart. I want to convert ADC data using timer( for precission), and when I send from pc a character the convertion ends.

thanks, excuse me but my english is no good. I hope you can understand 

#include <msp430g2553.h>

#ifndef TIMER0_A1_VECTOR
#define TIMER0_A1_VECTOR TIMERA1_VECTOR
#define TIMER0_A0_VECTOR TIMERA0_VECTOR
#endif

volatile long tempRaw;
volatile unsigned int i;
volatile int dato;

void FaultRoutine(void);
void ConfigWDT(void);
void ConfigClocks(void);
void ConfigLEDs(void);
void ConfigADC10(void);
void ConfigTimerA2(void);
void EnviarDatos(void);
void ConfigTX(void);


void main(void)
{
ConfigWDT();
ConfigClocks();
ConfigLEDs();
ConfigADC10();
ConfigTX();
ConfigTimerA2();

__enable_interrupt();

while(1)
{
__bis_SR_register(LPM1_bits + GIE);
}
}

void ConfigWDT(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
}

void ConfigClocks(void)
{
if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
FaultRoutine(); // If calibration data is erased
// run FaultRoutine()
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation
BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO
IFG1 &= ~OFIFG; // Clear OSCFault flag
BCSCTL2 |= SELM_0 + DIVM_3 + DIVS_0; // MCLK = DCO/8, SMCLK = DCO/8
}

void FaultRoutine(void)
{
P1OUT = BIT0; // P1.0 on (red LED)
while(1); // TRAP
}

void ConfigLEDs(void)
{
P1DIR = BIT6 + BIT0; // P1.6 and P1.0 outputs
P1OUT = 0; // LEDs off

P1SEL |= BIT1 + BIT2;
P1SEL2 |= BIT1 + BIT2;
}

void ConfigADC10(void)
{
ADC10CTL1 = INCH_3 + ADC10DIV_0 ; // ADC10CLK
ADC10CTL0 = SREF_0 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + MSC;

}

void ConfigTX(void){

UCA0CTL1 = UCSSEL_2 | UCSWRST;
UCA0MCTL = UCBRF_0 | UCBRS_1;
UCA0BR0 = 104;
UCA0BR1 = 0;

UCA0CTL1 &= ~UCSWRST;
IE2 |= UCA0RXIE;


}

void ConfigTimerA2(void)
{
CCTL0 = CCIE;
CCR0 = 33000;
TACTL = TASSEL_2 + MC_1;

}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{

ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start

while ((ADC10CTL1 & ADC10BUSY) == 0x01);

tempRaw = ADC10MEM;
EnviarDatos();

}

}


#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR_HOOK(void)
{

_bic_SR_register_on_exit(LPM1_bits);

}

void EnviarDatos(void){

while (!(IFG2 & UCA0TXIFG));
UCA0TXBUF = tempRaw;
//_delay_cycles(10000);
while (!(IFG2 & UCA0TXIFG));
UCA0TXBUF = tempRaw>>8;

}

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR_HOOK(void)
{
if (IFG2 & UCA0RXIFG) {

if(UCA0RXBUF == 'C'){
//dato = UCA0RXBUF;
P1OUT ^= BIT6;
CCTL0 &= ~CCIE;
}

}

}

  • Yout timer ISR including waiting for the ADC conversion to be ready and transmitting the data over the UART will probably take longer than the time until the next timer interrupt. So there is always a waiting timer interrupt when the timer ISR is finished. Since the timer interrupt has higher priority than the USCI interrupt, the one from the USCI will never be serviced.

    Dennis
  • By default you can serve only one interrupt (ISR) at the same time and when serving an interrupt, interrupts for all other modules are disabled. Therefore you need to keep your ISR’s short; no delays, or for/while loops, or calls to another function.
    And due to this, transmitting data inside your timer ISR is not possible.

    In the Timer ISR you must only start the ADC and move all other lines to the Main:while loop after you enable LPM.
    When the ADC is ready, the exit LPM in your ADC ISR ensures that your main:while will continue after enabling LPM.
  • thanks, Leo and Denis you are right. I did what you said and I could solve the problem.

**Attention** This is a public forum