Как я могу отправить строку последовательно из 8051 только ОДИН РАЗ?

StackOverflow https://stackoverflow.com/questions/1216376

Вопрос

Я создаю микроконтроллер 8051 для беспроводной связи с компьютером.Микроконтроллер отправит строку на свой последовательный порт (DB9), а компьютер получит эту строку и будет манипулировать ею.

Моя проблема в том, что я не знаю, как заставить 8051 передавать строку только один раз.Поскольку мне нужно манипулировать строкой на стороне ПК, она должна быть получена только один раз.В настоящее время, несмотря на то, что в коде C я отправляю строку один раз, на моем компьютере я получаю одну и ту же строку непрерывно.Я предполагаю, что это происходит потому, что все, что находится в SBUF, непрерывно передается.Есть ли какой-нибудь способ, которым я могу отправить свою строку только один раз?Есть ли способ очистить SBUF?

Я попытался использовать вывод RTS (Request to Send) (7-й вывод) на DB9, потому что я где-то читал, что если я уменьшу напряжение на этом выводе, это остановит поток данных на последовательный порт.Итак, что я сделал, так это запрограммировал свой микроконтроллер на отправку строки, а затем отправил логический уровень 0 на выходной вывод, который был подключен к моему выводу DB9 RTS.Однако это не сработало.

У кого-нибудь есть какие-нибудь предложения?Я был бы им очень признателен.

Редактировать

Программное обеспечение, которое я использую на ПК, называется X-CTU для модулей Xbee.Это код на моем микроконтроллере:

include reg51.h 
void SerTx(unsigned char);  
void main(void)  
{  
  TMOD = 0x20;  
  TH1 = 0xFD;  
  SCON = 0x50;  
  TR1 = 1;   

  SerTx('O');  
  SerTx('N');  
  SerTx('L');  
  SerTx('Y'); 

}

void SerTx(unsigned char x)  
{  
  SBUF = x;  
  while(TI==0);   
  TI = 0;   
}  

Не мог бы кто-нибудь, пожалуйста, подтвердить, что на самом деле он отправляет строку только один раз?

Редактировать

Похоже, Стив, Бруксмосс и Нил попали в самую точку, когда сказали, что причиной проблемы было то, что происходило ПОСЛЕ выполнения моей основной функции.Я только что попробовал предложенный Стивом код (точнее, for(;;);и определение serTX вне main), и это сработало отлично.Вероятно, контроллер перезагружен, и, следовательно, один и тот же код продолжает повторяться.

Большое спасибо за помощь!:)

Это было полезно?

Решение

Можете ли вы подтвердить, что 8051 действительно отправляет данные только один раз? Один из способов проверки состоит в том, чтобы использовать прицел, чтобы увидеть, что происходит на выводе TART UART.

Какое программное обеспечение вы используете на ПК? Я бы предложил использовать простые коммуникационные программы, такие как HyperTerminal или PuTTY . Если они показывают строку, отправляемую на ПК несколько раз, скорее всего, ошибка в программном обеспечении, работающем на 8051.

РЕДАКТИРОВАТЬ: Честно говоря, это похоже на отладку, с которой приходится сталкиваться инженерам на регулярной основе, и поэтому у вас есть хорошая возможность попрактиковаться в старомодной методической проблеме. решение.

Если я могу быть очень тупым, я предлагаю вам сделать следующее:

