Demo功能
在学习Linux的串口通信程序之前,我们先来看看Demo的效果,这样比先来一大堆串口知识介绍更加有学习动力,毕竟是能运行的。本文章不会讲解串口的原理,如何接线等,只会讲解在Linux(Android)下如何使用串口。
程序的功能是发送4个8bit的数据,然后serial_comm不断接受数据并且回传会串口,从下图可以看出,程序正常运行。
这里的数据格式是以非标准(Raw)的格式进行传输,即以16进制进行传输,末尾不会发送回车符。这种方式普遍用在两个嵌入式IC之间的通信,而标准格式,则需要在末尾加回车符,数据才能读到。
这里推荐大家使用AccessPort这个软件(免费的),下载地址:http://www.sudt.com,能收发非标准模式,以及标准模式。而另一款SecureCRT软件只能收发标准模式,所以我调试非标准模式时一般都用这个软件。其实选择这个软件的原因嘛,仅仅是界面比较好看,哈哈。
串口配置
一般串口配置有:1、串口号。2、波特率。3、校验位。4、数据位。5、停止位。只要配置这些信息,我们就可以使用Window串口进行调试,而Linux的串口也是类似,代码中也是类似的操作。
Linux一切设备都是文件,串口设备的访问就是访问/dev/ttyS*,我们用ls -l /dev/ttyS*查看当前系统注册的设备,并确认其 运行权限,看是否可读可写。这里也是需要注意的地方,不然调试半天,才发现是没权限访问,那就尴尬了。从下面看出当前系统有3个串口设备其中ttyS0是debug打印log的串口,ttyS1是蓝牙用的串口,ttyS3才是没人使用的串口。ttyS3怎么产生,请查看之前的文章:https://blog.csdn.net/sweetmilkcake/article/details/82749764
petrel-p1:/ # ls -l /dev/ttyS*
crw------- 1 root root 252, 0 2018-01-01 08:00 /dev/ttyS0
crw-rw---- 1 bluetooth net_bt_stack 252, 1 2018-01-01 08:01 /dev/ttyS1
crw------- 1 root root 252, 3 2018-01-01 08:06 /dev/ttyS3
查看串口是否被占用
之前调过一个Bug,就是我的程序无论怎么都接受不到正常数据,甚至进行自己收发回环测试都不行(回环测试,串口端的TX和RX互联,自己进行收发处理,这样可以快捷测试串口的状态),当时也是搞了好久,一度怀疑是硬件问题,最后才发现是有另外一个程序一直访问同一个串口设备,不断的进行读写(它启动的早),导致我的数据不能正常输出,后面直接把它kill掉就好了,当然这是快捷的方法,最终修改还是要两个程序进行协调。那么问题来了,如果你刚接手别人的项目,对别人的系统又不熟悉,那么怎么确保自己使用的串口没有问题呢?其实还是有方法的,我们可以使用lsof | grep ttyS查看串口设备的占用情况。就像下面例子一样,我把serial_comm放到后台运行,所以看到它在占用着我们的ttyS3。用这种方法就可以很快进行问题定位。
petrel-p1:/ # lsof | grep ttyS
droid.blu 3044 bluetooth 74u CHR 252,1 0t0 4227 /dev/ttyS1
petrel-p1:/ # serial_comm &
[1] 19274
petrel-p1:/ # serial test start.
petrel-p1:/ # lsof | grep ttyS
droid.blu 3044 bluetooth 74u CHR 252,1 0t0 4227 /dev/ttyS1
serial_co 19274 root 3u CHR 252,3 0t0 4228 /dev/ttyS3
详细配置代码
// dev control date end
// 02 01 12 7F
#define SERIAL_REC_NUM 4
// VTIME and VMIN is very important.
// VTIME: Time to wait for data (tenths of seconds)
#define SERIAL_VTIME 1
// VMIN: Minimum number of characters to read
#define SERIAL_VMIN SERIAL_REC_NUM
int serial_set(int fd, int speed, int bits, int event, int stop)
{
struct termios ttys;
memset(&ttys, 0, sizeof(ttys));
// Enable the receiver and set local mode
// CLOCAL: Local line - do not change "owner" of port
// CREAD: Enable receiver
ttys.c_cflag |= (CLOCAL | CREAD);
// Mask the character size bits
// CSIZE: Bit mask for data bits
ttys