Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: работа с COM портом
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
TigerSHARC
Здравствуйте!
Никак не могу правильно прочитать данные из COM-порта.

Мой процессор отправляет в компорт в бесконечном цикле (каждые 156 мкс) int-число и две эскейп последовательности в таком виде

int d = 123;
printf("%d"\r\n, d); //отправляю в порт

Теперь моя задача считать на компьютере эти данные в такую же переменную. Посредствам стандартных средств в СBuilder я заливаю всё что передаёться в COM-пот в массив чаров buf зармером 255.

Вопрос: как считывать последовательно эти данные из массива buf в переменную типа int?
Как я понимаю нужно как то логически в цикле разделять набор чисел в массиве buf, а затем преобразовывать в int. Но конструкцию никак не придумаю(((((
буду признателен за любую помощь.
skripach
Цитата
printf("%d"\r\n, d);

printf("%d\r\n", d);

Используйте функцию стандартную atoi.
Zelepuk
Что за аtoi ?

Функция printf посылает в порт микроконтроллера числа. Со стороны микроконтроллера всё впорядке. Мне же нужно со стороны хоста(бытовой компьютер) разобрать по сути непрерывный поток чаров в буфере buf и получить числа int, которые в этом потоке передаются, разделяемые esc-последовательностями (\n\r)



Блин, опять с чужого компа зажёл... сорри)
zombi
Как организован доступ к вашему буферу?
Какому числовому значению равны ваши \n,\r?
Какая длина вашего int в байтах?
Почитайте вот это Кольцевой буфер
sergeeff
У вас какая скорость передачи в COM? Скорее всего не выше 115200 baud, т.е. 8,7 мкс на бит. Стандартная посылка 8+1 стоп. Итого 9 бит на байт. Вы посылаете int (вроде как 4 байта для TigerShark) + CRLF. Итого 6*9*8,7 = 469 мкс.

Вы шлете данные каждые каждые 156 мкс. И что вы хотите читать?
TigerSHARC
За ссылку про кольцевой буфер спасибо.
А задача уже решена. Вот решение кому интересно:

#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
Цитата(sergeeff @ Feb 21 2011, 21:19) *
У вас какая скорость передачи в COM? Скорее всего не выше 115200 baud, т.е. 8,7 мкс на бит. Стандартная посылка 8+1 стоп. Итого 9 бит на байт.
А если прибавить стартовый бит, ситуация ещё более усугубляется sm.gif
TigerSHARC
Цитата(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
QUOTE (skripach @ Feb 21 2011, 13:50) *
Используйте функцию стандартную atoi.

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


Вы обладаете могучим талантом запудривания мозгов!

Для завершения советую прочитать где-нибудь на просторах inet'a, что называется (и почему) esc-последовательностью.
ViKo
Цитата(RabidRabbit @ Feb 21 2011, 20:27) *
А если прибавить стартовый бит, ситуация ещё более усугубляется

А если приглядеться внимательнее к передаваемому формату, то для 32-битового числа со знаком получается ±2147483648, итого 12 байтов. x10 = 120 битов. x8.7 = 1042us

Цитата(zltigo @ Feb 21 2011, 20:44) *
Запомните, atoi() НЕ является стандартной ANSI функцией. По этой причине ее нет в доброй половине библиотек.

atoi как раз является... только она здесь не нужна.
TigerSHARC
Цитата(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
Цитата(ViKo @ Feb 21 2011, 21:58) *
А если приглядеться внимательнее к передаваемому формату, то для 32-битового числа со знаком получается ±2147483648, итого 12 байтов. x10 = 120 битов. x8.7 = 1042us


Ну автор же дошел до светлой мысли (глядя в осцилограф), что COM оказывается сильно тормозит его ADC. Потом додумается и до того, что его "протокол" мягко говоря ...
ViKo
Цитата(TigerSHARC @ Feb 21 2011, 21:21) *
как не нужна? код выше работает!

Я думал, речь про передачу идет.
Т.е., сначала вы строку преобразовываете в целое, а потом выводите целое в виде строки?!
А просто строку вывести что-то мешает?
TigerSHARC
Ребятааааа!!! Ну какой ещё ADC)))) есть только микроконтроллер, который генерирует числа!!!! ну ладно, пусть ограничение на частоту передаваемых чисел есть....

Я сначала передаю в COM порт int путём printf.
Затем принимаю в буфер чаров значения принимаемые с микроконтроллера в виде последовательности чаров. Затем преобразую их в инты (atoi) и записываю в другой буфер.
sergeeff
Цитата(TigerSHARC @ Feb 21 2011, 23:02) *
Просто мой процессорный модуль, который шлёт данные, выступает в качестве некоего АЦП...


У вас что, провалы в памяти? Это же ваши слова?

Вы можете делать со своим контроллером абсолютно, что вашей душе угодно. Только зачем вы коллегам по форуме голову морочите невнятной постановкой вопросов и ошибками?

TigerSHARC
Ладно, думаю всё это особенности общения на форуме)

Я же подумал что вы решили что у меня АЦП шлёт данные в ком порт, который его тормозит....

В любом случае всё решено! Всем спасибо!
zltigo
QUOTE (ViKo @ Feb 21 2011, 21:58) *
atoi как раз является... только она здесь не нужна.

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

В книжках (Г.Шилдт) она фигурирует, как стандартная. Вот первая же ссылка из Интернета, я понимаю так, что по крайней мере, в C99 она уже есть.
http://www.thinkage.ca/english/gcos/expl/c/lib/atoi.html
Вот еще:

Standards
The 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
QUOTE (ViKo @ Feb 22 2011, 10:43) *
в C99 она уже есть.

В 99 - есть, в чистом ANSI - нет sad.gif. К огромному сожалению, спустя 12 лет не все компиляторы С99 соответствуют sad.gif, или, как уже писал, делают только формальные обертки sad.gif.

ar__systems
Цитата(TigerSHARC @ Feb 21 2011, 05:17) *
две эскейп последовательности в таком виде

int d = 123;
printf("%d"\r\n, d);

Это не ескейп последовательность а банальный перевод строки.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.