(Этот ответ предполагает, что вы используете PIC16, предложенный именами определенных регистров.)
Короче говоря, это похоже на переполнение буфера в сочетании с ошибкой в этом цикле в receiveData
. Тот факт, что он замораживается после отправки трех символов подряд, может быть объяснен p117 руководства:
Возможно, что два байта данных будут получены и переданы в RCREG FIFO, а третий байт начнет переключаться в регистр RSR
Это объясняет магическое число три.
Пошагово перебирая код PIC, рассмотрите следующий сценарий (только пример). Первый раз:
// One character already in RCREG - RCIF set
while(PIR1bits.RCIF==0);
// Reads ONE character - RCIF clear
rxData[index]= RCREG;
// While waiting here, two more characters are received - RCIF set
Delay1KTCYx(5);
index++;
Второй раз вокруг:
// RCIF set from before
while(PIR1bits.RCIF==0);
// Reads ONE character - RCIF STILL set, ONE character remains in UART FIFO!
rxData[index]= RCREG;
// While waiting here, three more characters are received
// RCIF set, RCREG fills up and the third character is discarded!
Delay1KTCYx(5);
index++;
Теперь остальная часть цикла будет продолжать читать из RCREG до index == length
, но, поскольку некоторые символы были отброшены, когда UART FIFO был заполнен, вы никогда не попадете туда и, похоже, завис!
Что еще более вероятно, так это то, что вы получаете символы еще до того, как дойдете до этой функции, поэтому UART FIFO заполняется еще до того, как вы туда доберетесь.
Есть несколько способов обойти это.
- Сделайте это в прерывании, чтобы немного быстрее переместить входящие символы в буфер.
- Используйте цикл для чтения из
RCREG
: while(RCIF) rxData[index]= RCREG;
, это гарантирует, что вы очистите буфер при чтении из буфера UART, но это не остановит переполнения вне этой функции или во время этой задержки.
- Проверьте флаг
OERR
- если он установлен, предположите, что случилось что-то плохое, и начните сначала.
- Имеет символ остановки или начальный символ (например, конец строки, пунктуация и т. Д.), Который сообщает вам, когда действительная команда запускается или останавливается. Если у вас есть два начальных символа без символа остановки или какой-либо другой запутанной комбинации, предположите, что вы в плохом состоянии, и начните все сначала.
Несколько дополнительных советов: вы можете просто сойти с ума, пытаясь учесть и компенсировать каждый пропущенный символ или проблему, подобную этой, в вашем коде PIC, но в конечном итоге это просто еще одна ошибка связи. Приоритеты в коде PIC должны быть следующими: быстрое восстановление после ошибок и отсутствие блокировки. Обнаружение ошибок и правильное восстановление должны обрабатываться клиентским кодом, где это намного, намного проще.