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.

Sending ADC values via UART using MSP430F2274

Hi,

I m new to coding msp. I am trying to take an analog input from an ultrasonic sensor, do an adc on it and send the output via uart to the computer so that i can see it on bray's terminal. ADC input pin is P2.0. The following is the code -

 

#include "msp430x22x4.h"

void main(void)

WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

 ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE;
  TACCR0 = 30;                              // Delay to allow Ref to settle
  TACCTL0 |= CCIE;                          // Compare-mode interrupt.
  TACTL = TASSEL_2 + MC_1;                  // TACLK = SMCLK, Up mode.
  __bis_SR_register(CPUOFF + GIE);          // LPM0, TA0_ISR will force exit
  TACCTL0 &= ~CCIE;                         // Disable timer Interrupt
  ADC10AE0 |= 0x01;                         // P2.0 ADC option select
  P3DIR |= 0x01;                            // Set P3.0 to output direction
BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
  DCOCTL = CALDCO_1MHZ;
  P3SEL = 0x30;                             // P3.4,5 = USCI_A0 TXD/RXD
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 104;                            // 1MHz 9600
  UCA0BR1 = 0;                              // 1MHz 9600
  UCA0MCTL = UCBRS0;                        // Modulation UCBRSx = 1
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, interrupts enabled
  for (;;)
  {
    ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
    __bis_SR_register(CPUOFF + GIE);        // LPM0, ADC10_ISR will force exit
__interrupt void USCI0RX_ISR();

   if (ADC10MEM < 0x88)                    // ADC10MEM = A0 > 0.2V?
      P3OUT &= ~0x01;                       // Clear P3.0 LED off
    else
      P3OUT |= 0x01;                        // Set P3.0 LED on


  }
}

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
  __bic_SR_register_on_exit(CPUOFF);        // Clear CPUOFF bit from 0(SR)
}

#pragma vector=TIMERA0_VECTOR
__interrupt void TA0_ISR(void)
{
  TACTL = 0;
  LPM0_EXIT;                                // Exit LPM0 on return
}

//  Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCIAB0RX_VECTOR

__interrupt void USCI0RX_ISR(void)
{
  while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?
  UCA0TXBUF = ADC10MEM;                    // TX -> RXed character
}

 

Here the adc isnt working. Please help me!!

  • You don't need a UART ISR for this. In the ADC ISR, just try this:
    while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?
    UCA0TXBUF = ADC10MEM;                    // TX -> RXed character

    Also note that ADC10MEM value is 10-bit and UCA0TXBUF is only 8-bit. So you might to store ADC10MEM in a variable (called ADCresult for example) and transmit it via the UART twice by doing some math.

  • Hi mux. Hereafter the code I wrote to handle the same problem. It works perfectly.

    #pragma vector=ADC10_VECTOR
    __interrupt void ADC10_ISR(void)
    {
      _BIS_SR(GIE);                 // any interrupt is served even if the current routine is not concluded.
      STIM_POWER_SUPPLY_nSHDN_PxOUT |= STIM_POWER_SUPPLY_nSHDN_PIN;
      if ((ADC10DTC0 & BLOCK_FILLED) == 0)     // check if block 2 has been filled
        for (i=0; i < BLOCK_SIZE; i++)        // Send current block
          {
            UCA0TXBUF = (unsigned char)(ADC_DATA[BLOCK_SIZE+i]>>2);
            while (!(IFG2&UCA0TXIFG));
           }
        else
         for (i=0; i < BLOCK_SIZE; i++)        // Send current block
            {
              UCA0TXBUF = (unsigned char)(ADC_DATA[i]>>2);
              while (!(IFG2&UCA0TXIFG));
            }
      STIM_POWER_SUPPLY_nSHDN_PxOUT &= ~STIM_POWER_SUPPLY_nSHDN_PIN;
    }

    The ADC is set to work in two-block trasfer mode. Each time a new block is completed the results are automatically moved to the buffer ADC_DATA which is 2*BLOCK_SIZE wide. (it is an unsigned int*) and the routine is executed.

    Note that in this example the first 2 LSBs are not transmitted. Anyway you can transfer the whole 10bit digital word of each sample by replacing the instruction:

            UCA0TXBUF = (unsigned char)(ADC_DATA[BLOCK_SIZE+i]>>2);
            while (!(IFG2&UCA0TXIFG));

    whit the following:

            UCA0TXBUF = (unsigned char)(ADC_DATA[BLOCK_SIZE+i]); // send the 8LSBs
            while (!(IFG2&UCA0TXIFG));

            UCA0TXBUF = (unsigned char)(ADC_DATA[BLOCK_SIZE+i]>>8); //send the 8MSBs
            while (!(IFG2&UCA0TXIFG));

     

    If you have any doubts, don't exitate to contact me.

  • hi,

    do u able to complete this. I am trying by using MB12xx ultrasonic sensor. Able to interface the ultrasonic sensor with UART but not with ADC. Can u help me?

**Attention** This is a public forum