Полная версия этой страницы:
работа с COM портом
TigerSHARC
Feb 21 2011, 10:17
Здравствуйте!
Никак не могу правильно прочитать данные из COM-порта.
Мой процессор отправляет в компорт в бесконечном цикле (каждые 156 мкс) int-число и две эскейп последовательности в таком виде
int d = 123;
printf("%d"\r\n, d); //отправляю в порт
Теперь моя задача считать на компьютере эти данные в такую же переменную. Посредствам стандартных средств в СBuilder я заливаю всё что передаёться в COM-пот в массив чаров buf зармером 255.
Вопрос: как считывать последовательно эти данные из массива buf в переменную типа int?
Как я понимаю нужно как то логически в цикле разделять набор чисел в массиве buf, а затем преобразовывать в int. Но конструкцию никак не придумаю(((((
буду признателен за любую помощь.
skripach
Feb 21 2011, 10:50
Цитата
printf("%d"\r\n, d);
printf("%d\r\n", d);
Используйте функцию стандартную atoi.
Zelepuk
Feb 21 2011, 11:01
Что за аtoi ?
Функция printf посылает в порт микроконтроллера числа. Со стороны микроконтроллера всё впорядке. Мне же нужно со стороны хоста(бытовой компьютер) разобрать по сути непрерывный поток чаров в буфере buf и получить числа int, которые в этом потоке передаются, разделяемые esc-последовательностями (\n\r)
Блин, опять с чужого компа зажёл... сорри)
Как организован доступ к вашему буферу?
Какому числовому значению равны ваши \n,\r?
Какая длина вашего int в байтах?
Почитайте вот это
Кольцевой буфер
sergeeff
Feb 21 2011, 18:19
У вас какая скорость передачи в COM? Скорее всего не выше 115200 baud, т.е. 8,7 мкс на бит. Стандартная посылка 8+1 стоп. Итого 9 бит на байт. Вы посылаете int (вроде как 4 байта для TigerShark) + CRLF. Итого 6*9*8,7 = 469 мкс.
Вы шлете данные каждые каждые 156 мкс. И что вы хотите читать?
TigerSHARC
Feb 21 2011, 18:21
За ссылку про кольцевой буфер спасибо.
А задача уже решена. Вот решение кому интересно:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main (int argc, char ** argv)
{
char buf[] = "32321\n\r32322\n\r32323\n\r", *pb = NULL;
// здесь полагаем, что buf мы прочитали из COM порта
pb = buf;
for(;;)
{
// проверяем есть ли начало escape последовательности
char *ptr = strstr(pb, "\n\r");
if (!ptr)
break;
// если да, то завершаем найденный указатель на \0
// чтобы функция atoi() смогла отработать
*ptr = '\0';
int a = atoi(pb);
// теперь в a бинарное представление строки
// выводим в консоль прочитанное число
if (a)
printf("I've just read %d!\n", a);
// смещаемся на начало новой строки
pb = ptr + 1;
}
return 0;
}
только это вариант для статического буфера buf, а у меня он меняется, так как данные идут непрерывно, но думаю теперь это не проблема, главное концепция ясна.
Цитата(Zelepuk @ Feb 21 2011, 14:01)

Функция printf посылает в порт микроконтроллера числа... разделяемые esc-последовательностями (\n\r)
Функция printf имеет "зеркальную" функцию scanf (или родственные ей - fscanf, sscanf) - на персоналке используйте одну из них. Символы \n\r имеют шестнадцатиричные коды 0A и 0D - "перевод строки" и "возврат каретки".
RabidRabbit
Feb 21 2011, 18:27
Цитата(sergeeff @ Feb 21 2011, 21:19)

У вас какая скорость передачи в COM? Скорее всего не выше 115200 baud, т.е. 8,7 мкс на бит. Стандартная посылка 8+1 стоп. Итого 9 бит на байт.
А если прибавить стартовый бит, ситуация ещё более усугубляется
TigerSHARC
Feb 21 2011, 18:31
Цитата(sergeeff @ Feb 21 2011, 21:19)

У вас какая скорость передачи в COM? Скорее всего не выше 115200 baud, т.е. 8,7 мкс на бит. Стандартная посылка 8+1 стоп. Итого 9 бит на байт. Вы посылаете int (вроде как 4 байта для TigerShark) + CRLF. Итого 6*9*8,7 = 469 мкс.
Вы шлете данные каждые каждые 156 мкс. И что вы хотите читать?
я посылаю строку в COM-порт. эта строка соответствует набору чмсел в int.
Короче данные идут(это видно в терминале).
Пардон!)) данные идут каждые 1 мс)
Поясню для чего я это делаю. Просто мой процессорный модуль, который шлёт данные, выступает в качестве некоего АЦП, который оцифровал синусоиу и шлёт данные (числа - это отсчёты синуса). Так вот, получается что скорость передачи данных накладывает ограничения на частоту дискретизации этого виртуального "синуса"
zltigo
Feb 21 2011, 18:44
QUOTE (skripach @ Feb 21 2011, 13:50)

Используйте функцию стандартную atoi.
Запомните, atoi()
НЕ является стандартной ANSI функцией. По этой причине ее нет в доброй половине библиотек.
sergeeff
Feb 21 2011, 18:47
Цитата(TigerSHARC @ Feb 21 2011, 21:31)

Пардон!)) данные идут каждые 1 мс)
Вы обладаете могучим талантом запудривания мозгов!
Для завершения советую прочитать где-нибудь на просторах inet'a, что называется (и почему) esc-последовательностью.
Цитата(RabidRabbit @ Feb 21 2011, 20:27)

