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.

ADC and UART

Part Number: MSP430FR2355


Tool/software: TI C/C++ Compiler

I use MSP-EXT430FR2355  to realize the ADC and transform  the data from UART.

when I debug ,always get  the warning ,inform me the program  can not execute.

Warning:CPU is OFF (low power mode) and interrupts are disabled! Cannot execute Step/Go.

My program is:

#include "msp430fr2355.h"

unsigned int ADvalue;
unsigned char a[2];
void ADC12Init(void);
void UART0Init(void);

void main(void)
{
 WDTCTL=WDTPW+WDTHOLD;

 CSCTL3 |= SELREF__XT1CLK; // Set XT1 as FLL reference source
 CSCTL0 = 0; // clear DCO and MOD registers
 CSCTL1 = DCORSEL_5; // Set DCO = 16MHz
 CSCTL2 = FLLD_0 + 487; // DCOCLKDIV = 16MHz,16000000/32768-1=487
 CSCTL4 = SELMS__DCOCLKDIV | SELA__XT1CLK; // set XT1 (~32768Hz) as ACLK source, ACLK = 32768Hz

ADC12Init();
UART0Init();
_EINT();

while(1)
{
   ADCCTL0 |= ADCENC | ADCSC; // Sampling and conversion start

   UCA0TXBUF = a[1];
   UCA0TXBUF = a[0];


}
}

void ADC12Init(void)
{

ADCCTL0 &=~ADCENC ;
ADCCTL0 = ADCON;
ADCCTL1 = ADCCONSEQ_0+ADCSHP+ADCSSEL_0;
ADCCTL2 = ADCRES_2;

ADCMCTL0=ADCINCH_0+ADCSREF_0;
ADCIE =ADCIE0 ;
ADCCTL0 |= ADCENC;
}

void UART0Init(void)
{
// Configure UART pins
P1SEL0 |= BIT6 | BIT7; // set 2-UART pin as second function,(1.7TXD,1.6RXD)

// Configure UART
UCA0CTLW0 |= UCSWRST ;
UCA0CTLW0 |= UCSSEL__SMCLK;
UCA0CTLW0 =UCSPB_0+UC7BIT_0; //8 bit transfer,1bit stop

UCA0BR0 = 0x8a; // 16000000/115200
UCA0BR1 = 0x0e;
UCA0MCTLW =UCBRS0;
UCA0IE |= UCTXIE0;
UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
}

#pragma vector=ADC_VECTOR
__interrupt void ADC(void)
{
switch(ADCIV)
{
case ADCIV_0:break;
case ADCIV_2:break;
case ADCIV_4:break;
case ADCIV_6:break;
case ADCIV_8:break;
case ADCIV_10:break;

case ADCIV_12:
ADvalue =ADCMEM0;
a[0]=ADvalue&0xFF;
a[1]=(ADvalue>>8)&0xFF;

ADCCTL0 |=ADCSC;
default:break;
}
}

