前言:如果用qt写程序作为上位机,然后通过和usb和下位机通信的时候,就需要用到qt中的串口通信了。
使用qt中的串口通信的时候需要用到的两个头文件分别为:
#include
#include
除了加上面两个头文件之外,还需要在工程文件中加下面一行代码:
QT += serialport
我们一般都需要先定义一个全局的串口对象,记得在自己的头文件中添加上:
QSerialPort *serial;
到这里我们就可以调用qt串口通信中的函数了,一般来讲qt串口通信需要经过7步:
1、设置串口名(如COM1)
serial = new QSerialPort;
serial->setPortName(ui->PortBox->currentText());
这里我使用自动寻找可用串口的方法,直接自动设置了
foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
QSerialPort serial;
serial.setPort(info);
if(serial.open(QIODevice::ReadWrite))
{
ui->PortBox->addItem(serial.portName());
serial.close();
}
}
2、打开串口
serial->open(QIODevice::ReadWrite);
3、设置波特率(如115200)
serial->setBaudRate(QSerialPort::Baud115200);//设置波特率为115200
4、设置数据位(如8)
serial->setDataBits(QSerialPort::Data8);//设置数据位8
5、设置校验位(如0)
serial->setParity(QSerialPort::NoParity); //校验位设置为0
6、设置停止位(如1)
serial->setStopBits(QSerialPort::OneStop);//停止位设置为1
7、设置流控制
serial->setFlowControl(QSerialPort::NoFlowControl);//设置为无流控制
到这里串口通信的设置就完成了,下面我们需要实现对数据的发送和接收
1、连接数据接收槽函数,下位机中一有数据发送过来的时候就会响应这个槽函数
QObject::connect(serial,&QSerialPort::readyRead,this,&MainWindow::ReadData);
2、从上位机发送数据到下位机
serial->write(ui->textEdit_2->toPlainText().toLatin1());
主要使用的函数就这些了,我们来看看代码:
1、工程文件SerialPortTool.pro
1 #-------------------------------------------------
2 #
3 # Project created by QtCreator 2017-11-17T15:43:04
4 #
5 #-------------------------------------------------
6
7 QT += core gui
8 QT += serialport
9
10 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
11
12 TARGET = SerialPortTool
13 TEMPLATE = app
14
15 # The following define makes your compiler emit warnings if you use
16 # any feature of Qt which as been marked as deprecated (the exact warnings
17 # depend on your compiler). Please consult the documentation of the
18 # deprecated API in order to know how to port your code away from it.
19 DEFINES += QT_DEPRECATED_WARNINGS
20
21 # You can also make your code fail to compile if you use deprecated APIs.
22 # In order to do so, uncomment the following line.
23 # You can also select to disable deprecated APIs only up to a certain version of Qt.
24 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
25
26
27 SOURCES += \
28 main.cpp \
29 mainwindow.cpp
30
31 HEADERS += \
32 mainwindow.h
33
34 FORMS += \
35 mainwindow.ui
2、头文件mainwindow.h
1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3
4 #include
5 #include
6 #include
7 #include
8
9 namespace Ui {
10 class MainWindow;
11 }
12
13 class MainWindow : public QMainWindow
14 {
15 Q_OBJECT
16
17 public:
18 explicit MainWindow(QWidget *parent = 0);
19 ~MainWindow();
20
21 private slots:
22 void on_OpenSerialButton_clicked();
23
24 void ReadData();
25
26 void on_SendButton_clicked();
27
28 private:
29 Ui::MainWindow *ui;
30 QSerialPort *serial;
31 };
32
33 #endif // MAINWINDOW_H
3、源文件mainwindow.cpp
1 #include "mainwindow.h"
2 #include "ui_mainwindow.h"
3
4
5 MainWindow::MainWindow(QWidget *parent) :
6 QMainWindow(parent),
7 ui(new Ui::MainWindow)
8 {
9 ui->setupUi(this);
10
11 //查找可用的串口
12 foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
13 {
14 QSerialPort serial;
15 serial.setPort(info);
16 if(serial.open(QIODevice::ReadWrite))
17 {
18 ui->PortBox->addItem(serial.portName());
19 serial.close();
20 }
21 }
22 //设置波特率下拉菜单默认显示第0项
23 ui->BaudBox->setCurrentIndex(0);
24
25 }
26
27 MainWindow::~MainWindow()
28 {
29 delete ui;
30 }
31
32 void MainWindow::on_OpenSerialButton_clicked()
33 {
34 if(ui->OpenSerialButton->text() == tr("打开串口"))
35 {
36 serial = new QSerialPort;
37 //设置串口名
38 serial->setPortName(ui->PortBox->currentText());
39 //打开串口
40 serial->open(QIODevice::ReadWrite);
41 //设置波特率
42 serial->setBaudRate(QSerialPort::Baud115200);//设置波特率为115200
43 //设置数据位数
44 switch (ui->BitBox->currentIndex())
45 {
46 case 8:
47 serial->setDataBits(QSerialPort::Data8);//设置数据位8
48 break;
49 default:
50 break;
51 }
52 //设置校验位
53 switch (ui->ParityBox->currentIndex())
54 {
55 case 0:
56 serial->setParity(QSerialPort::NoParity);
57 break;
58 default:
59 break;
60 }
61 //设置停止位
62 switch (ui->BitBox->currentIndex())
63 {
64 case 1:
65 serial->setStopBits(QSerialPort::OneStop);//停止位设置为1
66 break;
67 case 2:
68 serial->setStopBits(QSerialPort::TwoStop);
69 default:
70 break;
71 }
72 //设置流控制
73 serial->setFlowControl(QSerialPort::NoFlowControl);//设置为无流控制
74
75 //关闭设置菜单使能
76 ui->PortBox->setEnabled(false);
77 ui->BaudBox->setEnabled(false);
78 ui->BitBox->setEnabled(false);
79 ui->ParityBox->setEnabled(false);
80 ui->StopBox->setEnabled(false);
81 ui->OpenSerialButton->setText(tr("关闭串口"));
82
83 //连接信号槽
84 QObject::connect(serial,&QSerialPort::readyRead,this,&MainWindow::ReadData);
85 }
86 else
87 {
88 //关闭串口
89 serial->clear();
90 serial->close();
91 serial->deleteLater();
92
93 //恢复设置使能
94 ui->PortBox->setEnabled(true);
95 ui->BaudBox->setEnabled(true);
96 ui->BitBox->setEnabled(true);
97 ui->ParityBox->setEnabled(true);
98 ui->StopBox->setEnabled(true);
99 ui->OpenSerialButton->setText(tr("打开串口"));
100
101 }
102
103
104
105
106 }
107 //读取接收到的信息
108 void MainWindow::ReadData()
109 {
110 QByteArray buf;
111 buf = serial->readAll();
112 if(!buf.isEmpty())
113 {
114 QString str = ui->textEdit->toPlainText();
115 str+=tr(buf);
116 ui->textEdit->clear();
117 ui->textEdit->append(str);
118
119 }
120 buf.clear();
121 }
122
123 //发送按钮槽函数
124 void MainWindow::on_SendButton_clicked()
125 {
126 serial->write(ui->textEdit_2->toPlainText().toLatin1());
127 }
4、界面文件mainwindow.ui
1
2
3 MainWindow
4
5
6
7 0
8 0
9 547
10 470
11
12
13
14 MainWindow
15
16
17
18
19
20 10
21 50
22 54
23 12
24
25
26
27 串口
28
29
30
31
32
33 10
34 90
35 54
36 12
37
38
39
40 波特率
41
42
43
44
45
46 10
47 130
48 54
49 12
50
51
52
53 数据位
54
55
56
57
58
59 100
60 50
61 69
62 22
63
64
65
66
67
68
69 100
70 90
71 69
72 22
73
74
75
76 0
77
78 -
79
80 9600
81
82
83 -
84
85 19200
86
87
88 -
89
90 38400
91
92
93 -
94
95 57600
96
97
98 -
99
100 115200
101
102
103
104
105
106
107 100
108 120
109 69
110 22
111
112
113
114 0
115
116 -
117
118 8
119
120
121
122
123
124
125 100
126 160
127 69
128 22
129
130
131 -
132
133 0
134
135
136
137
138
139
140 10
141 160
142 61
143 16
144
145
146
147 校验位
148
149
150
151
152
153 10
154 200
155 54
156 12
157
158
159
160 停止位
161
162
163
164
165
166 100
167 200
168 69
169 22
170
171
172 -
173
174 1
175
176
177
178
179
180
181 100
182 240
183 71
184 23
185
186
187
188 打开串口
189
190
191
192
193
194 200
195 30
196 221
197 291
198
199
200
201
202
203
204 200
205 330
206 221
207 31
208
209
210
211
212
213
214 430
215 330
216 75
217 31
218
219
220
221 发送
222
223
224
225
226
227
228 0
229 0
230 547
231 23
232
233
234
235
236
237 TopToolBarArea
238
239
240 false
241
242
243
244
245
246
247
248
效果图如下,自己设置对应下位机的波特率就可以实现数据收发了
这里注意一下,使用串口通信的时候是按字节发送的,所以如果你定义一个char buff[10],而且你想这样定义buff[0] = '255'发送255这个字符给下位机的时候,下位机是接收不完整的,经过测试发现发送大于或等于10的字符是会被截断的,只会留下最后一个字符,比如说发送10字符的时候,下位机很有可能只能接收到0这个字符,当然如果想要完整的发送过去的话可以定义成字符串形式。比如char buff[] ="255",这样就可以发送一个完整的255过去了,但是需要注意的是这是一个字符串不是一个字符,所以如果你在下位机如果要根据上位机发送的数据来处理一些事情的时候一定要清楚你发送的是字符还是字符串。