Размеры буфера приема и буфера передачи класса Serial.

Вопросы программирования в системе Ардуино
Эдуард
Администратор
Сообщения: 360
Зарегистрирован: 30 окт 2016, 20:53

Размеры буфера приема и буфера передачи класса Serial.

Сообщение Эдуард » 13 ноя 2016, 19:02

Для работы с аппаратными контроллерами последовательного порта в Ардуино есть встроенный класс Serial.
Если работа порта разрешена функцией Serial.begin(), то данные поступающие на вход контроллера Rx в последовательном коде преобразуются в байты и записываются в программный буфер. Этот процесс происходит незаметно для основной программы, по прерыванию контроллера порта.

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

Передача данных последовательного порта также происходит через программный буфер. Например, при скорости 9600 передача одного байта занимает 1 мс. Если необходимо передать 10 байтов, то потребуется 10 мс. Это не значит, что основная программа должна в течение 10 мс передавать в контроллер последовательного порта данные и контролировать их передачу. Достаточно, к примеру, функцией Serial.write() загрузить данные в программный буфер класса Serial и выполнять другие задачи. Передача данных в аппаратный контроллер последовательного порта будет происходить параллельным процессом по прерыванию контроллера порта.

Часто возникают вопросы:
    Какие размеры имеют буфер приема и буфер передачи класса Serial?
    Сколько данных можно принять через последовательный порт, не считывая их программой?
    Сколько байтов для передачи можно загрузить в класс Serial одновременно?

Размеры приемного и передающего буферов последовательного порта Ардуино (класс Serial) задаются в файле:

\hardware\arduino\avr\cores\arduino\HardwareSerial.h

Определение констант размеров буферов выглядит так:

Код: Выделить всё

#if !defined(SERIAL_TX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif
#endif
#if !defined(SERIAL_RX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_RX_BUFFER_SIZE 64
#endif
#endif

По умолчанию и для приемного и передающего буферов заданы размеры:
    16 байтов для микроконтроллеров с памятью до 1023 байта;
    64 байта для микроконтроллеров с памятью свыше 1023 байта.
Для Arduino UNO R3 буферы передачи и приема имеют размер 64.

В принципе эти константы можно изменит в файле HardwareSerial.h. Можно исправить константы в строчках:

Код: Выделить всё

#define SERIAL_TX_BUFFER_SIZE 16
#define SERIAL_TX_BUFFER_SIZE 64
#define SERIAL_RX_BUFFER_SIZE 16
#define SERIAL_RX_BUFFER_SIZE 64

Можно дописать перед блоком:

Код: Выделить всё

#define SERIAL_TX_BUFFER_SIZE 100
#define SERIAL_RX_BUFFER_SIZE 100

Значения констант должны быть кратными 2.

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


Student_K
Сообщения: 2
Зарегистрирован: 15 май 2017, 01:19

Re: Размеры буфера приема и буфера передачи класса Serial.

Сообщение Student_K » 15 май 2017, 01:37

Есть код записанный ардуино uno

Код: Выделить всё

//пример из книги Джереми блума но я написал граф интерфейс на C# + winWorm

const int red = 11; const int green = 10; const int blue = 9; // пины

int rval = 0, gval = 0, bval = 0; //0-255 яркость
void setup() {
  Serial.begin(9600);
  pinMode(red, OUTPUT); pinMode(green, OUTPUT); pinMode(blue, OUTPUT);
}
void loop() {
  while (Serial.available() > 0)
  {
    rval = Serial.parseInt();    gval = Serial.parseInt();    bval = Serial.parseInt();
    if (Serial.read() == '\n')
    {
     // Serial.println("prinyal"); // так для проверки
      analogWrite(red, rval);
      analogWrite(green, gval);
      analogWrite(blue, bval);
    }
  }
}

и есть мной собраннаый граф интерфейс на winForms
[img][IMG]http://www.imageup.ru/img297/thumb/122767720.jpg[/img][/img]
► Показать

Двигая ползунки которого - мы меняем яркость светодиодов.
Вопросы:
1) Может ли у меня переполниться буфер?
2) что случиться, когда он переполниться?
3) На сколько вообще это опасно для МК( не сломаю ли я мк, или не поврежду вшитый загрузчик?
4) Нужно ли доработать скетч ардуино, дописав в конце loop'а строчку Serial.Flush() ?

Эдуард
Администратор
Сообщения: 360
Зарегистрирован: 30 окт 2016, 20:53

Re: Размеры буфера приема и буфера передачи класса Serial.

Сообщение Эдуард » 15 май 2017, 01:54

Здравствуйте!

    1. Буфер переполниться не может по тому, что программа считывает из него данные намного быстрее, чем они могут поступить из UART. При скорости 9600 бод 1 байт может быть принят за время не менее 1 мс. А программа проверяет буфер Serial в цикле loop c периодом несколько микросекунд.

    2. Если буфер переполнится, то старые данные будут потеряны.

    3. Буфер находится в оперативной памяти и никак не угрожает загрузчику во Flash памяти.

    4. Serial.flush это функция ожидания окончания передачи данных из передающего буфера. У вас программа работает только на прием.

Student_K
Сообщения: 2
Зарегистрирован: 15 май 2017, 01:19

Re: Размеры буфера приема и буфера передачи класса Serial.

Сообщение Student_K » 15 май 2017, 03:23

Спасибо, успокоили =)
Пошел дальше изучать ваши уроки =)


Вернуться в «Программирование Ардуино»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей