• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

sending stream of bytes...

Status
Not open for further replies.

sanddune008

New Member
Hi,

Setup:
Two PIC's are connected via UART's.

1. How to send a frame of 8 hex bytes over the UART eg: <startofframe :1byte>:<Data :6bytes><Endofframe:1byte>.
a: Do i have send all the 8 bytes as ascii.
eg: if 0x01 = startofframe then do i have send following byte as follows '0','x','0','1' . Then how to send 8 bytes continuously..

2. On the Rx side() how do i decode the 3rd byte of the 8 hex bytes to do a specific task.
There may be circumstance that the frame length may be 4 bytes how do i negotitate this.

As my uart will receive an interrupt on each char byte. how do i design the following.

Thank to all
 

Nigel Goodwin

Super Moderator
Most Helpful Member
If you're sending a specific HEX value as a 'start' byte, then that pretty well means you can't send the data as binary, as it may include the start byte, likewise the 'stop' byte, that can't be included in the data either. So sending the data as ASCII may be your simplest option, although it depends what the data actually is.

You can't send data 'continuously', it's sent 'sequentially', one byte after another, with a stop bit in between every byte.

To check a specifc byte, simply store them in a buffer, and pick the one you want, check it's value using SUBLW or XORLW.
 

sanddune008

New Member
So to send a following byte stream of

<Startbyte> : <Databytes> :<Endbyte>
0x01 : 0xffff : 0x05
Thanks for your time.


first i have convert the following bytes to ascii which is:

'0','x','0','1' etc

is this the way i have send.

How do i decode the same at the receiver.
Which receives interrupt for each byte received .In this case

receives int when received '0' wait till i receive all character in 0x01 and convert back to integer. Is this the way i have to proceed..

correct me if i am wrong.

thanks
 

Nigel Goodwin

Super Moderator
Most Helpful Member
What EXACTLY is the data you're sending?.

Is there any specific reasons you're wanting to use interrupts, polling is the far more common method.
 
Last edited:

sanddune008

New Member
thanks for ur time...

If following is my data frame that is to be sent over UART.
0x01 : 0xffff : 0x09 : 0x05

Is it possible to send it as it is ie, 0x01 whole as hex value and 0x0fff so on
or do i have to convert the first byte 0x01 to ascii which is '0','x','0','1' and send so on till all the frame is sent.

Now at the receiver it becomes complex to decode. as i will be receiving only part of the entire byte (0x01) i.e, first :'0' second ='x' third = '0' and fourth = '1'...if sent each Hex byte as ascii

Is this how i will receive at the UART fifo buffer?....

If so how to go abt it? Is my presumption correct.
 

Nigel Goodwin

Super Moderator
Most Helpful Member
thanks for ur time...

If following is my data frame that is to be sent over UART.
0x01 : 0xffff : 0x09 : 0x05
You're still not telling us what it is, and what it's possible range of values might be - and you've now introduced a bizarre mix of 16 and 8 bit values.

Is it possible to send it as it is ie, 0x01 whole as hex value and 0x0fff so on
or do i have to convert the first byte 0x01 to ascii which is '0','x','0','1' and send so on till all the frame is sent.
The start and end bytes are send as direct binary data, that's the point of them been there. The data bytes in between are send as ASCII characters, two bytes per hexadecimal byte - you don't send the '0x' that's just an instruction to the assembler.

This assumes you need ASCII, but it depends on what you're doing.

Now at the receiver it becomes complex to decode. as i will be receiving only part of the entire byte (0x01) i.e, first :'0' second ='x' third = '0' and fourth = '1'...if sent each Hex byte as ascii
No, the receive routine waits for a byte to arrive, it checks if it's a start byte (0x01), and if it's not, it returns to the waiting loop. Once it receives the start byte it jumps to a data routine, and stores each byte in a sequential data buffer, checking each byte looking for the end byte, when it would exit the buffer routine. You also need to check the size of the buffer, so you don't over fill it, but presumably your application has a specific packet size?.

Assuming the data is sent as ASCII, you could either convert the two bytes back to HEX before storing in the buffer, or do it after the buffer is full.

Personally I'd do it before placing in the buffer.

Is this how i will receive at the UART fifo buffer?....
One byte at a time and move it else where.
 

sanddune008

New Member
You're still not telling us what it is, and what it's possible range of values might be - and you've now introduced a bizarre mix of 16 and 8 bit values.
I have connected two microntroller over uart:

