使用 libserialport 来实现简单的串口终端
东东 Lv4

本文主要介绍使用 libserialport 来实现简单的串口终端

如下所示, 打开程序后首先查找可用的连接串口并尝试连接, 然后开新的线程用来在终端中获取每一行输入, 发送到串口, 在主线程中不断接收的串口数据并打印

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
#include <stdio.h>
#include <libserialport.h>
#include <string.h>
#include <windows.h>
#include <pthread.h>

struct sp_port *port = NULL;
int connected = 0;

int serialport_connect(const char *port_name)
{
if(port != NULL)
{
sp_close(port);
sp_free_port(port);
port = NULL;
}

sp_get_port_by_name(port_name, &port);

int res = sp_open(port, SP_MODE_READ_WRITE);
if(res != SP_OK)
{
sp_free_port(port);
port = NULL;
return -1;
}

sp_set_baudrate(port, 115200);
sp_set_bits(port, 8);
sp_set_parity(port, SP_PARITY_NONE);
sp_set_stopbits(port, 1);
sp_set_flowcontrol(port, SP_FLOWCONTROL_NONE);

return 0;
}

/* 连接到第一个扫描到的串口 */
const int serialport_connect_to_available(void)
{
struct sp_port **port_list = NULL;
enum sp_return result = sp_list_ports(&port_list);
if (result != SP_OK) {
return -1;
}

for (int i = 0; port_list[i] != NULL; i++)
{
struct sp_port *port = port_list[i];
char *port_name = sp_get_port_name(port);

int r = serialport_connect(port_name);
if(r == 0)
{
printf("\n连接到串口 %s\n\n", port_name);

sp_free_port_list(port_list);
return 0;
}
}

sp_free_port_list(port_list);

return -1;
}

void *serial_write_task(void * arg)
{
char buf[8192];

while (1)
{
gets(buf);
int n = strlen(buf);
buf[n++] = '\r';
buf[n++] = '\n';
if(connected)
{
sp_blocking_write(port, buf, n, 1000);
}
}
}

int main(int argc, char const *argv[])
{
SetConsoleOutputCP(65001);
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleMode(hOutput, ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);

int res = serialport_connect_to_available();
if(res != 0)
printf("\n未找到串口, 请将设备插入USB口\n");
else
connected = 1;

char buf[4096];
int buf_len = sizeof(buf);

gets(buf);

pthread_t t;
pthread_create(&t, NULL, serial_write_task, NULL);

while (1)
{
if(connected == 1)
{
int n = sp_blocking_read(port, buf, buf_len, 1);
if(n < 0)
{
printf("\n串口连接断开了!\n");
connected = 0;
continue;
}
printf("%.*s", n, buf);
fflush(stdout);
}

else if(serialport_connect_to_available() == 0)
{
connected = 1;
}

Sleep(10);
}

getchar();

return 0;
}

makefile:

1
2
3
4
5
6
default:
gcc serial_terminal.c -lserialport -lpthread -lCfgmgr32 -lSetupapi -static

run:
make default
./a.exe

源文件来自于

 评论