我是靠谱客的博主 微笑钢笔,这篇文章主要介绍Linux 串口读取,现在分享给大家,希望可以做个参考。

复制代码
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
#include <stdlib.h> #include <fcntl.h> #include "stdio.h" #include "termios.h" #include "unistd.h" #include "limits.h" #include <stdint.h> #include "time.h" //=================== #include <sys/select.h> #include <sys/time.h> //=================== #define UART_DEV "/dev/ttyUSB0" //根据电脑插入的串口号定义 void main() { int fd =0; int RxLen=0; uint8_t RxBuff[1024]={0}; //==========串口打开============// fd = open(UART_DEV ,O_RDWR|O_NOCTTY); if(fd<0){ printf("COM (%s) Open Fail ! n",UART_DEV); //必须要权限. return; } printf("COM (%s) Open Success ! Watting recv...nn",UART_DEV); //==========配置串口============// struct termios opt; //配置串口的属性定义在结构体struct termios中 tcgetattr(fd, & opt); //获取终端控制属性 cfsetispeed(& opt, B115200); //指定输入波特率(若不设置系统默认9600bps) cfsetospeed(& opt, B115200); //指定输出波特率(若不设置系统默认9600bps) /* c_lflag 本地模式 */ opt.c_cflag &= ~ INPCK; //不启用输入奇偶检测 opt.c_cflag |= (CLOCAL | CREAD); //CLOCAL忽略 modem 控制线,CREAD打开接受者 /* c_lflag 本地模式 */ opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //ICANON启用标准模式;ECHO回显输入字符;ECHOE如果同时设置了 ICANON,字符 ERASE 擦除前一个输入字符,WERASE 擦除前一个词;ISIG当接受到字符 INTR, QUIT, SUSP, 或 DSUSP 时,产生相应的信号 /* c_oflag 输出模式 */ opt.c_oflag &= ~ OPOST; //OPOST启用具体实现自行定义的输出处理 opt.c_oflag &= ~(ONLCR | OCRNL); //ONLCR将输出中的新行符映射为回车-换行,OCRNL将输出中的回车映射为新行符 /* c_iflag 输入模式 */ opt.c_iflag &= ~(ICRNL | INLCR); //ICRNL将输入中的回车翻译为新行 (除非设置了 IGNCR),INLCR将输入中的 NL 翻译为 CR opt.c_iflag &= ~(IXON | IXOFF | IXANY); //IXON启用输出的 XON/XOFF流控制,IXOFF启用输入的 XON/XOFF流控制,IXANY(不属于 POSIX.1;XSI) 允许任何字符来重新开始输出 /* c_cflag 控制模式 */ opt.c_cflag &= ~ CSIZE; //字符长度掩码,取值为 CS5, CS6, CS7, 或 CS8,加~就是无 opt.c_cflag |= CS8; //数据宽度是8bit opt.c_cflag &= ~ CSTOPB; //CSTOPB设置两个停止位,而不是一个,加~就是设置一个停止位 opt.c_cflag &= ~ PARENB; //PARENB允许输出产生奇偶信息以及输入的奇偶校验,加~就是无校验 /* c_cc[NCCS] 控制字符 */ opt.c_cc[VTIME] = 0 ; //等待数据时间(10秒的倍数),每个单位是0.1秒 若20就是2秒 opt.c_cc[VMIN] = 0 ; //最少可读数据,非规范模式读取时的最小字符数,设为0则为非阻塞,如果设为其它值则阻塞,直到读到到对应的数据,就像一个阀值一样,比如设为8,如果只接收到3个数据,那么它是不会返回的,只有凑齐8个数据后一齐才READ返回,阻塞在那儿 /* new_cfg.c_cc[VMIN] = 8;//DATA_LEN; new_cfg.c_cc[VTIME] = 20;//每个单位是0.1秒 20就是2秒 如果这样设置,就完全阻塞了,只有串口收到至少8个数据才会对READ立即返回,或才少于8个数据时,超时2秒也会有返回 另外特别注意的是当设置VTIME后,如果read第三个参数小于VMIN ,将会将VMIN 修改为read的第三个参数*/ /*TCIFLUSH 刷清输入队列 TCOFLUSH 刷清输出队列 TCIOFLUSH 刷清输入、输出队列*/ tcflush(fd, TCIOFLUSH); //刷串口清缓存 tcsetattr(fd, TCSANOW, &opt); //设置终端控制属性,TCSANOW:不等数据传输完毕就立即改变属性 while(1) { //==========串口接收(字符串)============// while( ((RxLen = read(fd, RxBuff,sizeof(RxBuff))) > 0) ) { RxBuff[RxLen] = 0; printf( "%s",RxBuff); } } }