please help me thanks!

  • > UCA0IE |= UCTXIE0;

    Remove this line. You don't have an ISR for UCA0, so your program will immediately (after _EINT()) vector off to ISR_TRAP.

    More generally, you need interlocks for both the ADC and the UART:

    1) You're setting ADCSC both in main and in the ADC ISR; you should do one or the other. Also, you need to wait for the ADC to complete before sending the result over the UART.

    2) You're writing to UCA0TXBUF without waiting for it to become available (UCTXIFG), so you're losing bytes.

    It may be useful to go through the examples in:

    http://dev.ti.com/tirex/explore/node?node=ACqyBhoKY-mma1YuW1PofA__IOGqZri__LATEST

    [Edit: You're setting the clock to 16MHz without setting the FRAM wait states. See Example msp430fr235x_CS_03.c:

    http://dev.ti.com/tirex/explore/node?node=AKck5cmxoHuBiRVX8QJuhg__IOGqZri__LATEST

    ]

  • Thank you for your reply.  I read the example and try again , but I  receive the ADvalue from  serial port of PC ,the data is full of '0'.

    My program is:

    #include "msp430fr2355.h"
    #include <msp430.h>
    unsigned int ADvalue;
    unsigned char a[2];
    void Software_Trim(); // Software Trim to get the best DCOFTRIM value
    #define MCLK_FREQ_MHZ 16 // MCLK = 16MHz


    /******************************************************************************************
    函数功能:发送一个字节数据
    ****************************************************************************************/
    void UART_Send_Byte(unsigned char mydata) // 发送一个字节
    {
    UCA0TXBUF=mydata; //将数据写到数据发射缓冲器TXBUF1中,等待发射,发送完一个字节的数据为8位
    while(!(UCA0IFG&UCTXIFG)); //UCTXIFG为发送器空标志,若为0表示TXBUF中有数据,为“1”表示TXBUF为空
    //在此等待一个字节的数据发送完
    }

    void main(void)
    {
    WDTCTL=WDTPW+WDTHOLD;

    FRCTL0 = FRCTLPW | NWAITS_1;
    __bis_SR_register(SCG0); // disable FLL
    CSCTL3 |= SELREF__REFOCLK; // Set REFO as FLL reference source
    CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_5;// DCOFTRIM=5, DCO Range = 16MHz
    CSCTL2 = FLLD_0 + 487; // DCOCLKDIV = 16MHz
    __delay_cycles(3);
    __bic_SR_register(SCG0); // enable FLL
    Software_Trim(); // Software Trim to get the best DCOFTRIM value

    CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // set default REFO(~32768Hz) as ACLK source, ACLK = 32768Hz
    // default DCOCLKDIV as MCLK and SMCLK source


    // Configure ADC A0 pin
    P1SEL0 |=BIT0; //使能AD输入,选择的通道为P1.0
    P1SEL1 |=BIT0;
    // Configure UART pins
    P1SEL0 |= BIT6 | BIT7; // set 2-UART pin as second function,(1.7TXD,1.6RXD)
    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high-impedance mode
    // Configure ADC12
    ADCCTL0 |= ADCSHT_2 | ADCON; // ADCON, S&H=16 ADC clks
    ADCCTL1 |= ADCSHP; // ADCCLK = MODOSC; sampling timer
    ADCCTL2 &= ~ADCRES; // clear ADCRES in ADCCTL
    ADCCTL2 |= ADCRES_2; // 12-bit conversion results
    ADCMCTL0 |= ADCINCH_0; // A0 ADC input select; Vref=AVCC

    // Configure UART
    UCA0CTLW0 |= UCSWRST;
    UCA0CTLW0 |= UCSSEL__SMCLK;
    // Baud Rate calculation
    // 16000000/(115200) = 134.88888,134=0x8a
    // Fractional portion = 0.8888
    // User's Guide Table 22-4: UCBRSx = 0xf7
    // UCBRFx = int ( (134.8888-134)*16) = 14
    UCA0BR0 = 0x8a; // 16000000/115200
    UCA0BR1 = 0x00;
    UCA0MCTLW =0xf700 | UCOS16 | UCBRF_1;
    UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI

    ADCIE |= ADCIE0_1; // Enable ADC conv complete interrupt // to activate previously configured port settings


    while(1)
    {
    ADCCTL0 |= ADCENC | ADCSC; // Sampling and conversion start
    __bis_SR_register(LPM0_bits | GIE); // LPM0, ADC_ISR will force exit
    __no_operation(); // For debug only
    a[0]=ADvalue&0xFF;
    a[1]=(ADvalue>>8)&0xFF;
    UART_Send_Byte(a[0]);
    UART_Send_Byte(a[1]);
    }
    }

    // ADC interrupt service routine
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC_VECTOR
    __interrupt void ADC_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
    {
    case ADCIV_NONE:
    break;
    case ADCIV_ADCOVIFG:
    break;
    case ADCIV_ADCTOVIFG:
    break;
    case ADCIV_ADCHIIFG:
    break;
    case ADCIV_ADCLOIFG:
    break;
    case ADCIV_ADCINIFG:
    break;
    case ADCIV_ADCIFG:
    ADvalue = ADCMEM0;
    __bic_SR_register_on_exit(LPM0_bits); // Clear CPUOFF bit from LPM0
    break;
    default:
    break;
    }
    }

    void Software_Trim()
    {
    unsigned int oldDcoTap = 0xffff;
    unsigned int newDcoTap = 0xffff;
    unsigned int newDcoDelta = 0xffff;
    unsigned int bestDcoDelta = 0xffff;
    unsigned int csCtl0Copy = 0;
    unsigned int csCtl1Copy = 0;
    unsigned int csCtl0Read = 0;
    unsigned int csCtl1Read = 0;
    unsigned int dcoFreqTrim = 3;
    unsigned char endLoop = 0;

    do
    {
    CSCTL0 = 0x100; // DCO Tap = 256
    do
    {
    CSCTL7 &= ~DCOFFG; // Clear DCO fault flag
    }while (CSCTL7 & DCOFFG); // Test DCO fault flag

    __delay_cycles((unsigned int)3000 * MCLK_FREQ_MHZ);// Wait FLL lock status (FLLUNLOCK) to be stable
    // Suggest to wait 24 cycles of divided FLL reference clock
    while((CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)) && ((CSCTL7 & DCOFFG) == 0));

    csCtl0Read = CSCTL0; // Read CSCTL0
    csCtl1Read = CSCTL1; // Read CSCTL1

    oldDcoTap = newDcoTap; // Record DCOTAP value of last time
    newDcoTap = csCtl0Read & 0x01ff; // Get DCOTAP value of this time
    dcoFreqTrim = (csCtl1Read & 0x0070)>>4;// Get DCOFTRIM value

    if(newDcoTap < 256) // DCOTAP < 256
    {
    newDcoDelta = 256 - newDcoTap; // Delta value between DCPTAP and 256
    if((oldDcoTap != 0xffff) && (oldDcoTap >= 256)) // DCOTAP cross 256
    endLoop = 1; // Stop while loop
    else
    {
    dcoFreqTrim--;
    CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4);
    }
    }
    else // DCOTAP >= 256
    {
    newDcoDelta = newDcoTap - 256; // Delta value between DCPTAP and 256
    if(oldDcoTap < 256) // DCOTAP cross 256
    endLoop = 1; // Stop while loop
    else
    {
    dcoFreqTrim++;
    CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4);
    }
    }

    if(newDcoDelta < bestDcoDelta) // Record DCOTAP closest to 256
    {
    csCtl0Copy = csCtl0Read;
    csCtl1Copy = csCtl1Read;
    bestDcoDelta = newDcoDelta;
    }

    }while(endLoop == 0); // Poll until endLoop == 1

    CSCTL0 = csCtl0Copy; // Reload locked DCOTAP
    CSCTL1 = csCtl1Copy; // Reload locked DCOFTRIM
    while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
    }

  • >UCA0BR0 = 0x8a; // 16000000/115200
    >UCA0MCTLW =0xf700 | UCOS16 | UCBRF_1;

    Using UCOS16 divides SMCLK by 16 which makes BRW=0x8A much too large (~7kbps). You can adjust one or the other. I suggest removing UCOS16, since that gives you more resolution.

    [Note to archaeologists: Running this code requires patching P1.6/7 (J1) to RXD/TXD (J101, USB side) since the backchannel UART is UCA1.]

**Attention** This is a public forum