A serial port efficient transceiver idea and scheme

Source: Internet
Author: User
Tags data structures

Abstract: This paper discusses how to use the serial port with FIFO to reduce the number of received interrupts, and gives the frame packing method through a custom communication protocol format, and then introduces a special serial port data sending method, which can improve the response speed of the system in case of avoiding the use of serial port sending interrupt. 1. Introduction

The serial port is widely used because of its simple use and low price, and with RS485 chip, it can realize long-distance and strong anti-jamming local area network. With the increase of product function, the tasks that need to be dealt with are more and more complex, and the system tasks need to respond more and more. Most modern single-chip (ARM7, CORTEX-M3) serial ports have a certain number of hardware FIFO, this article will introduce how to use hardware FIFO to reduce the number of receive interrupts, improve the efficiency of transmission. Before this, first to enumerate the traditional serial data transmission and delivery of the shortcomings:

Each byte of data is received, resulting in a receive interrupt. Can not effectively use the serial hardware FIFO, reduce the number of interrupts. The answer data takes the method of waiting to be sent. Because the serial data transmission time is far from the CPU processing time, waiting for the serial port to send the current byte and then send the next byte will cause the CPU waste, not conducive to the overall system response (at 1200bps, send a byte about 10ms, if send dozens of bytes of data at a time,  The CPU is in a wait state for a long time). The response data is sent with interrupts.  Add an interrupt source to increase the number of interrupts in the system, which can affect the overall stability of the system (from a reliability perspective, the fewer interrupt events, the better). In response to these shortcomings, a common custom communication protocol will be combined to provide a complete solution.

2. Serial Port FIFO

The serial port FIFO can be understood as the serial port dedicated cache, which adopts the FIFO method. The data receive FIFO and the data send FIFO are usually independent of two hardware. The serial port receives the data, first puts in the receiving FIFO, when the data in the FIFO reaches the trigger value (usually the trigger value is 1, 2, 4, 8, 14 bytes) or the data in the FIFO does not reach the setpoint but for a period of time (usually 3.5 character transfer time) no longer receives the data, notifies the CPU to generate a receive interrupt, the sent data is written to the send FIFO, as long as the sending FIFO is not empty, the hardware will automatically send the data in the FIFO. The number of bytes written to the send FIFO is affected by the maximum FIFO depth, which typically allows up to 16 bytes of write time. The data listed above are related to the specific hardware, the CPU type is different, the characteristics are not the same, before use should refer to the corresponding data sheet. 3. Data reception and packaging

FIFO can cache the data received from the serial port, so we can use FIFO to reduce the number of interrupts. Taking NXP's lpc1778 chip as an example, the trigger level of the receive FIFO can be set to 1, 2, 4, 8, 14 bytes, 8 bytes or 14 bytes are recommended, which is the default value of the PC serial port receiving FIFO. This way, when a large amount of data is received, every 8 bytes or 14 bytes will produce an interrupt (except the last one), resulting in an interrupt compared to the receipt of one byte, which greatly reduces the number of serial receive interrupts.

It is also very simple to set the receive FIFO to 8 or 14 bytes, or to lpc1778 as an example, just set the UART FIFO control register to UNFCR.

The data received must be in accordance with the Protocol, and the data and protocol are inseparable. Usually we need to package the received data into one frame according to the protocol and then go to the upper layer to process it. The following describes a custom protocol frame format and gives a generic way to package into frames.

The custom protocol format is shown in Figure 3-1.

Frame Top

Address number

Command number

Length

Data

Parity

Figure 3-1 Common communication protocol format for companies

Frame top: Usually 0xFF or 0xEE address number: The address number of the device to be communicated, 1 byte command number: corresponding to different functions, 1 bytes Length: Number of bytes in the data region, 1 bytes of data: With the specific command number, the data area length can be 0, the length of the entire frame should not exceed 256 bytes Checksum: Xor Checksum (1 bytes) or CRC16 checksum (2 bytes), this example uses the CRC16 checksum

Here's how to package the received data into one frame in the format shown in Figure 3-1.

3.1 Defining data Structures

