Форум программистов, компьютерный форум CyberForum.ru

Работа с COM портом - C++

Восстановить пароль Регистрация
 
vadim09
6 / 6 / 1
Регистрация: 04.08.2012
Сообщений: 62
25.03.2013, 22:47     Работа с COM портом #1
Доброго времени суток, уважаемые форумчане!
Помогите разобраться с COM портом. Хотя бы с чего начать.
На большинстве ресурсов предлогают использовать функции WinAPI, но я не могу с ними разобраться, так как я начинающий программист и мало чего знаю. Везде пишут описания функций ,а вот примерных программ нигде не нашел
Для начала, хотелось бы научиться хотя бы поморгать светодиодами, а там дальше сложней и сложней.
Спасибо.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Арсенал
144 / 66 / 6
Регистрация: 30.12.2011
Сообщений: 137
25.03.2013, 23:41     Работа с COM портом #2
vadim09, Никаких сложностей нет

Вот рабочая версия на Qt

Кликните здесь для просмотра всего текста
C++ (Qt)
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
#include <QThread>
#include <QMutex>
#include <QDebug>
 
#include <windows.h>
 
class WorkComPort : public QThread
{
    Q_OBJECT
public:
    WorkComPort();
    ~WorkComPort();
 
    void setStringPort(QString port);
    QString getStringMessage() const;
 
    bool openComPort();
    bool configComPort();
    bool isBusyComPort() const;
    void closeComPort();
    void setComPortSettings(DWORD baud, BYTE stopBits, BYTE byteSize, BYTE parity, DWORD dtr, DWORD rts);
 
    void writeToComPort(unsigned char code);
    void writeToComPort(QString &string);
 
signals:
    void send_data(QByteArray arr);
 
private:
    HANDLE          m_hComPort;
    DCB             dcb;
    COMMTIMEOUTS    comTimeOuts;
    COMSTAT         comStat;
 
    QString         m_stringComPort;
    QString         m_stringMessage;
 
    QMutex          m_mutex;
 
    DWORD           m_baudrate;
    BYTE            m_stopbits;
    BYTE            m_bytesize;
    BYTE            m_parity;
    DWORD           m_dtr;
    DWORD           m_rts;
 
    DWORD getReceiveBytes();
    DWORD readFromComPort(BYTE *inBuff, DWORD nInBytes);
 
    void arrayFromComPort(const unsigned char* buf, const int size);
 
protected:
    void run();
};


Кликните здесь для просмотра всего текста
C++ (Qt)
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#include "threadcom.h"
 
WorkComPort::WorkComPort()
{
    m_hComPort      = 0;
    m_stringComPort = "";
    m_stringMessage = "";
}
 
WorkComPort::~WorkComPort()
{
    this->terminate();
    this->wait(1);
}
 
void WorkComPort::setStringPort(QString port)
{
    m_stringComPort = port;
}
 
QString WorkComPort::getStringMessage() const
{
    return m_stringMessage;
}
 
void WorkComPort::setComPortSettings(DWORD baud, BYTE stopBits, BYTE byteSize, BYTE parity, DWORD dtr, DWORD rts)
{
    m_baudrate  = baud;
    m_stopbits  = stopBits;
    m_bytesize  = byteSize;
    m_parity    = parity;
    m_dtr       = dtr;
    m_rts       = rts;
}
 
