Это обычные символы. \r - carriage return, возврат каретки по нашему, в терминале он вызывает возврат на начало строки.
\n - new line, понятно, в терминале переходит курсор на новую строку в той же позиции. Так было изначально, как на печатающей машинке. Никто не мешает поменять их местами, результат не изменится - курсор будет в начале следующей строки.
Уже в дальнейшем, начались вариации, типа, \r - возврат с переводом, так же как и \n.
Escape последовательности - начинаются с ESC, он же '\e', он же \0x1b, второй символ обычно '[', ну и дальше последовательность может быть достаточно длинной, например '\e','[','\5',';','\0','H' - это прямая адресация курсора.
Это обычные символы. \r - carriage return, возврат каретки по нашему, в терминале он вызывает возврат на начало строки.
\n - new line, понятно, в терминале переходит курсор на новую строку в той же позиции. Так было изначально, как на печатающей машинке. Никто не мешает поменять их местами, результат не изменится - курсор будет в начале следующей строки.
Уже в дальнейшем, начались вариации, типа, \r - возврат с переводом, так же как и \n.
Escape последовательности - начинаются с ESC, он же '\e', он же \0x1b, второй символ обычно '[', ну и дальше последовательность может быть достаточно длинной, например '\e','[','\5',';','\0','H' - это прямая адресация курсора.
Да, для компилятора С/С++ \r или \0x0d это тоже последовательность, но на выходе получается один символ. Почему ESC? Наверно потому что Escape - это экранировать с английского, наиболее подходящее по смыслу значение.
Пожалуйста просвятите. К примеру у нас такая функция по обработке поступающего байта
unsigned char USART_Receive (void){
/* Wait for data to be received */
while (!(UCSRnA & (1<<RXCn)));
/* Get and return received data from buffer */
switch (c) {
case 'A': do something very long;
}
}
И к примеру оброботчик у нас очень длиный и долгий.
Что будет со следующим байтом в буфере ? Пропадет ? через сколько ? перезапишется ? через сколько ?
Как много байт может храниться в буфере? или только один ?
Я не про экранирование. Я про перевод слова escape. В Си управляющие последовательности начинаются с \ . Это тоже экранирование и ни какого отношения к escape не имеет.
И к примеру оброботчик у нас очень длиный и долгий.
Что будет со следующим байтом в буфере ? Пропадет ? через сколько ? перезапишется ? через сколько ?
Как много байт может храниться в буфере? или только один ?
Так а зачем в обработке прерывания делать что то долго? Нужно принять байт, положить его в кольцевой буфер и сдвинуть указатель головы. А обрабатывать уже не в прерывании, вытаскивая символы из этого буфера и сдвигая указатель на хвост. Сравнялись указатели хвоста и головы - буфер пуст.
Аппаратного буфера у AVR нет, есть место под принятый байт. Не успели забрать, перепишется следующим пришедшим.
И к примеру оброботчик у нас очень длиный и долгий.
Что будет со следующим байтом в буфере ? Пропадет ? через сколько ? перезапишется ? через сколько ?
дальше фразы про "длинный и долгий обработчик" можно не читать.
Алекс, ты не о том беспокоишься. Потеря байта?... ерунда. "Очень длинный и долгий" обработчик прерывания приведет не только к остановке чтения из UART - это приведет к блокировке всех других прерываний в системе, включая любые другие шины (I2C SPI), а так же таймеры, включая SYSTick
Вывод - "длинный и долгий обработчик" вообще не стоит обсуждать. это гавнокод и его в программе просто быть не должно. В обработчике ты только принимаешь байт и кладешь в буфер, а длинная и долгая обработка вся должна быть в основном цикле программы, а не в прерывании
Так а зачем в обработке прерывания делать что то долго?
это не прерывание это функция. под словом обработчик я имел ввиду код обрабатывающий полученный символ из UDR [которй мы можем получить и через обычную функцию внутри лупа]
b707 не не это не обработчик. про ISR всё понятно что долго и длино.
и вообще я долго и длино фразу использовал чтоб поднять вопросы которые я там спросил. понятно что надо писать быстро и коротко. суть не в этом. суть в вопросах . как долго храниться/что потом и т.д.
это не прерывание это функция. под словом обработчик я имел ввиду код обрабатывающий полученный символ из UDR [которй мы можем получить и через обычную функцию внутри лупа]
это проще, потому что не станет вешать весь МК. Тем не менее рекомендации те же - разделить прием и обработку. В обработке ты только читаешь байт из регистра и кладешь в буфер, а обрабатывающую функцию запускаешь отдельно. И функция твоя должна регулярно прерываться и читать из регистра очередной пришедший байт
суть не в этом. суть в вопросах . как долго храниться/что потом и т.д.
как раз это не суть. От того, хранится ли один байт или например 8 или 16 - мало что меняется. если обработка действительно "долгая" - рано или поздно буфер переполнится и произойдет потеря информации
Поэтому в любом случае "долгая и длинная обработка" должна регулярно читать новые байты из UART - или через прерывание, или через какой-то другой механизм. писать который придется тебе самому.
как раз это не суть. От того, хранится ли один байт или например 8 или 16 - мало что меняется. если обработка действительно "долгая" - рано или поздно буфер переполнится и произойдет потеря информации
Поэтому в любом случае "долгая и длинная обработка" должна регулярно читать новые байты из UART - или через прерывание, или через какой-то другой механизм. писать который придется тебе самому.
Меняется, особенно, когда Flow Control реализован.
b707, SergeiL оно понятно что надо постояно записывать из поступающего буфера и т.д.
тут вопрос больше позновательный а не посыл к действию... хочется понять (если приём без буфера. ведь впринципе можем реализоват и без. понятно что с оговрками и не везде) как долго будет байт в буфере и что потом если не заберём..
пропадут все остальные пока это не заберем.. если такой вариант то через сколько времени прилетит следующий чтобы понять сколько у нас времени в запасе...
или перезаписываться будут.. но тогда тоже через какоето время... опять же какое ?
А пишите то в какой среде? Если в ардуне - то она уже позаботилась о кольцевом буфере и по прерыванию туда собственно и скидывает. А все процедуры ардуиновские достают из буфера а не из регистра МК. Если где то ещё, то пока не встречал МК у которого в стандартных примерах производителя нет кольцевого буфера на UART. Зачем изобретать велосипед? Может проще на кошках учиться? ((С) Операция Ы....)
А пишите то в какой среде? Если в ардуне - то она уже позаботилась о кольцевом буфере и по прерыванию туда собственно и скидывает.
alexbmd пишет:
это не прерывание это функция. под словом обработчик я имел ввиду код обрабатывающий полученный символ из UDR [которй мы можем получить и через обычную функцию внутри лупа]
Тоже не понимаю почему стандартный Сериал не устраивает.
всем устраивает (ну кроме размера конечно).. так интересуюсь для изучения и расширения познаний
если правильно посчитал при скорости 57600 уходит 1мс на байт... осталось не понятным след байт перезаписывает тот что в регистре или пропадает, ну если регистр не успели считать..
Пожалуйста подскажите. Наверно успускаю какуюто важную деталь , никак не пойму какую. Плата Nano
class USART {
private:
typedef uint8_t T;
volatile T C = 0;
public:
inline void begin(const uint16_t ubrr = 9600, const uint8_t format = 6) {
cli();
UCSR0A |= bit(U2X0);
UBRR0H = (uint8_t)((F_CPU / 8L / ubrr - 1) >> 8);
UBRR0L = (uint8_t)((F_CPU / 8L / ubrr - 1) & 0xFF);
// Enable receiver, transmitter, interrupt
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (0 << TXCIE0) | (0 << UDRIE0);
// Set frame format 8N1
UCSR0C = format;
sei();
}
inline bool rx_interrupt() {
// Wait while UDR buffer is empty. RXC0 = 1 has unread data
while (!(UCSR0A & (1 << RXC0)));
C = UDR0;
}
inline bool write(const T c) {
// Wait until buffer is empty. UDRE0 = 1 can receive new data. TXC0 = 1 transmit completed
while (!(UCSR0A & (1 << UDRE0)));
// Put data into buffer
UDR0 = c;
return (UCSR0A & (1 << UDRE0));
}
inline bool write(const char *s) {
bool b = (strlen(s)) ? true : false;
while (b && *s) b = write(*s++);
return b;
}
inline T read() {
return C;
}
};
USART serial;
int flag = 1;
void setup() {
DDRB |= (1 << 5);
serial.begin(19200);
}
void loop() {
if (flag) {
serial.write("begin..\r\n");
flag = 0;
}
static uint32_t t = 0;
if (UCSR0A & bit(U2X0)) {
if ( millis() - t > 2000 ) {
PORTB ^= (1 << 5);
t = millis();
}
}
char c = serial.read();
if (c > 31) serial.write(c);
}
ISR(USART_RX_vect) {
serial.rx_interrupt();
}
2 проблемы
1) ни как не пойму почему строчка 56 печатается только be. стр 28 проверяем если готовы принять следующий символ. по идее не должно быть печати в "нахлёст" или "съеденных" букв. ни как не пойму почему только два символа.
2) если мы в инпут отправляем строку, например "Hello world" то напечать выводит "HHHello world". можно подумать что скетч слишком быстрый и успевает прочесть один и тот же символ дважды/трижды но нет. это происходит только с первым сиволом даже на длинной строке.
подскажите плиз как без буфера исправить данные баги?
Аааа, понял :) Ну тогда ch=*(char*)&"\n" .
не, до такого яб не додумался :)
как я уже выше отвечал детсимену - я бы просто ch = 0x0A написал бы
не, до такого яб не додумался :)
как я уже выше отвечал детсимену - я бы просто ch = 0x0A написал бы
А че... и туда тоже можно ! Лучше сh=10.
А че... и туда тоже можно ! Лучше сh=10.
низя! 10 - это обычное число. А в этой строчке нужен символ :)
Про бинарные 1010 забыли. Контроллер без перевода поймет))
Может стоит написать char ch='\n' ?
это не мне если что. там переписка выше про в ногу.
3 варианта...
4.. в линуксе по другому например , putty тоже не как ардуино шлёт и т.д.
низя! 10 - это обычное число.
http://arduino.ru/forum/programmirovanie/preryvanie-po-postupleniyu-bait...
а буквы цифры это не обычное число ? чем ескейп отличается ?... лдано проехали :)
а оно такое есть? - \n\r
Конечно ! Еще как. Даже в терминалке ИДЕ имеет место быть и это не с проста :)
Брукли, нет там такого:
только три варианта - "Newline" = \n, "Carriage return" = CR = \r и "NL + CR both", что, на саом деле, является \r\n.
Варианта \n\r я не встречал нигде за свои 30 лет работы с компами. Думаю, что такого не бывает вовсе. Покажите мне пример, где такое используется.
'\n' - это непонятно что, ни два ни полтора, ибо эскейп-последовательности работают только в двойных кавычках.
нет
нет
опоздал. уже выяснили. Лучше про \n\r напиши, если знаешь
putty только \r
Варианта \n\r я не встречал нигде за свои 30 лет работы с компами. Думаю, что такого не бывает вовсе. Покажите мне пример, где такое используется.
по русски - возврат каретки, перевод строки, могу на пальцах рассказать почему так, так как наследие печатающих машинок, в кодах 0x0D, 0x0A
putty только \r
В какой ОС?
скорее всего, как обычно, путаешь.
Открыл путти - по умолчанию там '\n'. Но в настройках можно выставить и \r\n
Это обычные символы. \r - carriage return, возврат каретки по нашему, в терминале он вызывает возврат на начало строки.
\n - new line, понятно, в терминале переходит курсор на новую строку в той же позиции. Так было изначально, как на печатающей машинке. Никто не мешает поменять их местами, результат не изменится - курсор будет в начале следующей строки.
Уже в дальнейшем, начались вариации, типа, \r - возврат с переводом, так же как и \n.
Escape последовательности - начинаются с ESC, он же '\e', он же \0x1b, второй символ обычно '[', ну и дальше последовательность может быть достаточно длинной, например '\e','[','\5',';','\0','H' - это прямая адресация курсора.
Это обычные символы. \r - carriage return, возврат каретки по нашему, в терминале он вызывает возврат на начало строки.
\n - new line, понятно, в терминале переходит курсор на новую строку в той же позиции. Так было изначально, как на печатающей машинке. Никто не мешает поменять их местами, результат не изменится - курсор будет в начале следующей строки.
Уже в дальнейшем, начались вариации, типа, \r - возврат с переводом, так же как и \n.
Escape последовательности - начинаются с ESC, он же '\e', он же \0x1b, второй символ обычно '[', ну и дальше последовательность может быть достаточно длинной, например '\e','[','\5',';','\0','H' - это прямая адресация курсора.
Quick Help по Си: C escape sequences:
А я о терминальных ESC последовательностях.) Вроде о них у нас речь или нет?
Да, для компилятора С/С++ \r или \0x0d это тоже последовательность, но на выходе получается один символ. Почему ESC? Наверно потому что Escape - это экранировать с английского, наиболее подходящее по смыслу значение.
В какой ОС?
Win.
Как понимаю стандарта нету и каждый пляшет як хочет.
Ввёл escape в гугле. Получил кучу вариантов. Среди вариантов экранировать не присутствует. А то думал может чего упустил.
Пожалуйста просвятите. К примеру у нас такая функция по обработке поступающего байта
И к примеру оброботчик у нас очень длиный и долгий.
Что будет со следующим байтом в буфере ? Пропадет ? через сколько ? перезапишется ? через сколько ?
Как много байт может храниться в буфере? или только один ?
экранировать не присутствует.
Это пошло издавна и не только в Си. Везде где есть спец символы в РУнете обычно пишут и говорят экранировать... отчего так не знаю
Я не про экранирование. Я про перевод слова escape. В Си управляющие последовательности начинаются с \ . Это тоже экранирование и ни какого отношения к escape не имеет.
И к примеру оброботчик у нас очень длиный и долгий.
Что будет со следующим байтом в буфере ? Пропадет ? через сколько ? перезапишется ? через сколько ?
Как много байт может храниться в буфере? или только один ?
Так а зачем в обработке прерывания делать что то долго? Нужно принять байт, положить его в кольцевой буфер и сдвинуть указатель головы. А обрабатывать уже не в прерывании, вытаскивая символы из этого буфера и сдвигая указатель на хвост. Сравнялись указатели хвоста и головы - буфер пуст.
Аппаратного буфера у AVR нет, есть место под принятый байт. Не успели забрать, перепишется следующим пришедшим.
И к примеру оброботчик у нас очень длиный и долгий.
Что будет со следующим байтом в буфере ? Пропадет ? через сколько ? перезапишется ? через сколько ?
дальше фразы про "длинный и долгий обработчик" можно не читать.
Алекс, ты не о том беспокоишься. Потеря байта?... ерунда. "Очень длинный и долгий" обработчик прерывания приведет не только к остановке чтения из UART - это приведет к блокировке всех других прерываний в системе, включая любые другие шины (I2C SPI), а так же таймеры, включая SYSTick
Вывод - "длинный и долгий обработчик" вообще не стоит обсуждать. это гавнокод и его в программе просто быть не должно. В обработчике ты только принимаешь байт и кладешь в буфер, а длинная и долгая обработка вся должна быть в основном цикле программы, а не в прерывании
Так а зачем в обработке прерывания делать что то долго?
это не прерывание это функция. под словом обработчик я имел ввиду код обрабатывающий полученный символ из UDR [которй мы можем получить и через обычную функцию внутри лупа]
b707 не не это не обработчик. про ISR всё понятно что долго и длино.
и вообще я долго и длино фразу использовал чтоб поднять вопросы которые я там спросил. понятно что надо писать быстро и коротко. суть не в этом. суть в вопросах . как долго храниться/что потом и т.д.
это не прерывание это функция. под словом обработчик я имел ввиду код обрабатывающий полученный символ из UDR [которй мы можем получить и через обычную функцию внутри лупа]
это проще, потому что не станет вешать весь МК. Тем не менее рекомендации те же - разделить прием и обработку. В обработке ты только читаешь байт из регистра и кладешь в буфер, а обрабатывающую функцию запускаешь отдельно. И функция твоя должна регулярно прерываться и читать из регистра очередной пришедший байт
суть не в этом. суть в вопросах . как долго храниться/что потом и т.д.
как раз это не суть. От того, хранится ли один байт или например 8 или 16 - мало что меняется. если обработка действительно "долгая" - рано или поздно буфер переполнится и произойдет потеря информации
Поэтому в любом случае "долгая и длинная обработка" должна регулярно читать новые байты из UART - или через прерывание, или через какой-то другой механизм. писать который придется тебе самому.
Поэтому в любом случае "долгая и длинная обработка" должна регулярно читать новые байты из UART - или через прерывание, или через какой-то другой механизм. писать который придется тебе самому.
Но я понимаю, что это не тот случай.
Вставило, решил вспомнить - проверить.
При записи в файл, в MS-DOS и Windows по '\n' писалось 0x0D, 0x0A.
При записи в файл '\r' писалось только 0x0D.
А в Unix, как мне вспоминается, 0x0A было, но могу и ошибаться, более 30 лет прошло.
b707, SergeiL оно понятно что надо постояно записывать из поступающего буфера и т.д.
тут вопрос больше позновательный а не посыл к действию... хочется понять (если приём без буфера. ведь впринципе можем реализоват и без. понятно что с оговрками и не везде) как долго будет байт в буфере и что потом если не заберём..
пропадут все остальные пока это не заберем.. если такой вариант то через сколько времени прилетит следующий чтобы понять сколько у нас времени в запасе...
или перезаписываться будут.. но тогда тоже через какоето время... опять же какое ?
через сколько времени прилетит следующий
Когда ты выставляешь скорость порта, например так:
то 9600 здесь - число битов в секунду. Посчитать из этого, насколько быстро прилетает байт за байтом - надеюсь справишься сам
А пишите то в какой среде? Если в ардуне - то она уже позаботилась о кольцевом буфере и по прерыванию туда собственно и скидывает. А все процедуры ардуиновские достают из буфера а не из регистра МК. Если где то ещё, то пока не встречал МК у которого в стандартных примерах производителя нет кольцевого буфера на UART. Зачем изобретать велосипед? Может проще на кошках учиться? ((С) Операция Ы....)
это не прерывание это функция. под словом обработчик я имел ввиду код обрабатывающий полученный символ из UDR [которй мы можем получить и через обычную функцию внутри лупа]
Тоже не понимаю почему стандартный Сериал не устраивает.
всем устраивает (ну кроме размера конечно).. так интересуюсь для изучения и расширения познаний
если правильно посчитал при скорости 57600 уходит 1мс на байт... осталось не понятным след байт перезаписывает тот что в регистре или пропадает, ну если регистр не успели считать..
Как то не правильно посчитали 1сек/57600*11 = 190 мкс или 0.19 мс.
Пожалуйста подскажите. Наверно успускаю какуюто важную деталь , никак не пойму какую. Плата Nano
2 проблемы
1) ни как не пойму почему строчка 56 печатается только be. стр 28 проверяем если готовы принять следующий символ. по идее не должно быть печати в "нахлёст" или "съеденных" букв. ни как не пойму почему только два символа.
2) если мы в инпут отправляем строку, например "Hello world" то напечать выводит "HHHello world". можно подумать что скетч слишком быстрый и успевает прочесть один и тот же символ дважды/трижды но нет. это происходит только с первым сиволом даже на длинной строке.
подскажите плиз как без буфера исправить данные баги?
первый вопрос решил. остался второй. есть идеи ?