This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Regarding reception of a frame using asynchronous serial interface

Hello,

I am using STMicroelectronics, ST10F269 evaluation board that works on Keil environment. I am trying establish communication between the board and the PC through RS232 serial interface. I am able to transmit a byte from board to PC and and receive a byte from PC to the board. But I am unable to receive a frame from PC to the board that has 1 start bit, 8 data bits and 1 stop bit. My application wants to receive a frame from the display device and process the commands and sends back a frame from board to the display. Receiving side is like a state machine, till it receives a valid frame, it will be in the while loop, keep checking for incoming characters. Once it receives a valid frame it sends an acknowldegement frame back to display. So the problem is when display sends a frame, board is able to receive only one byte, not the full frame. So could you please give me solution for this.

Thanks & Regards,

Naina

  • "So the problem is when display sends a frame, board is able to receive only one byte, not the full frame. So could you please give me solution for this."

    Probably not, unless you post the code that doesn't work.

    Stefan

  • Have you looked at Keil interrupt-driven, ring-buffered serial IO example?

    I have used that very code to do several block-oriented

    protocols.http://www.keil.com/download/docs/intsio.zip.asp

    You could also try a Search on this forum for "Mark Odell" - as he has also posted an interrupt-driven, ring-buffered UART driver.

  • Oops - just noticed that it was a C166 question, not C51.

    Anyway, all this means is that the specifics of the interrupt-handling will be a little different; the ring-buffer principle remains exactly the same.

    I'm sure you can do your own search to see if there's a ready-made example in the C166 downloads area...

  • Keil for C166 includes example program Traffic. It contains an implementation of interrupt-driven ring-buffered serial I/O using RTX166 Tiny.

    - mike

  • RTX166 shouldn't be necessary for this - just look at the interrupt-driven ring-buffered serial I/O bit!

  • Hello,

    Here is the code for the Thread 4227. Please give me the solution.

    /* Serial initialization */

    SerailInitialize()
    {
    P310 = 1; //set PORT 3.10 output latch (TXD)
    DP310 = 1; /* set PORT 3.10 direction control (TXD output) */
    DP311 = 0; /* reset PORT 3.11 direction control (RXD input)*/

    S0TIC = 0x0045; /* transmit interrupt enable; ILVL = 1; GLVL = 1 ; S0TIE =1; S0TIR=0 */

    S0RIC = 0x0046; /* receive interrupt enable; ILVL = 1; GLVL = 2 ; S0RIE =1; S0RIR=0 */
    S0BG = 0x0081; /* Baud rate set to 9600 baud */
    S0CON = 0x8011; /* set serial mode */
    }

    /* Code to be executed after receving frame*/

    if (ReceiveFrame())
    {
    NetworkState = CmdComplete;
    }

    /* State machine to be executed to send a vaid frame after receiving series of bytes from Display*/

    bit ReceiveFrame (void)
    {
    bit ValidFrame = FALSE;
    char ReceivedByte;
    bit bMsgComplete = FALSE;

    FrameReceiveStatus = WAIT_START;
    while (GetChar(&ReceivedByte)&& !ValidFrame)
    {
    switch (FrameReceiveStatus)
    {
    case WAIT_START: //WAIT_START 1
    // waiting for the 0x55 start byte

    if (ReceivedByte == 0x55)
    {
    Data[0] = ReceivedByte ; FrameReceiveStatus = WAIT_ADDR;
    }
    break;

    case WAIT_ADDR: // waiting for address byte

    Data[1] = ReceivedByte;
    Addr = ReceivedByte; ValidFrame = TRUE;
    FrameReceiveStatus = WAIT_START;
    bMsgComplete = TRUE;
    break;
    }
    }
    return (ValidFrame);
    }

    /* GetChar function to fill a receive buffer with incoming bytes */

    bit GetChar( char *valptr )
    {
    bit rx_buf_filled =FALSE;

    if (rx_buf_rd_ptr != rx_buf_wr_ptr)
    {
    *valptr = *rx_buf_rd_ptr;
    if (++rx_buf_rd_ptr >= &rx_buf[RX_BUF_SIZE])
    rx_buf_rd_ptr = rx_buf;
    rx_buf_filled =TRUE;
    }
    return( rx_buf_filled );
    }

    /* Receive interrupt service routine that writes incoming characters to the buffer */

    void serial_recv(void) interrupt 0x2B
    {
    *rx_buf_wr_ptr = (char)S0RBUF;
    rx_buf_wr_ptr++; //Locate write pointer to next location

    if(rx_buf_wr_ptr >= &rx_buf[RX_BUF_SIZE]) rx_buf_wr_ptr = rx_buf;

    }

  • "Here is the code"

    Please re-post it, taking care to follow the instructions for posting code!
    (3rd bullet point in the 'Notes' - immediately above the 'Message' box).

    Then your formatting will be preserved & we'll be able to read it properly!

  • GetChar() returns false if there are no characters available, so ReceiveFrame() will return after one character unless the entire frame has already been received by the serial ISR before ReceiveFrame() is called.

    Do you really need to use interrupt driven serial comms? The code you have posted looks as though it is intended to loop polling the receive buffer - that rather negates any benefit of using interrupts.

    Stefan