А если прибавить стартовый бит, ситуация ещё более усугубляется
А если приглядеться внимательнее к передаваемому формату, то для 32-битового числа со знаком получается
±2147483648, итого 12 байтов. x10 = 120 битов. x8.7 = 1042us
Цитата(zltigo @ Feb 21 2011, 20:44)

Запомните, atoi() НЕ является стандартной ANSI функцией. По этой причине ее нет в доброй половине библиотек.
atoi как раз является... только она здесь не нужна.
TigerSHARC
Feb 21 2011, 19:21
Цитата(sergeeff @ Feb 21 2011, 21:47)

Вы обладаете могучим талантом запудривания мозгов!
Для завершения советую прочитать где-нибудь на просторах inet'a, что называется (и почему) esc-последовательностью.
здесь я их использовал для того чтобы данные отображались в терминале красиво, столбиком. Толкьо и всего. Но никак для разделения чисел как таковых.
ничего я не запудриваю просто вы щите подвоха в постановке задачи. А тем временем она уже решена))
код выше я уже прикладывал.
ВОТ!
Цитата(ViKo @ Feb 21 2011, 21:58)

А если приглядеться внимательнее к передаваемому формату, то для 32-битового числа со знаком получается ±2147483648, итого 12 байтов. x10 = 120 битов. x8.7 = 1042us
atoi как раз является... только она здесь не нужна.
как не нужна? код выше работает!
sergeeff
Feb 21 2011, 19:24
Цитата(ViKo @ Feb 21 2011, 21:58)

А если приглядеться внимательнее к передаваемому формату, то для 32-битового числа со знаком получается ±2147483648, итого 12 байтов. x10 = 120 битов. x8.7 = 1042us
Ну автор же дошел до светлой мысли (глядя в осцилограф), что COM оказывается сильно тормозит его ADC. Потом додумается и до того, что его "протокол" мягко говоря ...
Цитата(TigerSHARC @ Feb 21 2011, 21:21)

как не нужна? код выше работает!
Я думал, речь про передачу идет.
Т.е., сначала вы строку преобразовываете в целое, а потом выводите целое в виде строки?!
А просто строку вывести что-то мешает?
TigerSHARC
Feb 21 2011, 20:02
Ребятааааа!!! Ну какой ещё ADC)))) есть только микроконтроллер, который генерирует числа!!!! ну ладно, пусть ограничение на частоту передаваемых чисел есть....
Я сначала передаю в COM порт int путём printf.
Затем принимаю в буфер чаров значения принимаемые с микроконтроллера в виде последовательности чаров. Затем преобразую их в инты (atoi) и записываю в другой буфер.
sergeeff
Feb 21 2011, 20:17
Цитата(TigerSHARC @ Feb 21 2011, 23:02)

Просто мой процессорный модуль, который шлёт данные, выступает в качестве некоего АЦП...
У вас что, провалы в памяти? Это же ваши слова?
Вы можете делать со своим контроллером абсолютно, что вашей душе угодно. Только зачем вы коллегам по форуме голову морочите невнятной постановкой вопросов и ошибками?
TigerSHARC
Feb 21 2011, 20:32
Ладно, думаю всё это особенности общения на форуме)
Я же подумал что вы решили что у меня АЦП шлёт данные в ком порт, который его тормозит....
В любом случае всё решено! Всем спасибо!
zltigo
Feb 21 2011, 23:10
QUOTE (ViKo @ Feb 21 2011, 21:58)

atoi как раз является... только она здесь не нужна.
Дело не в ненужности, а в том, что НЕ ANSI стандартная. Кроме того она часто является просто лишней оберткой для strtol().
_Pasha
Feb 22 2011, 05:20
Если не хватает скорости, но очень хочется именно в текстовом виде, используйте 7-битный формат.
Цитата(zltigo @ Feb 22 2011, 01:10)

Дело не в ненужности, а в том, что НЕ ANSI стандартная.
В книжках (Г.Шилдт) она фигурирует, как стандартная. Вот первая же ссылка из Интернета, я понимаю так, что по крайней мере, в C99 она уже есть.
http://www.thinkage.ca/english/gcos/expl/c/lib/atoi.htmlВот еще:
StandardsThe
atoi function conforms to ISO/IEC 9945-1:1990 ("POSIX.1"), ISO/IEC 9899:1990 ("ISO C90"), and ISO/IEC 9899:1999 ("ISO C99").
Другое дело itoa - вот такой функции в стандарте нет.
zltigo
Feb 22 2011, 10:55
QUOTE (ViKo @ Feb 22 2011, 10:43)

в C99 она уже есть.
В 99 - есть, в чистом ANSI - нет

. К огромному сожалению, спустя 12 лет не все компиляторы С99 соответствуют

, или, как уже писал, делают только формальные обертки

.
ar__systems
Feb 26 2011, 14:00
Цитата(TigerSHARC @ Feb 21 2011, 05:17)

две эскейп последовательности в таком виде
int d = 123;
printf("%d"\r\n, d);
Это не ескейп последовательность а банальный перевод строки.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.