Как использовать данные UART rx из ISR в основной цикл?

Я использую PIC18F и в настоящее время пытаюсь подключить его к SIM900. Я использую прерывание UART Rx. ISR работает правильно, но мне интересно, как получить данные в основном цикле. Скажем:

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

Теперь я хочу использовать Rxв основном цикле. Например, если я отправляю ATкоманду, мне нужно проверить, получил ли я OKили ERRORот SIM900. (В настоящее время я просто тестирую его с одним байтом и позже преобразую его в принимающие строки, потому что ответ от SIM900 находится в строковой форме)

Пример:

 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
 }

Итак, как использовать данные RX ISR в основном цикле?

Ответы (2)

Обычный способ сделать это — использовать циклический буфер (иногда также называемый циклической очередью). Процедура прерывания Rx вставляет полученные байты данных в очередь, используя свой входной указатель/индекс. Основной код использует выходной указатель/индекс для извлечения данных из очереди.

Большим преимуществом этой процедуры является то, что данные Rx могут поступать рывками, которые могут поступать быстрее, чем они могут быть использованы основным циклом из-за задержки в других задачах. До тех пор, пока глубина очереди достаточна, а основной код может потреблять данные Rx, по крайней мере, так же быстро, как и скорость долгосрочного потока данных, это путь.

Обратите внимание, что в Интернете есть множество информации о дизайне, кодировании и работе циклических очередей. Один из намеков на то, что при использовании циклических очередей может быть улучшена производительность, если глубина очереди поддерживается четной степенью двух байтов. Когда это будет сделано, перенос индекса очереди сверху вниз может стать простой маской индекса со значением (глубина очереди - 1).

Спасибо. Я буду изучать больше о circular buffer. Можете ли вы опубликовать демо-код для него.?

Альтернативой является сохранение полученных символов в прерывании RX в энергозависимом буфере, увеличивая указатель при каждом приеме. Когда получен символ CR/LF, установите бит глобального флага «получение завершено» и сбросьте указатель. Опросите это «получение завершено» в основном цикле. Когда отправитель завершает работу в CR/LF, основной цикл может прочитать заполненный буфер.