Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Com port? story about lost byte..  (Прочитано 37434 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Dmitry Samoylov
Гость
« : 15-04-2006 08:48 » 

в общем проблемка тут есть одна, написал прогу для отправки данных по Com порту..
Но вот проблема, когда посылаю данные допустим 0xF ---- то и получаю 0xF всё хорошо,
Но если посылаю 0xF1 ------- 1111 0001  то на Rx получаю 111 0001, утерян первый бит
и чем больше посылаю 0xFF1 ---- 1111 1111 0001 на Rx 1111 0111 0001 в общем лажа...
На экран вывожу в десятичном виде, двоичный вид привёл для наглядности
Незнаю где, может порт  "недоностроил"?  в общем я сломался, помогите...
Я уже не на первом форуме спрашиваю. Но везде молчат? Не надо
Код:
DCB           dcb;
   COMMTIMEOUTS  ct;
   HANDLE        port;
   DWORD         bc;
   DWORD         mask;
 
 
   

   dcb.DCBlength=sizeof(DCB);
   dcb.fBinary=1;
   BuildCommDCB("baud=9600 parity=N data=8 stop=1",&dcb);
   
   dcb.fNull=true;
   ct.ReadIntervalTimeout=10;
   ct.ReadTotalTimeoutMultiplier=ct.ReadTotalTimeoutConstant=0;
   ct.WriteTotalTimeoutMultiplier=ct.WriteTotalTimeoutConstant=0;



   port=CreateFile("COM2",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);

   SetCommState(port,&dcb);
   SetCommTimeouts(port,&ct);
   PurgeComm(port,PURGE_TXCLEAR|PURGE_RXCLEAR);
   
   SetupComm(port,256,256);

   

   int buf_out=0xF1;
   int buf_in;




WriteFile(port,&buf_out,11,&bc,NULL);
printf("out: %d\n",buf_out);
////// вижу 241 //// в десятичном


SetCommMask(port,EV_RXCHAR);
WaitCommEvent(port,&mask,NULL);

ReadFile(port,&buf_in,100,&bc,NULL);
printf("in: %d\n",buf_in);
////// вижу 113 //// в десятичном
   
    CloseHandle(port);
Все ответившим благодарен, а реально помогшим тем более....

Не страшно если не знаешь, страшно если не учишся.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 15-04-2006 09:30 » 

WriteFile(port, &buf_out ,11,&bc,NULL);

точно & надо?

аналогиччно в

ReadFile(port,&buf_in,100,&bc,NULL);
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 15-04-2006 11:39 » 

Алексей1153, конечно.

Dmitry Samoylov, а почему у тебя бувером выступает int, а размер ты задаешь произвольный: 11 и 100 байт?! Так нельзя. используй char или подобный тип.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 15-04-2006 11:43 » 

У Тебя вообще какая та чухня написанна!!!!!!!!!!
Что это такое:

int buf_out=0xF1;
int buf_in;

WriteFile(port,&buf_out,11,&bc,NULL);
ReadFile(port,&buf_in,100,&bc,NULL);     // ужас, ты такими темпами всю прогу в памяти затрешь


Тебе надо передовать указатель на массив символов а не на целочисленную переменную.
Пиши так:

char buf_out[11];
char buf_in[100];

WriteFile(port,buf_out,11,&bc,NULL);
ReadFile(port,buf_in,100,&bc,NULL);

А с указателями надо уметь работать, а не то проблем необерешься.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 15-04-2006 14:42 » 

Serg79, поспокойнее Улыбаюсь Человек просто не в курсе
Записан

Dmitry Samoylov
Гость
« Ответ #5 : 18-04-2006 08:45 » 

Ок.. Может я не прав...

Но вот вам вопрос?
Пример: int x=0010; это же реально число 2
           char x[4]="0010"; а это набор символов ? тобишь отдельно ноль, ноль,  и т.д
           Я неуверен в том, что на осциллографе я увижу char x="А"-1010 скорей всего это будет ASCII код "A" - 41.
Это одно и тоже или нет? В том смысле что переферийному уст-ву всё равно как отсылается??
И ещё, а тогда как в шеснадцатиричном виде? А черт его знает...
char x[5]="0xFF" - послал и тоже самое пришло, но это же не правельно?

Если в чем то не прав, извините грамотно вопросы задавать тоже надо уметь... Спасибо за ответы...

PS. И кстати надо помогать а не шуметь по поводу неправельности кода, потому что даже умный сомневается, а глупый уже уверен..
Записан
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #6 : 18-04-2006 09:58 » 

Цитата
int x=0010; это же реально число 2
это реально число 8.

и твоя ошибка не в числах а в ссылках на это число, вместо ссылок на массивы данных.
Записан

Удачного всем кодинга! -=x[PooH]x=-
Dmitry Samoylov
Гость
« Ответ #7 : 18-04-2006 10:24 » 

Ну не знаю 0010  в десятичном виде это 2 (собственно, о чём разговор);

Код:
int x=0xF1;

Так вот
Код:
printf("X = %d", x);
------>на экран>  X=241 в десятичном виде.(осциллограф покажет 11110001) true
Код:
char y[5]="0xF1";
Код:
printf("X = %s",y);
------> на экран> x=0xF1 и заданы они ASCII.(осциллограф покажет
1011 1111 1000 1111 0111 -> в десятичном 0784631, что соответствует значениям ASCII кодам символов.

 :confused:Может я Вообще не понимаю Не понял
Если не прав поправте.. И предложите свои решения. Заранее всем спасибо.

Не страшно если не знаешь, страшно если не учишься.
Записан
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #8 : 18-04-2006 10:45 » 

Цитата
Ну не знаю 0010  в десятичном виде это 2 (собственно, о чём разговор);
Видимо, не знаете (а может я ошибаюсь), но насколько, мне известно, числа начинающиеся с 0 обрабатываются компилятором, как числа в восмеричной системе.
То бишь
int x=10 (фактически 10)
int x=010 (фактически 8 )

====

тут немного о другом говорили...
у Вас

int buf_in // это число (4 байта)

ReadFile(port, &buf_in,100 // а тут получаете ссылку на число, и по этому адресу пишете 100 байт... вопрос: куда будут писаться последние 96 байт

Вам нужно передавать ссылку не на число, а на массив.


Записан

Удачного всем кодинга! -=x[PooH]x=-
Dmitry Samoylov
Гость
« Ответ #9 : 18-04-2006 11:40 » 

Теперь понял!! Спасибо, а то так бы и не заметил..  А по поводу другово, что я описал идей нет? А черт его знает...
Записан
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #10 : 18-04-2006 11:59 » 

Попробуй сделать unsigned char buf_in, buf_out и писать и читать по одному байту.
Записан

Удачного всем кодинга! -=x[PooH]x=-
asker
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 18-04-2006 14:08 » 

Привет Dmitry Samoylov
Если актуален вопрос насчет потери старшего бита,то (если конечно мне память не изменяет) проблема в таймаутах, попробуй поэксперементировать со значением поля WriteTotalTimeoutMultiplier
Записан

С уважением, asker
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 19-04-2006 04:05 » 

Привет Dmitry Samoylov
Если актуален вопрос насчет потери старшего бита,то (если конечно мне память не изменяет) проблема в таймаутах, попробуй поэксперементировать со значением поля WriteTotalTimeoutMultiplier
Таймауты сдесь не причем, проблемма в том, что человек не может понять в чем разница между:

int a = 0xFFFFFFFF;
и
char a[] = "0xFFFFFFFF";

и он думает, что в памяти они должны занимать одинаковый размер.
Записан
Dmitry Samoylov
Гость
« Ответ #13 : 19-04-2006 07:29 » 

Я ещё раз говорю, неужеле не понятно, то что вы видите в линии и то что передаёте, не одно, и тоже. Я зол!  когда char, передаётся ASCII код, когда int его двоичный код...
Причём здесь память  Я зол!? сейчас это не имеет значения для меня? Мне важно чтоб, то что я передал, я увидел и в линии, и на приёмном конце..
Переферийное устройство не воспринимает ASCII код, это понятно? ребят столько разговоров и не одного совета.

Когда идёт передача мне нужно в линии получить 0xF1-1111 0001, а не 1011 1111 1000 1111 0111 -> в десятичном 0784631.
Всё что нужно это просто самим понять вопрос?  Быть такого не может
Записан
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #14 : 19-04-2006 07:50 » 

ты пробовал передавать один байт?
Записан

Удачного всем кодинга! -=x[PooH]x=-
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #15 : 19-04-2006 08:00 » 

 Ага Диман, ты не кипятись. Улыбаюсь
Если тебе надо послать одно шестнадцатиричное значение 0xF1 то делай так:

char a = 0xF1;
WriteFile(ghPort,&a,sizeof(char),&dwWrite,NULL);

а принимай так:

char b;
ReadFile(ghPort,&b,sizeof(char),&dwWrite,NULL);

и я тебе даю 100%, что символы a и b будут одинаковы.  Да-да
Записан
Dmitry Samoylov
Гость
« Ответ #16 : 19-04-2006 09:52 » 

Дайт ошибку... (см строчку 1)  warning C4305: 'initializing' : truncation from 'const int' to 'char'
                       warning C4309: 'initializing' : truncation of constant value

Законно... чЕ дЕлАтЬ... Быть такого не может
Код:

1 char buf_out= 0xF1;
2 char buf_in;
3 WriteFile(port,&buf_out,sizeof(char),&bc,NULL);
4 printf("%d\n",bc);
5 printf("out: %d\n",buf_out);
6
7
8 SetCommMask(port,EV_RXCHAR);
9 WaitCommEvent(port,&mask,NULL);
10
11 ReadFile(port,&buf_in,sizeof(char),&bc,NULL);
12
13
14 printf("in: %d\n",buf_in);
15
16   
17    CloseHandle(port);
« Последнее редактирование: 19-12-2007 21:27 от Алексей1153++ » Записан
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #17 : 19-04-2006 11:05 » 

Не обрашай внимания, компилятор воспринемает константу 0xF1 как int (т.е. он ее понимает как 0x000000F1). Поэтому он и выдает это предуприждение об усичение размера int к char.
Если тебя раздражает это сообщение, то перепеши так:

char buf_out;
buf_out = 0xF1;

и будет все ОК.  Да-да
Записан
Dmitry Samoylov
Гость
« Ответ #18 : 19-04-2006 12:02 » 

Один бит он отправляет. Все верно..
А если нужно отослать 0x0A1 или 0xF21 то тут возникает ошибка как тут то быть?
Даёт ошибки (см. строку 2)warning C4305: '=' : truncation from 'const int' to 'char'
                   (см. строку 2)warning C4309: '=' : truncation of constant value
Код:
1  char buf_out;
 2 buf_out = 0xF1;
 3 char buf_in;
« Последнее редактирование: 19-12-2007 21:29 от Алексей1153++ » Записан
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #19 : 19-04-2006 12:04 » 

Завтра, объясним Тебе что к чему, а сейчас рабочий день уже кончился. Улыбаюсь
Записан
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #20 : 19-04-2006 12:07 » 

Цитата
Один бит он отправляет. Все верно..
не бит, а байт
и число 0xА21 хранится в двух байтах, и, соответственно, buf_out должен состоять из двух байт и передаваться должно два байта.
а вот с числом 0x0A1 проблем не должно быть (это 1 байт)
« Последнее редактирование: 19-04-2006 12:10 от PooH » Записан

Удачного всем кодинга! -=x[PooH]x=-
doublebug
Гость
« Ответ #21 : 19-04-2006 12:57 » 

Цитата
А если нужно отослать 0x0A1 или 0xF21 то тут возникает ошибка как тут то быть?
Даёт ошибки (см. строку 2)warning C4305: '=' : truncation from 'const int' to 'char'
                   (см. строку 2)warning C4309: '=' : truncation of constant value
2х байтовое число

short int ToSend = 0xF1F2;

4x байтовое
int ToSend = 0xF1F2F3F4;

Много байтовое
unsigned char ToSend[_NUMBER_OF_BYTES] = {0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8 ....};
В любом случае тип приема и посылки должны совпадать
а WriteFile и ReadFile им пофигу что посылать и читать им важен адрес откуда/куда и сколько байт.
Те ты указываешь адрес и сколько байт читать/писать и эти функции все делают последовательно.

По поводу типов
unsigned char ToSend[4] = {0xF1, 0xF2, 0xF3, 0xF4};
представляет в памяти число 0xF4F3F2F1;
т.е.

unsigned char ToSend[4] = {0xF1, 0xF2, 0xF3, 0xF4};
int* lpNumber = (int*)ToSend;

(*lpNumber == 0xF4F3F2F1) == TRUE в данном случае.

проще всего не заморачиваться и посылать принимать буфер содержащий Н-е кол-во байт.

« Последнее редактирование: 19-12-2007 21:33 от Алексей1153++ » Записан
Dmitry Samoylov
Гость
« Ответ #22 : 22-04-2006 10:43 » 

Я пока так и не сделал, чтоб два и более байт передовались... А черт его знает...

Ребята, жду вашего кода на несколько байт.
Один байт передаёт легко, а вот два не как.. теряется первый бит?? А черт его знает...
Задача: Такая
1. На приёмном конце 0xF1 или 241 в линии 0 1111 0001 1 на приёмном конце 241
2. На приёмном конце 0xFА1 или 4001 в линии 0 11111010 1_0 00011 на приёмном конце 4001
Вот помогите?
 Для глухих
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #23 : 22-04-2006 11:36 » 

Dmitry Samoylov, пришли мне код, я проверю у себя . Если ты пишешь в VC++6

ящик

alex1153 на яндексе
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #24 : 23-04-2006 17:30 » 

в код ещё не вникал, просто попытался откомпилить. Первое, что бросилось в глаза (при чём даже не мне, а компилятору) вот что:

   unsigned char buf_out =0xF1F2;
   char buf_in;

   WriteFile(port,buf_out,sizeof(char),&bc,NULL);
   ReadFile(port,buf_in,sizeof(char),&bc,NULL);

так даже не откомпилится, потому что char неявно преобразовать к (void*) низя.
(мне кажется, тебе уже выше не раз говорили об этом)
объяви массив, а НЕ ОДНУ переменную:
   unsigned char buf_out [100]={0xF2,0xF1,"my text"};
   char buf_in[100];

а тут:
   WriteFile(port,buf_out,sizeof(char),&bc,NULL);
   ReadFile(port,buf_in,sizeof(char),&bc,NULL);
становится понятно, почему больше 1 байта не передаётся, дык поставь:
   WriteFile(port,buf_out,sizeof(buf_out),&bc,NULL);
   ReadFile(port,buf_in,sizeof(buf_in),&bc,NULL);



с портом не проверял, у меня один ком, но в снифере видно всё

пробуй...

а, не пугайся, что передастся 100 байт Улыбаюсь
« Последнее редактирование: 23-04-2006 17:50 от Алексей1153 » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #25 : 23-04-2006 17:49 » 

а настройки таймаутов в структуре COMMTIMEOUTS я бы поставил так:
    ReadIntervalTimeout=1;          /* Maximum time between read chars. */
    ReadTotalTimeoutMultiplier=1;   /* Multiplier of characters.        */
    ReadTotalTimeoutConstant=10;     /* Constant in milliseconds.        */
    WriteTotalTimeoutMultiplier=1;  /* Multiplier of characters.        */
    WriteTotalTimeoutConstant=10;    /* Constant in milliseconds.        */

хотя для твоего железа возможно надо будет подбирать
    ReadIntervalTimeout
    ReadTotalTimeoutConstant
    WriteTotalTimeoutConstant
----------------
структура DCB. У тебя написано:
   dcb.fNull=true;//во первых тип неправильный - TRUE надо бы а не true

в мсдн:
If this member is TRUE, null bytes are discarded when received.

то есть поставь всё таки
    dcb.fNull=0;
Записан

Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #26 : 24-04-2006 04:15 » 

Парни, Я думаю, что надо отправлять отсюда Дмитрия Самойлова в тему "Для начинающих" или "C/C++", т.к. он незнает даже основ работы с основными типами данных и массивами, неговоря уже о указателях.
Мы сдесь только и делаем, что пытаемся ему объяснить в чем разница между "char" и "int".
Записан
Dmitry Samoylov
Гость
« Ответ #27 : 24-04-2006 07:10 » 

int 2 байта 16 бит занимает в памяти (от -32000 до 32000)
int 4 байта  32 бита занимает в памяти (Значения от-2 100 000 000 до 2 100 000 000)
short 2 байта

char 1 байт 8 бит-256 значений символов

Serg79 все время пытаешься уличить внезнании, собеседника это не правельно.
Мне кажется ответ выше... Спасибо
Записан
Mаster
Гость
« Ответ #28 : 05-06-2008 09:40 » 

Привет!
Решил отписать решение проблемы, т.к. гуглением данная ветка вылезла первой и, к сожалению, в ней не оказалось решения.
В общем, IMHO зря Вы парня зачмырили. Проблема так и повисла, и дело совершенно не в размерах переменных, а в том, что терялся первый бит посылки.
Я столкнулся с той же проблемой и решил следующим образом.
Заметил, что после перезагрузки системы ситуация проявляется - 1бит из байта при передаче сбрасывается в 0. Но после запуска терминалки (в моём случае Terra Term Pro) на проверяемом COM-порте ситуация выправляется: первый бит передаётся корректно.
В отладчике остановился после получения структуры DCB по GetCommState и сравнил поля до и после запуска терминалки. Оказалось, поля XonLim и XoffLim отличаются: 0007 и 0008, 1100 и 0000 соответственно. После правки поля XonLim первый бит стал передаваться корректно, в том числе, и после перезапуска системы.
Удачи!
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #29 : 05-06-2008 12:30 » 

Mаster, не надо гадать на кофейной гуще - действуй по документации.
XON и XOFF используются только в программном режиме управления потоком.
Эмпирические методы дадут себя знать позже в виде перемежающихся ошибок и тогда, когда меньше всего ждешь их.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines