简介
嵌入式Linux下串口编程与Linux系统下的编程没有什么区别,系统API都是一样的。嵌入式设备中串口编程是很常用的,比如会对接一些传感器模块,这些模块大多是RS232或者RS485接口,对于软件层面上来说,RS232与RS48区别不大。RS232与RS485在使用上的区别,RS232是全双工的,只能对接一个设备串口设备。RS485是半双工的总线协议,一般可以挂多个传感器设备,半双工的意思是同时只能有一个设备向串口发数据。
用到的API函数
函数 | 说明 |
---|---|
open | 打开设备,用于打开串口设备 |
fcntl | 修改设备描述符属性参数 |
isatty | 检测打开的描述符是否指向一个终端 |
tcgetattr | 用来获取串口终端参数 |
cfmakeraw | 将终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理 |
tcflush | 用于清空输入、输出缓冲区 |
tcsetattr | 设置串口终端参数 |
read | 读取数据 |
write | 写数据 |
close | 关闭串口设备 |
代码
1#include
2#include "uart.h"
3
4/*************************************** 5*name : open_port 6*功能描述: 打开串口 7*入口参数: 串口号 8*返 回 值: 成功返回文件描述符,失败返回负值 9*作 者: 10*修改时间: 11***************************************/
12int open_port(const char * com_port) 13{
14 int fd;
15
16 if( com_port == NULL ){
17 printf("the port name is null\n");
18 return -1;
19 }
20 /*open port*/
21 fd = open(com_port, O_RDWR | O_NOCTTY | O_NDELAY);
22 if(fd 0){
23 fd = open(com_port, O_RDWR | O_NOCTTY | O_NDELAY);
24 if(fd 0){
25 perror("open serial port");
26 return -1;
27 }
28 }
29 printf("open %s OK!\n", com_port);
30 if(fcntl(fd, F_SETFL,0) 0){
31 perror("fcntl F_SETFL");
32 }
33
34 if(isatty(fd) == 0){
35 perror("isatty is not a terminal device");
36 }
37 return fd;
38}
39
40/****************************** 41*name : set_port 42*功能描述: 设置串口参数 43*入口参数: fd 文件描述符, baud_rate 波特率, data_bits 数据位, 44* parity 奇偶校验, stop_bits 停止位 45* 调用示例: set_port(fd, 115200, 8, 'N',1); 46*返 回 值: 成功返回0,失败返回-1 47*作 者: 48*修改: 49******************************/
50int set_port(int fd, int baud_rate, 51 int data_bits, char parity, int stop_bits) 52{
53 struct termios new_cfg, old_cfg;
54 int speed_arry[]= {B2400, B4800, B9600, B19200, B38400,B57600, B115200};
55 int speed[]={2400,4800,9600,19200,38400,57600,115200};
56 int i = 0;
57
58 /*save and test the serial port*/
59 if(tcgetattr(fd, &old_cfg) 0){
60 perror("tcgetattr");
61 return -1;
62 }
63
64 if(fcntl(fd,F_SETFL,0) 0)//恢复为阻塞模式
65 {
66 perror("fcntl(CzjFd,F_SETFL,0)!");
67 }
68
69 new_cfg = old_cfg;
70 cfmakeraw(&new_cfg); //配置为原来配置
71 new_cfg.c_cflag &= ~ CSIZE; //用数据位掩码清空数据位的设置
72
73 /*set baud_rate*/
74 for(i = sizeof(speed_arry) / sizeof(speed_arry[0]); i > 0; i--)
75 {
76 if(baud_rate == speed[i]){
77 cfsetispeed(&new_cfg,speed_arry[i]);
78 cfsetospeed(&new_cfg,speed_arry[i]);
79 }
80 }
81
82 switch(data_bits) /*设置数据位*/
83 {
84 case 7:
85 new_cfg.c_cflag |= CS7;
86 break;
87
88 default:
89 case 8:
90 new_cfg.c_cflag |= CS8;
91 break;
92 }
93
94 switch(parity)
95 {
96 default:
97 case 'N':
98 case 'n':
99 {
100 new_cfg.c_cflag &= ~PARENB; //清除校验位
101 new_cfg.c_iflag &= ~(ICRNL|INPCK|IXON|IXOFF); //关闭奇偶校验 关闭软件流控
102
103 break;
104 }
105
106 case 'o':
107 case 'O':
108 {
109 new_cfg.c_cflag |= (PARODD | PARENB); //使用奇校验不是用偶校验
110 new_cfg.c_iflag |= INPCK;
111 break;
112 }
113
114 case 'e':
115 case 'E':
116 {
117 new_cfg.c_cflag |= PARENB;
118 new_cfg.c_cflag &= ~PARODD; //使用偶校验
119 new_cfg.c_iflag |= INPCK;
120 break;
121 }
122
123 case 's':
124 case 'S':
125 {
126 new_cfg.c_cflag &= ~PARENB;
127 new_cfg.c_cflag &= ~CSTOPB;
128 break;
129 }
130 }
131
132 new_cfg.c_iflag &= ~(ICRNL| IXON | IXOFF ); //关闭奇偶校验 关闭软件流控
133 new_cfg.c_oflag &= ~OPOST;
134
135 switch(stop_bits)
136 {
137 default:
138 case 1:
139 {
140 new_cfg.c_cflag &= ~CSTOPB;
141 new_cfg.c_cflag &= ~CRTSCTS; //禁用硬件流控
142 //new_cfg.c_cflag |= CRTSCTS; //启用硬件流控
143 break;
144 }
145 case 2:
146 {
147 new_cfg.c_cflag |= CSTOPB;
148 break;
149 }
150 }
151
152 /*set wait time*/
153 new_cfg.c_cc[VTIME] = 0;
154 new_cfg.c_cc[VMIN] = 1;
155
156 tcflush(fd, TCIFLUSH); //处理未接收字符
157 if((tcsetattr(fd, TCSANOW, &new_cfg)) 0)
158 {
159 perror("tcsetattr");
160 return -1;
161 }
162
163 return 0;
164}
调用测试代码:
1#include "uart.h"
2#include
3#include
4
5
6int main() 7{
8 int fd = open_port("/dev/ttyS1");
9 if ( fd 0 )
10 {
11 perror("open port");
12 return -1;
13 }
14
15 set_port(fd, 115200, 8, 'N',1);
16
17 char readBuf[32] ={0};
18 const char *pstr="hello world";
19 write(fd, pstr, strlen(pstr)+1);
20
21 read(fd, readBuf, sizeof(readBuf));
22
23 close(fd);
24}
微信公众号:
![29d66f84-491f-eb11-8da9-e4434bdf6706.png](http://p03.5ceimg.com/content/29d66f84-491f-eb11-8da9-e4434bdf6706.png)