Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.79/19: Рейтинг темы: голосов - 19, средняя оценка - 4.79
25 / 25 / 2
Регистрация: 08.11.2011
Сообщений: 284

Чтение байтов из порта

02.01.2013, 13:09. Показов 3739. Ответов 1
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Записываю одни и те же данные в порт, устройство отвечает произвольное количество раз, и через сниффер видно что запись в порт идет, а вот прибор не отвечает. В чем проблема ?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
HANDLE readerRMT69L;    //дескриптор потока чтения из порта
DWORD WINAPI ReadThreadRMT69L(LPVOID);
void ReadPrintingRMT69L(void);
//---------------------------------------------------------------------------
//главная функция потока, реализует приём байтов из COM-порта
DWORD WINAPI ReadThreadRMT69L(LPVOID)
{
        COMSTAT comstat;        //структура текущего состояния порта, в данной программе используется для определения количества принятых в порт байтов
        DWORD btr, temp, mask, signal;  //переменная temp используется в качестве заглушки
        int T;
 
        overlappedRMT69L.hEvent = CreateEvent(NULL, true, true, NULL);  //создать сигнальный объект-событие для асинхронных операций
        SetCommMask(COMportRMT69L, EV_RXCHAR);                              //установить маску на срабатывание по событию приёма байта в порт
        while(1)                        //пока поток не будет прерван, выполняем цикл
        {
                WaitCommEvent(COMportRMT69L, &mask, &overlappedRMT69L);                 //ожидать события приёма байта (это и есть перекрываемая операция)
                signal = WaitForSingleObject(overlappedRMT69L.hEvent, INFINITE);    //приостановить поток до прихода байта
                if(signal == WAIT_OBJECT_0)                     //если событие прихода байта произошло
                {
                        if(GetOverlappedResult(COMportRMT69L, &overlappedRMT69L, &temp, true)) //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent
                        if((mask & EV_RXCHAR)!=0)                   //если произошло именно событие прихода байта
                        {
                                ClearCommError(COMportRMT69L, &temp, &comstat);     //нужно заполнить структуру COMSTAT
                                btr = comstat.cbInQue;                              //и получить из неё количество принятых байтов
                                if(btr==59)                                     //если действительно есть байты для чтения
                                {
                                        ReadFile(COMportRMT69L, bufrdRMT69L, btr, &temp, &overlappedRMT69L);     //прочитать байты из порта в буфер программы
                                        ReadPrintingRMT69L();                           //вызываем функцию для вывода данных на экран и в файл
                                        Form1->Label12->Caption="ОК";
                                        Form1->Label12->Font->Color=clGreen;
                                        T=0;
                                }
                                else T++;
                                if (T>3) {Form1->Label12->Caption="ОШИБКА";Form1->Label12->Font->Color=clRed; if (Form1->Image5->Visible==false) Beep(1000,200);}
                        }
                }
        }
}
Инициализация порта:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
void COMOpenRMT69L()
{
        String portname;         //имя порта (например, "COM1", "COM2" и т.д.)
        DCB dcb;                //структура для общей инициализации порта DCB
        COMMTIMEOUTS timeouts;  //структура для установки таймаутов
        portname = "\\\\.\\COM12";  //получить имя выбранного порта
        //открыть порт, для асинхронных операций обязательно нужно указать флаг FILE_FLAG_OVERLAPPED
        COMportRMT69L = CreateFile(portname.c_str(),GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
        //здесь:
        // - portname.c_str() - имя порта в качестве имени файла, c_str() преобразует строку типа String в строку в виде массива типа char, иначе функция не примет
        // - GENERIC_READ | GENERIC_WRITE - доступ к порту на чтение/записть
        // - 0 - порт не может быть общедоступным (shared)
        // - NULL - дескриптор порта не наследуется, используется дескриптор безопасности по умолчанию
        // - OPEN_EXISTING - порт должен открываться как уже существующий файл
        // - FILE_FLAG_OVERLAPPED - этот флаг указывает на использование асинхронных операций
        // - NULL - указатель на файл шаблона не используется при работе с портами
        if(COMportRMT69L == INVALID_HANDLE_VALUE)            //если ошибка открытия порта
        {
                // Form1->SpeedButton1->Down = false;           //отжать кнопку
                // Form1->StatusBar1->Panels->Items[0]->Text = "Не удалось открыть порт";       //вывести сообщение в строке состояния
                return;
        }
        //инициализация порта
        dcb.DCBlength = sizeof(DCB);    //в первое поле структуры DCB необходимо занести её длину, она будет использоваться функциями настройки порта для контроля корректности структуры
        //считать структуру DCB из порта
        if(!GetCommState(COMportRMT69L, &dcb))  //если не удалось - закрыть порт и вывести сообщение об ошибке в строке состояния
        {
                COMCloseRMT69L();
                // Form1->StatusBar1->Panels->Items[0]->Text  = "Не удалось считать DCB";
                return;
        }
        //инициализация структуры DCB
        dcb.BaudRate = 57600;                     //задаём скорость передачи 115200 бод
        dcb.fBinary = TRUE;                       //включаем двоичный режим обмена
        dcb.fOutxCtsFlow = FALSE;                 //выключаем режим слежения за сигналом CTS
        dcb.fOutxDsrFlow = FALSE;                 //выключаем режим слежения за сигналом DSR
        dcb.fDtrControl = DTR_CONTROL_DISABLE;    //отключаем использование линии DTR
        dcb.fDsrSensitivity = FALSE;              //отключаем восприимчивость драйвера к состоянию линии DSR
        dcb.fNull = FALSE;                        //разрешить приём нулевых байтов
        dcb.fRtsControl = RTS_CONTROL_DISABLE;    //отключаем использование линии RTS
        dcb.fAbortOnError = FALSE;                //отключаем остановку всех операций чтения/записи при ошибке
        dcb.ByteSize = 8;                         //задаём 8 бит в байте
        dcb.Parity = 0;                           //отключаем проверку чётности
        dcb.StopBits = 0;                         //задаём один стоп-бит
        //загрузить структуру DCB в порт
        if(!SetCommState(COMportRMT69L, &dcb))  //если не удалось - закрыть порт и вывести сообщение об ошибке в строке состояния
        {
                COMCloseRMT69L();
                // Form1->StatusBar1->Panels->Items[0]->Text  = "Не удалось установить DCB";
                return;
        }  
        //установить таймауты
        timeouts.ReadIntervalTimeout = 0;          //таймаут между двумя символами
        timeouts.ReadTotalTimeoutMultiplier = 0;       //общий таймаут операции чтения
        timeouts.ReadTotalTimeoutConstant = 0;         //константа для общего таймаута операции чтения
        timeouts.WriteTotalTimeoutMultiplier = 0;      //общий таймаут операции записи
        timeouts.WriteTotalTimeoutConstant = 0;        //константа для общего таймаута операции записи
        //записать структуру таймаутов в порт
        if(!SetCommTimeouts(COMportRMT69L, &timeouts))  //если не удалось - закрыть порт и вывести сообщение об ошибке в строке состояния
        {
                COMCloseRMT69L();
                //Form1->StatusBar1->Panels->Items[0]->Text  = "Не удалось установить тайм-ауты";
                ShowMessage("Не удалось установить тайм-ауты RMT69L");
                return;
        }
        //установить размеры очередей приёма и передачи
        SetupComm(COMportRMT69L,2000,2000);
 
        //директории
        TDateTime CurrentDate = Date(); // это текущая дата
        unsigned short year,month,day;
        CurrentDate.DecodeDate(&year, &month, &day);
        TVarRec DateRMT69L[]={day,month,year};
        AnsiString
        path1RMT69L="ТрендыRMT69L\\",
        path2RMT69L="ТрендыRMT69L\\"+Format("%.2d.%.2d.%.2d.txt",DateRMT69L,2);
        //проверка существовиния директорий
        if(DirectoryExists(path1RMT69L.c_str())==false){CreateDirectory (path1RMT69L.c_str(), NULL);}
        //открыть файл или создать если отсутствует для записи данных
        FILE *RMT69L = fopen(path2RMT69L.c_str(),"a+t");
        
        PurgeComm(COMportRMT69L, PURGE_RXCLEAR);     //очистить принимающий буфер порта
        readerRMT69L = CreateThread(NULL, 0, ReadThreadRMT69L, NULL, 0, NULL);          //создаём поток чтения, который сразу начнёт выполняться (предпоследний параметр = 0)
        writerRMT69L = CreateThread(NULL, 0, WriteThreadRMT69L, NULL, CREATE_SUSPENDED, NULL);  //создаём поток записи в остановленном состоянии (предпоследний параметр = CREATE_SUSPENDED)
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
02.01.2013, 13:09
Ответы с готовыми решениями:

Объединение и чтение байтов
Доброго и с наступающим! :drink: Работаю с байтами, и необходимо объединять две переменные в одну, тоесть типа так: TByteDynArray...

Чтение из COM порта
Приветствую всех! Для чтения из COM порта использую функцию ReadFile. Третьим параметром в данной функции указывается число байт для...

Непрерывное чтение из Com-порта
После подачи запроса необходимо дождаться ответа с порта. хотел дописать существующую функцию и непрерывно повторять, однако...

1
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
04.01.2013, 12:34
как вяжется
Цитата Сообщение от GrukhvinEV Посмотреть сообщение
устройство отвечает произвольное количество раз
с
Цитата Сообщение от GrukhvinEV Посмотреть сообщение
прибор не отвечает
если вы посылаете корректный запрос, а прибор не отвечает значит ваш запрос некорректный. если он отвечает, но программа не видит этого - копайте код: он у вас термоядерный - с потоками, с событиями, первый раз такое вижу, баллистические ракеты программируете? зачем такие навороты на ровном месте?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
04.01.2013, 12:34
Помогаю со студенческими работами здесь

Асинхронное чтение данных из COM порта
Приветствую всех. Совсем недавно получил я нелестные высказывания по поводу моего способа чтения информации из COM порта. Решил...

Чтение и обработка данных из СОМ порта
Добрый день! Есть программа для работы с внешним устройством через СОМ порт. Данные у меня она отправляет на ура, а вот с чтением у меня...

Чтение с COM порта потока данных на WinAPI функциях.
ПОМГИТЕ ПОЖАЛУСТО. ПОДКИНТЕ КТО НИБУДЬ ИСХОДНИК КОДА ДЛЯ ЧТЕНИЯ ПОТОКА ДАННЫХ ЧТО БУДЕТ БУДУ ВСЕМУ РАД :help:

c# SerialPort.ReadExisting Чтение байтов из последовательного порта
Доброе время суток. Подскажите пожалуйста каким образом используя SerialPort.ReadExisting прочитать данные из порта в формате байтов. На...

Выполнить чтение всех байтов с файла с помощью FileInputStream в массив байтов
Выполнить чтение всех байтов с файла с помощью FileInputStream в массив байтов. Создать строку на основе прочитанного массива байтов и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru