Проблема заключается в том, что функции отправки и получения опрашиваются и блокируются. Когда вы вызываете функцию приема, она вернется только после получения полного сообщения. Дито для функции отправки, но в случае отправки продолжительность может быть короче (ваша программа, вероятно, будет отправлять вызов только тогда, когда есть сообщение для отправки, в то время как получение может ждать в течение нескольких дней, прежде чем сообщение придет.
Если вам требуется асинхронная связь, лучше всего использовать связь на основе прерываний; по крайней мере для получения и в идеале для отправки и получения.
Также возможно воспрепятствовать этому, используя опрашиваемую связь, но тогда вам нужно написать функцию, которая проверяет, доступен ли символ для получения (или если tx-пустой), для чтения / записи следующего символа из / в буфер.
Преимущества связи на основе прерываний:
- полный дуплекс
- используется меньшее время процессора (без циклов ожидания)
- меньше энергии (это позволяет процессору переходить в режим пониженного энергопотребления / режим ожидания с активацией при прерывании; опрос всегда требует полной мощности)
В качестве первого шага я советую вам реализовать (или получить) получение на основе прерываний; даже если функция передачи по-прежнему заблокирована, она позволит работать в дуплексном режиме с минимальными усилиями. Если у вас нет ОС (rtos / планировщик), вам придется подумать о механизме синхронизации. Самая простая форма для вашего получения - обработать сообщение, если оно доступно, и немедленно вернуться, если нет (полного) сообщения.
удачи.
Редактировать после комментариев
По принципу «сообщение за сообщением» может показаться, что все работает, если рабочий стол реагирует на сообщения, отправленные контроллером. Если ваш контроллер имеет большой буфер FIFO (то есть 64 байта) на приеме, это может работать. У большинства контролеров, которых я знаю, этого нет. Многие из них имеют только один символьный буфер. Вы можете обнаружить это, используя бит OVERFLOW в регистрах; если это установлено, то символы были потеряны при получении.
Некоторые варианты использования:
* вы хотите отправить 2 сообщения за один раз (скажем: init + do_something). ПК отвечает на первое сообщение, но контроллер все еще отправляет и сбрасывает большую часть данных.
* ПК начинает отправку до того, как контроллер выполняет функцию receive (). Данные в начале пакета могут быть потеряны
* любая потеря связи может привести к взаимоблокировке (т. е. контроллер и рабочий стол оба ждут, пока другой конец отправит что-либо.
Итак, для диагностики: проверьте бит переполнения. Если он установлен, вы потеряли данные, и вам нужно работать с функциями прерывания. Если возможно, контролируйте обе стороны (по крайней мере, состояние; мигает светодиод для отправки и один для получения, например).
Вам может помочь монитор rs232 (для этого вам понадобятся дополнительные порты. Существует множество (в том числе бесплатных) приложений, которые могут отслеживать несколько портов rs232 и предоставлять временные метки. Таким образом, вы можете наблюдать за порядком сообщений. Google нашел меня : ссылка ; в последние годы я использовал несколько подобных утилит.