Как я могу непрерывно отправлять и получать через беспроводной последовательный порт в 8051? - PullRequest
5 голосов
/ 24 октября 2009

Я пытаюсь заставить микроконтроллер связываться с программой на моем рабочем столе. Я использую последовательный порт с радио Xbee на обоих концах.

Связь работает нормально, когда я отправляю что-то из микроконтроллера на рабочий стол, а программа на рабочем столе затем отправляет что-то обратно в микроконтроллер.

Однако, когда мне требуется непрерывно отправлять информацию из контроллера в настольную программу, пока настольная программа не отправит конкретный ответ, она не будет работать.

Вот код того, о чем я говорю:

    unsigned char ans = 'N';
    unsigned int count = 0;

    void main(void)
    {


        while(1)
        {
            if(count == 0)
            {
                Configure();
                count = 1;
            }

                  //there is some more code here but is irrelevant to the serial communication

         }

    }


void Configure()
{


    //Repeat this until the user accepts the sent string as correct
    while(ans == 'N')
    {

        BuildString();
        Send();
        Receive();
    }
}

void Send()
{
    unsigned int i;

    TMOD = 0x20;
    TH1 = 0xFD;
    SCON = 0x50;
    TR1 = 1;

    for(i=0; i<4; i++)
    {
        SBUF = toSend[i];
        while(TI == 0);
        TI = 0;
    }   

}

void Receive()
{
    unsigned int j;

    TMOD = 0x20;
    TH1 = 0xFD;
    SCON = 0x50;
    TR1 = 1;


    for(j=0; j<2; j++)
    {
        while(RI == 0);
        Received[j] = SBUF;
        RI = 0; 
    }


    if(count == 0)
        ans = Received[1];

    else
    {   
        RunType = Received[0];
        Move = Received[1];
    }


}

Функция BuildString () просто создает строку на основе некоторых входных сигналов датчика. Функции отправки и получения обычно работают нормально, но когда мне нужно, чтобы они отправляли и получали непрерывно, как в функции Configure () выше, это не работает.

Есть предложения? Я очень ценю их.

Ответы [ 2 ]

4 голосов
/ 24 октября 2009

Проблема заключается в том, что функции отправки и получения опрашиваются и блокируются. Когда вы вызываете функцию приема, она вернется только после получения полного сообщения. Дито для функции отправки, но в случае отправки продолжительность может быть короче (ваша программа, вероятно, будет отправлять вызов только тогда, когда есть сообщение для отправки, в то время как получение может ждать в течение нескольких дней, прежде чем сообщение придет.

Если вам требуется асинхронная связь, лучше всего использовать связь на основе прерываний; по крайней мере для получения и в идеале для отправки и получения.

Также возможно воспрепятствовать этому, используя опрашиваемую связь, но тогда вам нужно написать функцию, которая проверяет, доступен ли символ для получения (или если tx-пустой), для чтения / записи следующего символа из / в буфер.

Преимущества связи на основе прерываний:

  • полный дуплекс
  • используется меньшее время процессора (без циклов ожидания)
  • меньше энергии (это позволяет процессору переходить в режим пониженного энергопотребления / режим ожидания с активацией при прерывании; опрос всегда требует полной мощности)

В качестве первого шага я советую вам реализовать (или получить) получение на основе прерываний; даже если функция передачи по-прежнему заблокирована, она позволит работать в дуплексном режиме с минимальными усилиями. Если у вас нет ОС (rtos / планировщик), вам придется подумать о механизме синхронизации. Самая простая форма для вашего получения - обработать сообщение, если оно доступно, и немедленно вернуться, если нет (полного) сообщения.

удачи.

Редактировать после комментариев По принципу «сообщение за сообщением» может показаться, что все работает, если рабочий стол реагирует на сообщения, отправленные контроллером. Если ваш контроллер имеет большой буфер FIFO (то есть 64 байта) на приеме, это может работать. У большинства контролеров, которых я знаю, этого нет. Многие из них имеют только один символьный буфер. Вы можете обнаружить это, используя бит OVERFLOW в регистрах; если это установлено, то символы были потеряны при получении.

Некоторые варианты использования: * вы хотите отправить 2 сообщения за один раз (скажем: init + do_something). ПК отвечает на первое сообщение, но контроллер все еще отправляет и сбрасывает большую часть данных. * ПК начинает отправку до того, как контроллер выполняет функцию receive (). Данные в начале пакета могут быть потеряны * любая потеря связи может привести к взаимоблокировке (т. е. контроллер и рабочий стол оба ждут, пока другой конец отправит что-либо.

Итак, для диагностики: проверьте бит переполнения. Если он установлен, вы потеряли данные, и вам нужно работать с функциями прерывания. Если возможно, контролируйте обе стороны (по крайней мере, состояние; мигает светодиод для отправки и один для получения, например).

Вам может помочь монитор rs232 (для этого вам понадобятся дополнительные порты. Существует множество (в том числе бесплатных) приложений, которые могут отслеживать несколько портов rs232 и предоставлять временные метки. Таким образом, вы можете наблюдать за порядком сообщений. Google нашел меня : ссылка ; в последние годы я использовал несколько подобных утилит.

1 голос
/ 25 октября 2009

Ваша программа в том виде, в котором она написана, должна отправить 4 байта, а затем прочитать 2 байта (при условии, что ваши регистры верны, но, если вы вообще его заработали, они, вероятно, верны), тогда отправьте еще 4 байта ... не висит на отправляющей части, но на принимающей стороне, поскольку он всегда будет ждать чтения двух байтов, и если по какой-то причине два байта не поступят во входной регистр, вы будете продолжать ждать вечно.

Может быть, когда вы напрягаете систему (слишком быстро отправляете байт), вы переполняете входной буфер и в конечном итоге теряете байт? таким образом никогда не получая два байта. и застрянет.

  1. вы можете отлаживать, где вы застряли? это на самом деле в цикле приема?
  2. Можете ли вы ограничить передачу от ПК к микро, чтобы вы могли вручную посылать по одному байту за раз?
  3. есть ли рукопожатие между интерфейсом micro и xbee? это может быть подавлено микро?
...