<Ол>
  • Debug. Попробуйте, но не угадайте . Эксперимент. Сделайте небольшие изменения в своем коде и посмотрите, что произойдет. Попробуйте все, что вы можете придумать. Поиск в Интернете для получения дополнительной информации.
  • Если это не поможет, вернитесь сюда и предоставьте нам всю необходимую информацию. Сюда входят соответствующие фрагменты кода, полные сведения об используемом оборудовании и информация о том, что вы попробовали на шаге 1.
  • РЕДАКТИРОВАТЬ: у меня нет представителя для редактирования вопроса, поэтому вот код, опубликованный ОП в комментарии к ее вопросу:

    #include<reg51.h>
    
    void SerTx(unsigned char);
    
    void main(void)
    {
        TMOD = 0x20; TH1 = 0xFD; SCON = 0x50; TR1 = 1;
        SerTx('O'); SerTx('N'); SerTx('L'); SerTx('Y');
    
        void SerTx(unsigned char x)
            { SBUF = x; while(TI==0); TI = 0; } 
    }
    

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

    Кроме того, функция SerTx должна быть определена вне main. Это может быть синтетически правильно, но это упрощает задачу, не объявляя функции внутри других функций.

    Так что попробуйте (я также добавил несколько комментариев, чтобы облегчить понимание кода):

    #include<reg51.h>
    
    void SerTx(unsigned char);
    
    void main(void)
    {
        /* Initialise (need to add more explanation as to what
            each line means, perhaps by replacing these "magic
            numbers" with some #defines) */
        TMOD = 0x20;
        TH1  = 0xFD;
        SCON = 0x50;
        TR1  = 1;
    
        /* Transmit data */
        SerTx('O'); SerTx('N'); SerTx('L'); SerTx('Y');
    
        /* Stay here forever */
        for(;;) {}
    
    }
    
    void SerTx(unsigned char x)
    {
        /* Transmit byte */
        SBUF = x;
    
        /* Wait for byte to be transmitted */
        while(TI==0) {}
    
        /* Clear transmit interrupt flag */
        TI = 0;
    } 
    

    Другие советы

    Опубликованный вами код не имеет цикла в main(), поэтому вам нужно определить, что делает среда выполнения вашего компилятора C, когда main() возвращается после отправки 'Y'.Учитывая вашу проблему, я полагаю, что компилятор генерирует некоторый код для выполнения некоторой очистки, а затем перезапускает micro (возможно, аппаратный сброс, возможно, просто перезапуск среды выполнения C).Похоже, ваша программа работает точно так, как вы ее написали, но вы проигнорировали то, что происходит до и после вызова main() .

    Если вы хотите, чтобы ваша строка была отправлена один и только один раз, то вам нужно что-то вроде while(1) {} добавлено после отправки последнего символа.Но тогда ваша программа ничего не делает - она просто будет вечно выполнять пустой цикл.Сброс (например, включение питания) необходим для повторного запуска и отправки строки.

    Обратите внимание, что если ваш микроконтроллер оснащен сторожевым таймером, он может вмешаться и вызвать неожиданный сброс настроек.Если это произойдет, ваша строка будет отправляться один раз при каждом сбросе сторожевого таймера (что может быть примерно раз в секунду, со скоростью, зависящей от вашего оборудования).

    Кроме того, наличие serTx(), определенного вложенным внутри main(), вероятно, не то, что вы хотите.

    Трудно сказать, в чем проблема, не видя код 8051. Например, логическая ошибка на этой стороне может привести к тому, что данные будут отправлены несколько раз, или программное обеспечение 8051 может ожидать ACK, который так и не был получен и т. Д.

    Обычно в коде 8051 необходимо явно отправлять каждый символ, но я предполагаю, что об этом позаботится за вас среда выполнения C.

    Использование RTS / CTS (Request To Send / Clear To Send) предназначено для управления потоком (т. е. для предотвращения переполнения буфера - буферы на этих микроконтроллерах обычно довольно малы) и не для полной остановки передачи.

    Повторение ответа Нейла (в ответ, поскольку у меня пока нет представителя для комментариев): в типичной ситуации с микроконтроллером без ОС не сразу понятно, что функция exit () вызывается неявно в конце of main () должен делать - или, точнее, он не может выполнить обычный "конец программы и возврат к ОС", потому что нет ОС, к которой можно вернуться.

    Более того, в реальном приложении вы почти никогда не хотите, чтобы программа просто остановилась, если вы не выключите систему. Поэтому одна вещь, которую реализация exit () определенно не должна делать, это занимать много места в коде.

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

    Это похоже на правдоподобную теорию того, что здесь происходит.

    Эта статья предназначена для сборки, а не для C, но может оказаться полезной: http://www.8052.com/tutser.phtml

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top