Как Arduino справляется с переполнением последовательного буфера? Он выбрасывает новейшие входящие данные или самые старые? Сколько байтов может содержать буфер?
27
Для аппаратных последовательных портов вы можете увидеть в HardwareSerial.cpp, что размер буфера варьируется в зависимости от объема ОЗУ, доступного на конкретном AVR:
#if (RAMEND < 1000)
#define SERIAL_BUFFER_SIZE 16
#else
#define SERIAL_BUFFER_SIZE 64
#endif
Для программного последовательного порта в SoftwareSerial.h размер буфера приемника _SS_MAX_RX_BUFF
определен как 64 байта. В обоих случаях прекращается попытка вставить полученные данные в очередь, когда она заполнена, поэтому вы можете получить смесь старых и новых данных в зависимости от того, как вы извлекаете данные из очереди.
В идеале было бы лучше убедиться, что буфер всегда очищается быстро, чтобы избежать заполнения буфера. Может быть, посмотрите на таймеры и реализацию простого конечного автомата, если ваша проблема связана с другим кодом, блокирующим основной цикл.
получающий
Вы можете видеть из источника HardwareSerial, что если входящий байт находит кольцевой буфер заполненным, он отбрасывается:
Да, это будет отброшено. Там нет программного или аппаратного контроля потока, если вы не реализуете свой собственный.
Однако с 64-байтовым буфером и приемом данных (скажем) 9600 бод вы получаете один байт каждые 1,04 мс, и, таким образом, для заполнения буфера требуется 66,6 мс. На 16 МГц процессоре вы должны быть в состоянии проверять буфер достаточно часто, чтобы он не заполнялся. Все, что вам действительно нужно сделать, это переместить данные из буфера HardwareSerial в свой собственный, если вы не хотите обрабатывать его прямо сейчас.
Из
#if (RAMEND < 1000)
проверки видно, что процессоры с 1000+ байтами ОЗУ получают 64-байтовый буфер, а те, которые меньше ОЗУ, получают 16-байтовый буфер.Отправка
Данные, которые вы пишете, помещаются в буфер одинакового размера (16 или 64 байта). В случае отправки, если буфер заполняет код, «блокирует» ожидание прерывания для отправки следующего байта через последовательный порт.
Если прерывания отключены, этого никогда не произойдет, поэтому вы не выполняете последовательную печать внутри подпрограммы обработки прерываний.
источник
1/960 = 0.001042 s
- это один байт каждые 1,04 мс.