Following is the my frame structure:

<SOP>: <CMD>: <LEN>: <DATA> : <FCS>
SOP: 0x02(1 byte)
CMD : 0x0000-0xffff(3bytes)
Len : 1byte
DATA: based on len
FCS : 0x00-0xFF (1byte)

Now at the receiver side based on the CMD after parsing the frame i do certain specified task like controll relay etc:

So As Per understanding w.r.t explanation i have send the above CMD
as a sequence of 4 ascii characters

Now at the recievers end how will i map the 'CMD' at the receiver buffer. As the data in b/w the start and end byte will be a mix of both 1byte and 2 byte......since u can see that my CMD is of 2bytes but others are of 1 byte.

Basically judging that first byte is CMD and next byte is len etc becomes complex isn't?
 

Nigel Goodwin

Super Moderator
Most Helpful Member
Seems pretty straight forward, is 'data' only ever a short length, or can it get quite long?.

I'm presuming you're writing both ends of the data link?, so write it to keep it simple.

Bear in mind all data is only in bytes, your CMD is just two individual bytes.
 

geko

Active Member
You don't need to convert any of it to ascii,

The code should be stateful so it knows whether it's waiting for a start character or is receiving data.

Even if the data contains a start character, it will only cause a false start if you start receiving in the middle of the datastream which will normally only happen if there's been some problem or the device has just started up. In either case if the checksum is up to the job the received fragment will fail the checksum validation and can be discarded.

Swap the postion of the <CMD> and <LEN> fields so once you see a valid start code, you take the next byte as the data length.

Now you can count the data bytes received so you know when the checksum should arrive.

Once you have what you expect to be the checksum you can either process the frame if the checksum passes or discard it if it doesn't.

You should also validate the length field and restart if it's out-of-bounds; for example one would assume a length of 0 is invalid, if there is a maxium length of data check for that too.

You length field wants to include everything, command, data up to the checksum.
 

sanddune008

New Member
Seems pretty straight forward, is 'data' only ever a short length, or can it get quite long?.
Data length is decided by the len in the frame.It can have max of 255 bytes of data.

Following is my code is this fine

#define INDEXSTART 0
#define MAX_DATA 16
#define DEBUG_FLAG //if debug is set
#define END_OF_PACKET 13
#define STX 2
#define MIN_RX_DATA 2 //Least bytes in a frame
#define VALID_DATA TRUE
#define INVALID_DATA FALSE
#define CMD 2

PUBLIC void Uart1ServiceInterrupt(uint32 u32Device, uint32 u32ItemBitmap)
{
char ReadData;
//uint8 RcvStatus;

/* Read received character from UART and
stop multiple receive interrupts */
vLedControl(0x00, TRUE);
#ifdef DEBUG_FLAG
vPrintf("\n\rIn ISR");
#endif
if(u8AHI_UartReadLineStatus(E_AHI_UART_1)&E_AHI_UART_LS_DR)
{
ReadData = u8AHI_UartReadData(E_AHI_UART_1);
if(ReadData == END_OF_PACKET)
{
if(Index > MIN_RX_DATA)
{
SendBuff[Index] = '\0';
Index = INDEXSTART;
vLedControl(0x01, TRUE);
#ifdef DEBUG_FLAG
vPrintf("\n\rRcvd string:%s",SendBuff);
#endif
RCVDATA = VALID_DATA;
}
else
{
RCVDATA = INVALID_DATA;
#ifdef DEBUG_FLAG
vPrintf("\n\rBufferUnderRun");
#endif
}
}
else
{
#ifdef DEBUG_FLAG
vPrintf("\n\rRcvd:%c",ReadData);
#endif
if((ReadData==STX)&&(Index==0))
{
#ifdef DEBUG_FLAG
vPrintf("\n\rRcvd:SOP");
#endif
Index++;
}
else
SendBuff[Index++] = ReadData;
}
}
if(MAX_DATA==Index)
{
RCVDATA = INVALID_DATA;
#ifdef DEBUG_FLAG
vPrintf("\n\rBufferOverRun");
#endif
Index = INDEXSTART;
}
//Send the status of the received data.
bBosCreateTimer(Bos_UART1ACK_handler_handler,"Hello", 12, 2, &TimerID_Ack);
//while (*pcstring)
//{
// vAHI_UartWriteData(E_AHI_UART_0, *pcstring);
// pcstring++;
// }
}
 

