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.

MSP430F5419 UART

well, in my program i will need use two UARTs:

UCA1Rx I will receive serial data. this serial data i will send in UCA2TX,  I try make  aprogram but it's not work.

 

#include "msp430x54x.h"

void main(void)
{
WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer
P7SEL |= 0x03; // Port select XT1

do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
__delay_cycles(10); // Delay for Osc to stabilize
}while (SFRIFG1&OFIFG); // Test oscillator fault flag


P2DIR |= BIT0+BIT1; //
P5SEL |= BIT6+BIT7; // P5.6.7 UART option select
P9SEL |= BIT4+BIT5; //P9.4,5 UART
P9DIR |= 0x10; //P9.4 = output direction
P9DIR &= ~0x20; // P9.5 = input direction
P5DIR |= 0x40;
P5DIR &= 0x20;
//uart 1
UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
UCA1CTL1 |= UCSSEL_1; // CLK = ACLK
UCA1BR0 = 0x06; // 32k/9600 - 3.41
UCA1BR1 = 0x00; //
UCA1MCTL = 0xFB; // Modulation

//uart2
UCA2CTL1 |= UCSWRST; // **Put state machine in reset**
UCA2CTL1 |= UCSSEL_1; // CLK = ACLK
UCA2BR0 = 0x06; // 32k/9600 - 3.41
UCA2BR1 = 0x00; //
UCA2MCTL = 0x0FB; // Modulation
UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA2CTL1 &= ~UCSWRST;

UCA1IE |= UCTXIE + UCRXIE; // Enable USCI_A1 TX/RX interrupt

UCA2IE |= UCTXIE + UCRXIE; // Enable USCI_A2 TX/RX interrupt

__bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/ interrupts enabled
__no_operation(); // For debugger
}