bool WorkComPort::openComPort()
{
    m_mutex.lock();
    if (m_hComPort != 0)
    {
        m_mutex.unlock();
        return false;
    }
 
    m_hComPort = CreateFileA(m_stringComPort.toAscii(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
                           0, OPEN_EXISTING, 0, 0);
 
    if (m_hComPort == INVALID_HANDLE_VALUE)
    {
        m_stringMessage = tr("Port %1 not open.").arg(m_stringComPort);
        m_mutex.unlock();
        return false;
    }
    else
    {
        m_stringMessage = tr("Port %1 open.").arg(m_stringComPort);
        m_mutex.unlock();
        return true;
    }
}
 
bool WorkComPort::isBusyComPort() const
{
    return (m_hComPort) ? false : true;
}
 
bool WorkComPort::configComPort()
{
    m_mutex.lock();
    if (!(GetCommState(m_hComPort, &dcb)))
    {
        CloseHandle(m_hComPort);
        m_mutex.unlock();
        return false;
    }
 
    //------------------
    dcb.BaudRate = m_baudrate;
    dcb.ByteSize = m_bytesize;
    dcb.Parity   = m_parity;
    dcb.StopBits = m_stopbits;
 
    dcb.fDtrControl = m_dtr;
    dcb.fRtsControl = m_rts;
    //------------------
 
 
    if (!(SetCommState(m_hComPort, &dcb)))
    {
        CloseHandle(m_hComPort);
        m_mutex.unlock();
        return false;
    }
 
    comTimeOuts.ReadIntervalTimeout         = 0;
    comTimeOuts.ReadTotalTimeoutConstant    = 0;
    comTimeOuts.ReadTotalTimeoutMultiplier  = 0;
    comTimeOuts.WriteTotalTimeoutConstant   = 0;
    comTimeOuts.WriteTotalTimeoutMultiplier = 0;
 
    SetCommTimeouts(m_hComPort, &comTimeOuts);
 
    msleep(500);
    PurgeComm(m_hComPort, PURGE_RXCLEAR | PURGE_TXCLEAR);
    msleep(500);
 
    SetupComm(m_hComPort, 256, 256);
    SetCommMask(m_hComPort, EV_BREAK | EV_RXCHAR | EV_TXEMPTY | EV_RXFLAG);
 
    m_mutex.unlock();
    return true;
}
 
void WorkComPort::closeComPort()
{
    m_mutex.lock();
    m_stringMessage = tr("Port %1 close.").arg(m_stringComPort);
    CloseHandle(m_hComPort);
    m_mutex.unlock();
    m_hComPort = 0;
}
 
DWORD WorkComPort::getReceiveBytes()
{
    DWORD err = 0;
    comStat.cbInQue = 0;
    ClearCommError(m_hComPort, &err, &comStat);
    return comStat.cbInQue;
}
 
DWORD WorkComPort::readFromComPort(BYTE *inBuff, DWORD nInBytes)
{
    DWORD iBytesReaden = 0;
    ReadFile(m_hComPort, inBuff, nInBytes, &iBytesReaden, 0);
    return iBytesReaden;
}
 
void WorkComPort::run()
{
    unsigned long countBytes = 0;
    const int SIZE = 2048;
    unsigned char data[SIZE];
 
    while (1)
    {
        msleep(1);
        m_mutex.lock();
        countBytes = getReceiveBytes();
        m_mutex.unlock();
 
        if (countBytes > 0)
        {
            unsigned long readCountBytes = 0;
            readCountBytes = readFromComPort(data, countBytes);
            data[readCountBytes] = '\0';
 
            arrayFromComPort(data, readCountBytes);
        }
    }
}
 
void WorkComPort::arrayFromComPort(const unsigned char *buf, const int size)
{
    QByteArray bArr;
 
    for (int index = 0; index < size; index++)
        bArr[index] = buf[index];
 
    emit send_data(bArr);
}
 
void WorkComPort::writeToComPort(unsigned char code)
{
    DWORD iBytesWritten = 0;
    DWORD iBytesWrite = 1;
    BYTE buf[1];
 
    buf[0] = code;
 
    WriteFile(m_hComPort, buf, iBytesWrite, &iBytesWritten, NULL);
}
 
void WorkComPort::writeToComPort(QString &string)
{
    DWORD iBytesWritten = 0;
 
    QByteArray data = QByteArray::fromHex(string.toAscii());
 
    WriteFile(m_hComPort, data.constData(), data.size(), &iBytesWritten, NULL);
}


Сканируем в лоб, какие есть порты в системе
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[SPOILER]//------------COM
    for (size_t idx=1; idx <256; ++idx)
    {
        QString str = (idx < 10) ? tr("COM%1").arg(idx) : tr("\\\\.\\COM%1").arg(idx);
        bool check = false;
 
        HANDLE hPort = CreateFileA(str.toStdString().c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
        if (hPort == INVALID_HANDLE_VALUE)
        {
            DWORD dwError = GetLastError();
            if (dwError == ERROR_ACCESS_DENIED)
                check = true;
        }
        else
        {
            check = true;
            CloseHandle(hPort);
        }
        if (check)
            ui->cboxCom->addItem(str);
    }
    Sleep(100);[/SPOILER]
Ну и часть кода в главном

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
comPort->setComPortSettings(setsPort->getBaudrate(),
                             setsPort->getStopBits(),
                             setsPort->getByteSize(),
                             setsPort->getParity(),
                             setsPort->getDtrState(),
                             setsPort->getRtsState());
 
    if (comPort->openComPort())
    {
        if (comPort->configComPort())
        {
            setsPort->getLogString("Set configuration.");
            ui->pbOpenPort->setDisabled(true);
            ui->pbClosePort->setEnabled(true);
        }
        else
        {
            setsPort->getLogString("Configuration failed.");
            ui->pbOpenPort->setEnabled(true);
            ui->pbClosePort->setDisabled(true);
        }
    }
Там функции из WinAPI

Добавлено через 5 минут
Все остальное в интернете есть
vadim09
6 / 6 / 1
Регистрация: 04.08.2012
Сообщений: 62
01.04.2013, 01:20  [ТС]     Работа с COM портом #3
С WinApi функциями для работы с файлами(в моем случае с портами) - разобрался. Но, как же мне управлять отдельными ножками COM-порта?
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,058
01.04.2013, 01:27     Работа с COM портом #4
Цитата Сообщение от vadim09 Посмотреть сообщение
Но, как же мне управлять отдельными ножками COM-порта?
никак, он для этого не предназначен
raxp
10140 / 6527 / 475
Регистрация: 28.12.2010
Сообщений: 21,167
Записей в блоге: 1
01.04.2013, 02:04     Работа с COM портом #5
...для RTS/DTR через EscapeComFunction()

Управлять включением и выключением светодиодов по RS-232
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
01.04.2013, 03:11     Работа с COM портом #6
Цитата Сообщение от ValeryS Посмотреть сообщение
никак, он для этого не предназначен
не надо вводить в заблуждение. Линии DTR и RTS прекрасно управляются.
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,058
01.04.2013, 04:54     Работа с COM портом #7
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
е надо вводить в заблуждение. Линии DTR и RTS прекрасно управляются
а это что весь ком порт?
это линии "подтверждения"
а для "дерганья ногами" прекрасно подходит LPT (жаль их мало осталось)
vadim09
6 / 6 / 1
Регистрация: 04.08.2012
Сообщений: 62
01.04.2013, 18:28  [ТС]     Работа с COM портом #8
Цитата Сообщение от ValeryS Посмотреть сообщение
а это что весь ком порт?
это линии "подтверждения"
а для "дерганья ногами" прекрасно подходит LPT (жаль их мало осталось)
А причем тут LPT вообще?

В итоге я так понял, что управлять отдельно ногами через WinApi всё-таки можно.

Спасибо за инфу, буду разбираться

Добавлено через 12 минут
Думаю, когда научусь работать с COM портом перейти на виртуальный COM порт с использованием микросхемы FTDI
Надеюсь, с этим трудностей никаких не будет, не так ли?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.04.2013, 18:58     Работа с COM портом
Еще ссылки по теме:

Как работать с com-портом в С++ ? C++
C++ Управление LPT портом
C++ Работа с СОМ-портом

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

Или воспользуйтесь поиском по форуму:
raxp
10140 / 6527 / 475
Регистрация: 28.12.2010
Сообщений: 21,167
Записей в блоге: 1
01.04.2013, 18:58     Работа с COM портом #9
...не будет ...разве что вам попадется конвертор не на FTDI, а на профилик-чипе с кривыми дровами, бывает.
Yandex
Объявления
01.04.2013, 18:58     Работа с COM портом
Ответ Создать тему
Опции темы

Текущее время: 16:21. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru