1
\$\begingroup\$

I am using PIC18F and currently trying to interface it with SIM900. I am using UART Rx interrupt. ISR is working correctly but I wonder how to get data in main loop. Lets say :

#pragma interrupt hi_prioriint
void hi_prioriint(void)
{
   if(PIR1bits.RCIF==1)
   {
      Rx = ReadUSART();  //store the received byte in Rx
   }
 }

Now I want to use Rx in main loop. For example, if I send AT command then I need to check if I received OK or ERROR from SIM900. (For the time being I am just testing it with a single byte and will convert it later into receiving strings because response from the SIM900 is in string form)

Example:

 putrsUSART("AT\r");        //sending AT command
 delay(500)                 //delay of 500ms
 if(strcmp(Rx,"OK")==0)     //checking the response
 {
    //if received OK then proceed further
 }

So how to use RX data of ISR in main loop?

\$\endgroup\$

2 Answers 2

8
\$\begingroup\$

The conventional way to do this is to use a circular buffer (sometimes also referred to as a circular queue). The Rx interrupt routine inserts received data bytes into the queue using its input pointer/index. The mainline code uses the output pointer/index to extract the data from the queue.

The big advantage with this procedure is to allow the Rx data to arrive in spurts that may may come faster than they can be consumed by the mainline loop due to latency in other tasks. As long as the queue depth is enough and the mainline code is able to consume the Rx data at least as fast as the long term data flow rate this is the way to go.

Note that there is a plethora of information online regarding the design, coding and operation of circular queues. One hint is that there can be a performance improvement in the use of circular queues if the depth of the queue is kept to an even power of two number of bytes. When this is done the queue index wrap from top to bottom of the queue can become a simple mask of the index with a value of (queue depth - 1).

\$\endgroup\$
1
  • \$\begingroup\$ Thankyou. I will study more about circular buffer. Can you post a demo code for it.? \$\endgroup\$
    – S Andrew
    Commented Jul 23, 2016 at 12:50
0
\$\begingroup\$

An alternative is, in the RX interrupt, store the received chars in a volatile buffer, incrementing a pointer on each receive. When a CR/LF character is received, set a global flag bit "receive complete" and reset the pointer. Poll this "receive complete" in the main loop. When the sender terminates in a CR/LF, the main loop can then read the filled buffer.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.