#pragma vector=USCI_A2_VECTOR
__interrupt void USCI_A2_ISR(void)
{
switch(__even_in_range(UCA1IV,4))
{
case 0:break; // Vector 0 - no interrupt
case 2: // Vector 2 - RXIFG
while (!(UCA2IFG&UCTXIFG)); // USCI_A1 TX buffer ready?
UCA2TXBUF = UCA1RXBUF; // TX -> RXed character
break;
case 4:
while (!(UCA2IFG&UCTXIFG)); // USCI_A1 TX buffer ready?
UCA2TXBUF = UCA1RXBUF; // TX -> RXed character

break; // Vector 4 - TXIFG
default: break;
}
}

  • The code is inconsistent in its use of USCI A1 and USCI A2, and you seem to have enabled interrupts for both sides (A1 and A2), but you declared only one handler (for A2).

    Can you tell us a little more of what you are trying to do?

    Good luck!

    Jeff

  • thanks for the atention,

    I wanna receive serial data from GPS and send this serial data to a computer via hyperterminal. It's my first mission.

    After I wanna  send only date and time received from GPS to a computer.

    I will have to create 2 interruptions for A1 and A2 Uarts?

     

     

  • Your current task can be done with one DMA channel and no continuing CPU operation after DMA setup and no interrupt handlers.

    However, with your future plans in mind, I would make a TX queue, an RX queue, and an ISR for each USCI.  (So 2 TX queues, 2 RX queues, and 2 ISRs.)

    The RX ISR stores incoming data into the RX queue.  The TX ISR moves data from the TX queue to the USCI.  The RX ISR should wake up the main program whenever anything of interest comes in -- anything that could cause you to want to transmit something.  At first that might be every character.  Later it might be only the CR at the end of NMEA sentences.

    In main(), process incoming data by reading it out of the RX queues.  Then transmit the data of your choosing (all data or processed data) by putting it into the appropriate TX queue.

    As you put it together, there are lots of people on this forum that can help.

    Good luck!

    Jeff

  • If you can post a example code it will be very helpful.

    It's my first time with msp430 and language C.

    I learn a lot with code examples.

     

    thanks

  • Veronica Pinheiro said:
    I learn a lot with code examples.

    At least if they are commented and/or explained (so the TI examples are unfortunately of limited use)

    The proposal of settign up input/output queues is indeed the best universal solution. I fact, I use it myself and the code automatically adapts to 2 or 4 UARTs with just two ISRs with different entry points. I cannot post ih here for two reasons, first it uses inline assembly that only runs on mspgcc compiler (to allow feeding 4 interrupt vectors with 8 interrupt sources into 2 ISRs with indexed buffers for the 8 different channels), and second, my boss wouldn't really appreciate me giving away code I wrote for him :)

    Anyway, working with queues is the 'last stage' od UART programming, as it has some pitfalls. The 'standard situation' (on IRQ, fetch byte from buffer and write it into TXBUF)  is pretty simple. But what if the buffer runs dry, and what if the first byte is pushed into the buffer? And what to do if the buffer is full? Handling all this so the code will never hang or stop working (which isn't always the same) is a bit more difficult. So I suggest starting with an RX queue first. It is easier, as you only have to react, not to act. Do the TX manually in main(). If this works, you can start implementing a buffer for TX too.

  • #include "msp430x54x.h"
    unsigned char bufferIO [256];
    unsigned char bufferIOReturnCode;
    int pointerBufferIO = -1;

    char bufferIOGetChar ()
    {
    unsigned char returnChar;
    if (pointerBufferIO >= 0)
    {
    returnChar = bufferIO[pointerBufferIO];
    bufferIO[pointerBufferIO] = 0; // Ascii(0) ???
    pointerBufferIO--;
    bufferIOReturnCode = 0;
    return(returnChar);
    }
    else
    {
    bufferIOReturnCode = 1;
    return(0);
    }
    }

    void bufferIOPutChar (char cChar)
    {
    if (pointerBufferIO < 255)
    {
    pointerBufferIO++;
    bufferIOReturnCode = 0;
    bufferIO[pointerBufferIO] = cChar;
    }
    else
    {
    bufferIOReturnCode = 1;
    }

    //
    // Tratamento da interrupção de recepção
    //
    #pragma vector = USCI_A1_VECTOR
    __interrupt void RXInterrupt (void)
    {
    unsigned int continua = 0;
    unsigned char cLido;
    while (continua == 0)
    {
    cLido = UCA1RXBUF;
    if (cLido == '\r')
    {
    P2OUT |= 0x01;
    __delay_cycles(100000);
    P2OUT &= ~0x01;
    __delay_cycles(100000);
    }
    bufferIOPutChar(cLido); // Joga o caractere lido para o buffer
    if (bufferIOReturnCode == 1)
    {
    P2OUT |= 0x01;
    __delay_cycles(100000);
    P2OUT &= ~0x01;
    __delay_cycles(100000);
    }
    else
    {
    continua = 1;
    }
    }
    UCA2IE |= UCTXIE; // Enable USCI_A0 tX interrupt
    }

    /
    // interrupt de transmission
    //
    #pragma vector = USCI_A2_VECTOR
    __interrupt void TXInterrupt (void)
    {
    unsigned char tChar;
    while (!(UCA2IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
    tChar = bufferIOGetChar();
    if (bufferIOReturnCode == 0)
    {
    UCA2TXBUF = tChar;
    }
    else
    {
    P2OUT |= 0x01;
    __delay_cycles(100000);
    P2OUT &= ~0x01;
    __delay_cycles(100000);
    }
    if (tChar == '\r') // Testing o LF (line feed)
    {
    P7OUT |= 0x80;
    __delay_cycles(100000);
    P7OUT &= ~0x80;
    __delay_cycles(100000);
    }
    UCA2IE &= ~UCTXIE; // Disable USCI_A2 TX interrupt
    }

    void main(void)
    {
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    P7SEL |= 0x03; // Port select XT1
    P9SEL |= BIT4; // P9.4 = USCI_A2 TXD
    P5SEL |= 0xB0; // P5.7 = USCI_A1 RXD
    do
    {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
    // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG; // Clear fault flags
    __delay_cycles(100000); // Delay for Osc to stabilize
    }while (SFRIFG1&OFIFG); // Test oscillator fault flag

    P2OUT |= 0x00;
    P7DIR |= 0x80;
    P2DIR |= BIT0+BIT1;

    UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
    UCA1CTL1 |= UCSSEL_1; // ACLK
    UCA1CTL0 |= 0x00;
    UCA1BR0 = 0x06; // 4800
    UCA1BR1 = 0x00; //
    UCA1MCTL |= 0x0FB; // Modulation UCBRSx=1, UCBRFx=0
    UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
    UCA1IE |= UCRXIE; // Enable USCI_A2 RX interrupt

    UCA2CTL1 |= UCSWRST; // **Put state machine in reset**
    UCA2CTL1 |= UCSSEL_2; // aCLK


    UCA2BR0 = 0x06; // 4800
    UCA2BR1 = 0x00; //
    UCA2MCTL |= 0x0FB; // Modulation UCBRSx=1, UCBRFx=0
    UCA2CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
    //UCA2IE |= UCTXIE; // Enable USCI_A2 TX interrupt

    __bis_SR_register(LPM3_bits + GIE); // Enter LPM0, interrupts enabled
    __no_operation(); // For debugger
    }

      It's working, It's sending the serial data. But  in the hyperterminal is showing estrange characters  Not in ASCii .The GPS is garmin 15xL.

    where can be the problem?

     

  • Strange characters can have two reasons:

    first, the baudrate is wrong. Even with a completely wrong baudrate, you will sometimes get some readings, as any any signal on the line will sooner or later produce something that looks like a valid character (as long as the factor between both baudrates is <10, else it will always produce a framing error).

    The other reason is that maybe the data is binary. This means, a value of 32 might be transmitted as binary 32 which is a space character. Other values produce any character that is in the ASCII datasheet, including local special signs.

    P.s.: you should avoid using calls to functions inside ISRs. it makes the ISR slow and prevents the compiler from doing good optimization. If it isn't a large function and mroe than once used, you should inline it.

**Attention** This is a public forum