复制代码
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
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <fcntl.h> #include <termios.h> #include <unistd.h> /** * @brief set_baudrate 设置波特率 * @param opt * @param baudrate */ static void set_baudrate (struct termios *opt, unsigned int baudrate) { cfsetispeed(opt, baudrate); cfsetospeed(opt, baudrate); } /** * @brief set_data_bit 设置数据位 * @param opt * @param databit */ static void set_data_bit (struct termios *opt, unsigned int databit) { opt->c_cflag &= ~CSIZE; switch (databit) { case 8: opt->c_cflag |= CS8; break; case 7: opt->c_cflag |= CS7; break; case 6: opt->c_cflag |= CS6; break; case 5: opt->c_cflag |= CS5; break; default: opt->c_cflag |= CS8; break; } } /** * @brief set_parity 设置奇偶校验位 * @param opt * @param parity */ static void set_parity (struct termios *opt, char parity) { switch (parity) { case 'N': /* no parity check */ opt->c_cflag &= ~PARENB; break; case 'E': /* even */ opt->c_cflag |= PARENB; opt->c_cflag &= ~PARODD; break; case 'O': /* odd */ opt->c_cflag |= PARENB; opt->c_cflag |= ~PARODD; break; default: /* no parity check */ opt->c_cflag &= ~PARENB; break; } } /** * @brief set_stopbit 设置停止位 * @param opt * @param stopbit */ static void set_stopbit (struct termios *opt, const char *stopbit) { if (0 == strcmp (stopbit, "1")) { opt->c_cflag &= ~CSTOPB; /* 1 stop bit */ } else if (0 == strcmp (stopbit, "1")) { opt->c_cflag &= ~CSTOPB; /* 1.5 stop bit */ } else if (0 == strcmp (stopbit, "2")) { opt->c_cflag |= CSTOPB; /* 2 stop bits */ } else { opt->c_cflag &= ~CSTOPB; /* 1 stop bit */ } } int set_port_attr ( int fd, int baudrate, // B1200 B2400 B4800 B9600 .. B115200 int databit, // 5, 6, 7, 8 const char *stopbit, // "1", "1.5", "2" char parity, // N(o), O(dd), E(ven) int vtime, int vmin ) { struct termios opt; tcgetattr(fd, &opt); //设置波特率 set_baudrate(&opt, baudrate); opt.c_cflag |= CLOCAL | CREAD; /* | CRTSCTS */ //设置数据位 set_data_bit(&opt, databit); //设置校验位 set_parity(&opt, parity); //设置停止位 set_stopbit(&opt, stopbit); //其它设置 opt.c_oflag = 0; opt.c_lflag |= 0; opt.c_oflag &= ~OPOST; opt.c_cc[VTIME] = vtime; opt.c_cc[VMIN] = vmin; tcflush (fd, TCIFLUSH); return (tcsetattr (fd, TCSANOW, &opt)); } int main(int argc, char **argv) { printf("=========BuildTime:[%s %s]============n",__DATE__,__TIME__ ); //通过指令 ls /dev/* 查看电脑硬件设备 //一般 ttyS0 等价于Windows的COM1 ,以此类推 //可用MobaXterm软件在Windows下运行linux程序 char *devPath = "/dev/ttyS25"; int fd = open(devPath ,O_RDWR); long baud = 115200; if(fd < 0){ printf("[ERROR] uart [%s] open file failed .", devPath ); return -1; } set_port_attr(fd,baud,8,"N",'1',0,0); printf("uart [%s] open sucess,baud=%d bps.n",devPath , baud ); char buf[1024*5] = {0}; int max_size = sizeof(buf); int len = 0; while(1) //Ctrl+C 结束终端 { memset(buf,0,max_size); len = read(fd, buf,max_size); if(len<=0) { usleep(1000); continue; } printf("Length:%d,Text:%srn",len,buf); //printf("%s",buf); } close( fd ); printf("Quit main program.n"); }

最后

以上就是微笑钢笔最近收集整理的关于Linux 串口读取的全部内容,更多相关Linux内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(85)

评论列表共有 0 条评论

立即
投稿
返回
顶部