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.

understanding serial communication...

Other Parts Discussed in Thread: MSP430F5438A

I am having issues with sending bytes of data back and forth between a computer and

an MSP430. This is the code segments that I am using to handle the serial port on an MSP430F5438A

experimenter board.First is the write serial function:

void write_serial(char data){
    while(!(UCA1IFG&UCTXIFG)){} //wait for empty transmit buffer
    UCA1TXBUF=data; //load data
}

 

next is an interrupt to read the serial port (buffer stores bytes, buffer_ptr is incremented):

//serial port interrupt handler
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR (void)
{   
    /*commands:
     * turn pump (p) on/off (s) is      00000001 ppppssss, returns 00110011
     * turn three_way (t) on/off (s) is 00000010 ttttssss, returns 00110011
     * read sensor (s)                  00000011 ssssssss, returns 00110011
     * set selector (p)                 00000100 pppppppp, returns 00110011
     * home selector()                  00000101 00000000, returns 00110011 
     * reset()                          00000110 00000000, returns 00110011
     * off()                            00000111 00000000, returns 00110011
     * bias_sensor_gate(g,double)       00001000 double, returns 00110011
     * bias_sensor_drain(d,double)      00001001 double, returns 00110011
     * set_pressure(double pres)        00001010 double  , returns 00110011              
     * turn two_way (t) on/off (s)   is 00001011 ttttssss, returns 00110011
     * */
   
    //buffer[buffer_ptr] holds latest data
    buffer[buffer_ptr]=UCA1RXBUF;
    buffer_ptr++;
    __bic_SR_register_on_exit(LPM3_bits);                  
}

next is the initialization:

//init serial port
      P10DIR|=0x01;   //reset USB
      P10OUT&=!0x01;
      for(i=0;i<100;i++){}
      P10OUT|=0x01;
         
      UCA1CTL1|=UCSWRST; //reset
    P5SEL|=BIT7|BIT6;
    P5DIR|=BIT6;  //transmit
    P5DIR&=!BIT7; //receive   
   
    //general settings
    UCA1CTL0 = UCMODE_0;                      //all zeros
    UCA1CTL0 &= ~UC7BIT;                      // 8bit char
    UCA1CTL1 |= UCSSEL_1;                     //ACLK  
   
    //set up baud rate
    UCA1BR0=3;          //reasonably close to 9600 baud
    UCA1BR1=0;
    UCA1MCTL=6;  
    UCA1CTL1 &= ~UCSWRST;     
    UCA1IE|=UCRXIE;

 

Next is the test function that I am using, probably where the problem is:

void test_receive_str(){
    int i;
    //write_serial(READY);
    //expect to receive 10 bytes from scilab test program
    //then dump them out
    clear_buffer();
   
    do{
    write_serial(READY);
    }while(buffer[0]!=ACK);
   
    if(buffer_ptr>=10){
        for(i=0;i<10;i++)
            write_serial(buffer[i]);
        clear_buffer();   
    }
    write_serial(DONE);   
   
    //disable serial port, go to uca3
    P10SEL|=0x01;
    P10OUT&=!0x01;       
}

 

Any advice?...

 

 

 

  • first thing I notice is that teh RX ISR jsut reads to buffer using the current buffer_ptr, no matter what it might be. So it is possible to overwrite the whole ram. The RX ISR should somehow limit writes to buffer if the buffer capacity has been reached.

    THen you don't write how you declared buffer and (mroe important) buffer_ptr. If you didn't declare it volatil, the main loop will possibly never notice that buffer_ptr has been changed by teh ISR, and since the main program doesn't read and clear the buffer, it will eventually overflow and crash the system. The name buffer_ptr is misleading too, as pointers in C are usually memory pointers, pointing to a memory location (a variable storage space or a location inside an array) while in your case, it is rather a fill counter or an index)

    Also (even if the buffer_ptr change is properly recognized) you receive into the buffer, and when the buffer is full, you start sending. hHowever, it taks the same time to send (as you do it in busy waiting) as it took to read, and you only clear the buffer once you have sent the whole buffer. In the meantime, there may have been many bytes arrived and added to the (overflowing) buffer. Worst case, buffer_ptr increases with the same pace you send data (jsut wth an offset), so the buffer is never cleared and finally overwrites all available ram, including the stack.

**Attention** This is a public forum