1.  typedef struct {  
2.      uint8_t * DST_BUF;                  Point to receive Cache  
3.      uint8_t sfd;                        The first sign of the frame is 0xFF or 0xEE  
4.      uint8_t Sfd_flag;                   Find the top of the frame, typically a FF or EE  
5.      uint8_t Sfd_count;                  The first number of frames, usually  
6.      uint8_t Received_len;               The number of bytes that have been received  
7.      uint8_t Find_fram_flag;             When the full frame is found, set 1  
8.      uint8_t Frame_len;                  The total length of the frame data, this area is optional  
9.  } Find_frame_struct;


3.2 Initialization of data structures, usually in the serial port initialization

1.  /** 
2.  * @brief    Initialize the data structure of the search frame 
3.  * @param    P_fine_frame: Point to package frame data structure body variable 
4.  * @param    Dst_buf: Point to Frame buffer 
5.  * @param    SFD: The first sign of the frame, usually 0xFF or 0xEE 
6.  */  
7.  void Init_find_frame_struct (find_frame_struct * p_find_frame,uint8_t *dst_buf,uint8_t SFD)  
8.  {  
9.      p_find_frame->dst_buf=dst_buf;  
Ten.     p_find_frame->sfd=sfd;  
p_find_frame->find_fram_flag=0;.  
p_find_frame->frame_len=10;.       
p_find_frame->received_len=0;.  
p_find_frame->sfd_count=0;.  
p_find_frame->sfd_flag=0;.       


3.3 Data Packaging program

1./** 2.  * @brief look for a frame of data to return the number of processed data 3.  * @param p_find_frame: Point to package frame data structure body variable 4.  * @param src_buf: Raw data to the serial port received 5.  * @param data_len:src_buf The number of raw data received by this serial port 6.  * @param sum_len: Maximum length of frame cache 7.  * @return The number of data processed 8.  */9. uint32_t find_one_frame (find_frame_struct * p_find_frame,const uint8_t * src_buf,uint32_t data_len,uint32_t Sum_len) 10 .  
{one. uint32_t src_len=0;     12.13.     while (data_len--) 14.         {. if (p_find_frame->sfd_flag==0) 16.             {//No start frame found for first 17.             if (Src_buf[src_len++]==p_find_frame->sfd) 18.  
{p_find_frame->dst_buf[p_find_frame->received_len++]=p_find_frame->sfd;                 if (++p_find_frame->sfd_count==5) 21.  
{P_find_frame->sfd_flag=1;  
P_find_frame->sfd_count=0; P_find_frame->frame_len=10;             25.} 26.             } 27.             Else 28.   
{P_find_frame->sfd_count=0;   
P_find_frame->received_len=0;         31.} 32.         } 33.         Else 34. {//Is the ' length ' byte?             Y-> gets the data length of this frame 35.             if (7==p_find_frame->received_len) 36.                   
{PNs. p_find_frame->frame_len=src_buf[src_len]+5+1+1+1+2;//Frame header + Address number + command number + data length + checksum 38.                 40. if (P_find_frame->frame_len>=sum_len).                     {//Here the processing method is not necessarily the same according to the specific application 41.  
MY_DEBUGF (Slave_debug, ("Data length exceeds cache!\n");       
P_find_frame->frame_len= Sum_len;             43.} 44.               
} 45.  
P_find_frame->dst_buf[p_find_frame->received_len++]=src_buf[src_len++];             47.48. if (P_find_frame->received_len==p_find_frAme->frame_len) 49.              {P_find_frame->received_len=0;                 One frame complete 51.  
P_find_frame->sfd_flag=0;   
P_find_frame->find_fram_flag=1;                 53.54.  
return Src_len;         55.} 56.     } 57.     } 58.  
P_find_frame->find_fram_flag=0;  
A. return src_len;  60.}

Examples of Use:

To define a data structure body variable:

    FIND_FRAME_STRUCTSLAVE_FIND_FRAME_SRT;

To define the receive data buffer:

    #define Slave_rec_data_len
    uint8_t Slave_rec_buf[slave_rec_data_len];

Call the struct variable initialization function in serial port initialization:

    Init_find_frame_struct (&slave_find_frame_srt,slave_rec_buf,0xee);

Call the data wrapper function in the serial receive interrupt:

    Find_one_frame (&slave_find_frame_srt,tmp_rec_buf,data_len,slave_rec_data_len);

Wherein, REC_BUF is the serial port receives the temporary buffer, Data_len is this time receives the data length.

4. Data transmission

As mentioned earlier, the traditional way of waiting to be sent wastes CPU resources, while the interrupt sending method does not cause CPU wasting, but adds an interrupt source. In our use, we found that the timer interrupt is used by almost every application, we can use the timer interrupt and the hardware FIFO to send data, through the reasonable design, such a sending method will not cause the CPU resources wasted, and will not increase the interrupt source and interrupt events.

It should be explained in advance that this method is not suitable for all applications, and for those applications that do not have a timer interrupt, this method is not supported, and if the timer interrupt interval is longer and the communication baud rate is very high, this method is also not applicable. The current use of the company's communication baud rate is generally relatively small (1200bps, 2400bps), at these baud rate, the timer interval of 10ms (including 10ms) can be satisfied. If the timer interval is less than 1ms (including 1ms), it is possible to use 115200bps.

The main idea of this method is: After the timer interrupt trigger, determine whether there is data to send, if there is data to send and meet the sending conditions, then the data into the send FIFO, for lpc1778, can put up to 16 bytes of data at a time. The hardware will then automatically start sending without CPU involvement.

The following describes how to use the timer to send data, the hardware carrier is RS485. Because the transmission needs to operate the serial register and RS485 direction control pin, need to be closely related to the hardware, the following code uses the hardware is lpc1778, but the idea is universal. 4.1 Defining data Structures

1./  * Serial frame send structure */  
2.  typedef struct {  
3.      uint16_t Send_sum_len;          The length of the frame data to be sent  
4.      uint8_t  Send_cur_len;          The currently sent data length is  
5.      uint8_t  Send_flag;             Whether to send flag  
6.      uint8_t * SEND_DATA;            Point to the data buffer to send  
7.  } Uart_send_struct;  

4.2 Timer processing function

1./** 2.  * @brief timed Send function, call in timer interrupt, reduce send wait 3 without using send interrupt.  * @param uartx: Point to Hardware serial port register base address 4.  * @param p: Point to the serial frame to send struct variable 5.  */6.  #define FARME_SEND_FALG 0x5A 7.  #define SEND_DATA_NUM 12 8.  static void Uart_send_com (Lpc_uart_typedef *uartx,uart_send_struct *p) 9.  
{Ten. uint32_t i;  
One. uint32_t tmp32;     12.13.     if (UARTX->LSR & (0X01<<6))//Send as null 14.         {16. if (P->SEND_FLAG==FARME_SEND_FALG).                             {Rs485clrde;               
Set 485 to send status 18.  
tmp32=p->send_sum_len-p->send_cur_len;.             if (tmp32>send_data_num)//To send FIFO byte data 21.                 {23. for (i=0;i<send_data_num;i++).  
{uartx->thr=p->send_data[p->send_cur_len++];.             25.} 26. } 27.            Else 28.                 {30. for (i=0;i<tmp32;i++).  
{uartx->thr=p->send_data[p->send_cur_len++];.                 32.} 33.                      
p->send_flag=0;         34.} 35.         } 36.         Else 37.  
{rs485setde.     39.} 40. } 41.   }
Where Rs485clrde is defined as a macro, the RS485 is set to send mode, RS485SETDE is also defined for the macro, and the RS485 is set to receive mode.

Examples of Use:

To define a data structure body variable:

    Uart_send_struct Uart0_send_str;

To define a send buffer:

    uint8_t Uart0_send_buf[uart0_send_len];

According to the use of the hardware serial port, the timer processing function to do two times encapsulation:

    void Uart0_send_data (void)
    {
        uart_send_com (LPC_UART0,&UART0_SEND_STR);
    }

The encapsulation function is Uart0_send_data () and put into the timer interrupt processing function;

Set the serial port frame to send the structure variables where you need to send the data:

    Uart0_send_str.send_sum_len=data_len;      Data_len is the length of the data to be sent
    uart0_send_str.send_cur_len=0;           Fixed to 0
    uart0_send_str.send_data=uart0_send_buf;    Bind send buffer
    uart0_send_str.send_flag=farme_send_falg;   Set Send Flag

5. Summary

This paper mainly discusses a kind of high efficient serial port data receiving and transmitting method, and gives the concrete code realization. With the increasing of current processor tasks, a new idea is provided, which occupies less resources and can improve the overall performance of the system.

Reprint Please specify source: http://blog.csdn.net/zhzht19861011/article/details/48522391

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.