sanddune008

New Member
Following is my code can someone verify:


Code:
#define INDEXSTART                   0
#define MAX_DATA                     16
#define DEBUG_FLAG //if debug is set
#define END_OF_PACKET                13
#define STX                          2
#define MIN_RX_DATA                  2 //Least bytes in a frame
#define VALID_DATA                   TRUE
#define INVALID_DATA                 FALSE
#define CMD                          1

PUBLIC void Uart1ServiceInterrupt(uint32 u32Device, uint32 u32ItemBitmap)
{
    char ReadData;
    uint8 i;
    //uint8 RcvStatus;

     /* Read received character from UART and
      stop multiple receive interrupts */
      vLedControl(0x00, TRUE);
      #ifdef DEBUG_FLAG
      vPrintf("\n\rIn ISR");
      #endif
      if(u8AHI_UartReadLineStatus(E_AHI_UART_1)&E_AHI_UART_LS_DR)
      {
            ReadData = u8AHI_UartReadData(E_AHI_UART_1);
            if(ReadData == END_OF_PACKET)
            {
               if(Index > MIN_RX_DATA)
               {
                    SendBuff[Index] = '\0';
                    Index = INDEXSTART;
                    vLedControl(0x01, TRUE);
                    StringtoNum(SendBuff[0]);
                    #ifdef DEBUG_FLAG
                    vPrintf("\n\rRcvd string:%s",SendBuff);
                    for(i=0;i<strlen(SendBuff);i++)
                    vPrintf("\n\rRcvd string:%x",SendBuff[i]);
                    #endif
                    RCVDATA = VALID_DATA;
                    ackFlag = VALID_DATA;
                   //Send Ack
                   bBosCreateTimer(Bos_UART1ACK_handler_handler,"Hello", 12, 2, &TimerID_Ack);
               }
               else
               {
                    ackFlag = INVALID_DATA;
                    #ifdef DEBUG_FLAG
                    vPrintf("\n\rBufferUnderRun");
                    #endif
                   bBosCreateTimer(Bos_UART1ACK_handler_handler,"Hello", 12, 2, &TimerID_Ack);
               }
            }
            else
            {
                #ifdef DEBUG_FLAG
                vPrintf("\n\rRcvd:%c",ReadData);
                #endif
                if((ReadData==STX)&&(Index==0))
                {
                    #ifdef DEBUG_FLAG
                    vPrintf("\n\rRcvd:SOP");
                    #endif
                    SendBuff[Index++] = ReadData;
                }
                else
                    SendBuff[Index++] = ReadData;
            }
       }
       if(MAX_DATA==Index)
       {
           ackFlag = INVALID_DATA;
           #ifdef DEBUG_FLAG
           vPrintf("\n\rBufferOverRun");
           #endif
           Index = INDEXSTART;
           Senddata_UART1("invalid");
           bBosCreateTimer(Bos_UART1ACK_handler_handler,"Hello", 12, 2, &TimerID_Ack);
       }
    //while (*pcstring)
    //{
    //  vAHI_UartWriteData(E_AHI_UART_0, *pcstring);
    //  pcstring++;
   // }
}

void StringtoNum(char* s)
{
uint8 num=0,flag=0,i;
vPrintf("\n\rInsconvert");
for(i=0;i<=strlen(s);i++)
{
   vPrintf("\n\rdata:%x",s[i]);
   vPrintf("\n\rdata:%d",s[i]);
   if(s[i] >= '0' && s[i] <= '9')
   {
        num = num * 10 + s[i] -'0';
        vPrintf("\n\rdata:%x",num);
   }
   else if(s[0] == '-' && i==0)
   {
        flag =1;
   }
   else
   {
        break;
   }
}
if(flag == 1)
num = num * -1;
}
 

sanddune008

New Member
with above info as reference.

If this is my msg format.
<STX>: <CMD1>: <LEN>: <Variable> : <FCS>: <ETX>

If the data is being sent in ascii format.

And if my interrrupt occurs for every byte(Ascii) received....Then conversion to Hex and filling the revevice buffer will be problem rite? As two ascii characters make one Hex byte.

How to subdue this problem?Then conversion should happen when all the bytes are received isn't?I don't want to make my ISR unnecessarily long.


Thanks all in advance....
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top