例子

下面是一个简单的读取串口数据的例子,使用了上面定义的一些函数和头文件

/**********************************************************************

*代码说明:使用串口二测试的,发送的数据是字符,但是没有发送字符串结束符号,

*所以接收到后,后面加上了结束符号。我测试使用的是单片机发送数据到第二个串口,测试通过。

**********************************************************************/

#defineFALSE  -1

#defineTRUE   0

/*********************************************************************/

intOpenDev(char*Dev)

{

//Dev就是设备,设备就是文件,就是给出该设备文件的路径

intfd =open(Dev, O_RDWR );//| O_NOCTTY | O_NDELAY

if(-1 == fd)

{

perror("Can't Open Serial Port");

return-1;

}

else

returnfd;

}

intmain(intargc,char**argv)

{

intfd;

intnread;

charbuff[512];

char*dev ="/dev/ttyS1";//串口二

fd = OpenDev(dev);

set_speed(fd, 19200);

if(set_Parity(fd, 8, 1,'N') == FALSE)

{

printf("Set Parity Error\n");

exit(0);

}

while(1)//循环读取数据

{

while((nread =read(fd, buff, 512))>0)

{

printf("\nLen %d\n", nread);

buff[nread+1] ='\0';

printf("\n%s", buff);

}

}

//close(fd);

// exit (0);

}

1、虚拟机下使用串口的方法使用vmwave,默认串口设备是没有添加的,通过vmwave将设备加入即可正常使用串口。虚拟机串口打开后,可能会占用windows下的串口。另外,虚拟机的串口收发比正常的速度的确要慢许多。

2、消除Linux串口收发的一些规则

Linux串口收发有许多模式,如:

(1)接收返回模式:如果串口没有接收到数据,read()函数不返回。

(2)数据接收\n才返回接收的数据,否则read()函数返回0

(3)特殊字符解析问题,部分特殊字符接收/发送时,会被屏蔽或者转义。如发送0x0A接收变为0x0A 0x0A,0x0D被屏蔽等。

(4)接收反馈:如串口接收到数据,立即将该数据发送出去。

(上面是我遇到的一些问题,可能表述不很清楚,呵呵。如果用于收发txt文件,一般不大注意。)

3、解决问题的方法是,消除这些默认规则,关键是struct termios的参数影响。

structtermios  {

tcflag_tc_iflag;/**//*输入模式旗标*/

tcflag_tc_oflag;/**//*输出模式旗标*/

tcflag_tc_cflag;/**//*控制模式旗标*/

tcflag_tc_lflag;/**//*区域模式旗标*/

cc_tc_line;/**//*行控制(line discipline) */

cc_tc_cc[NCCS];/**//*控制特性*/

};

由于研究不深,如果要消除所有上面的规则,我是如下处理的

struct termios options;

串口打开方式:

open ("dev/ttyS0", O_RDWR|O_NOCTTY| O_NDELAY );

消除收发模式规则:

options.c_lflag        = 0;

options.c_oflag        = 0;

options.c_iflag        = 0;

消除字符屏蔽规则:

options.c_cc[VINTR]    = 0;/**//* Ctrl-c */

options.c_cc[VQUIT]     = 0;/**//* Ctrl- */

options.c_cc[VERASE]    = 0;/**//* del */

options.c_cc[VKILL]    = 0;/**//* @ */

options.c_cc[VEOF]     = 0;/**//* Ctrl-d */

options.c_cc[VTIME]    = 1;/**//*  */

options.c_cc[VMIN]     = 0;/**//*  */

options.c_cc[VSWTC]    = 0;/**//* '' */

options.c_cc[VSTART]   = 0;/**//* Ctrl-q */

options.c_cc[VSTOP]    = 0;/**//* Ctrl-s */

options.c_cc[VSUSP]    = 0;/**//* Ctrl-z */

options.c_cc[VEOL]     = 0;/**//* '' */

options.c_cc[VREPRINT] = 0;/**//* Ctrl-r */

options.c_cc[VDISCARD] = 0;/**//* Ctrl-u */

options.c_cc[VWERASE]  = 0;/**//* Ctrl-w */

options.c_cc[VLNEXT]   = 0;/**//* Ctrl-v */

options.c_cc[VEOL2]    = 0;/**//* '' */

以上设置,在其它参数串口设置前执行,如果你需要保留部分参数,请参阅http://blog.chinaunix.net/article.php?articleId=15964&blogId=60在RedHat Feroda 4下编译通过

= = = = = = = = = = =非阻塞read= = = = = = = = = = =

Q:在调用串口read(fd,   buff,   len);时,如果串口没有数据,会停在read处,请问有没有办法让这个read动作中止?

A:使用非阻塞方式select函数(I/O多工机制)或者open的时候加O_NONBLOCK参数。

intselect(intn,fd_set * readfds,fd_set *writefds,fd_set * exceptfds,structtimeval * timeout);关于这个函数的使用我会在下篇blog中整理。

= = = = = = = = = = =串口收发源码= = = = = = = = = = =

一下代码已经经过我测试,没有问题。开发环境Redhat9,运行环境s3c2410

= = = = = = receive.c= = = = = =

#include

#include

#include

#include

#include

#include

#include

#include

#include

#defineTRUE 1

//初始化串口选项:

voidsetTermios(structtermios * pNewtio,intuBaudRate)

{

bzero(pNewtio,sizeof(structtermios));/* clear struct for new port settings */

//8N1

pNewtio->c_cflag = uBaudRate | CS8 | CREAD | CLOCAL;

pNewtio->c_iflag = IGNPAR;

pNewtio->c_oflag = 0;

pNewtio->c_lflag = 0;//non ICANON

/*

initialize all control characters

default values can be found in /usr/include/termios.h, and

are given in the comments, but we don't need them here

*/

pNewtio->c_cc[VINTR] = 0;/* Ctrl-c */

pNewtio->c_cc[VQUIT] = 0;/* Ctrl-\ */

pNewtio->c_cc[VERASE] = 0;/* del */

pNewtio->c_cc[VKILL] = 0;/* @ */

pNewtio->c_cc[VEOF] = 4;/* Ctrl-d */

pNewtio->c_cc[VTIME] = 5;/* inter-character timer, timeout VTIME*0.1 */

pNewtio->c_cc[VMIN] = 0;/* blocking read until VMIN character arrives */

pNewtio->c_cc[VSWTC] = 0;/* '\0' */

pNewtio->c_cc[VSTART] = 0;/* Ctrl-q */

pNewtio->c_cc[VSTOP] = 0;/* Ctrl-s */

pNewtio->c_cc[VSUSP] = 0;/* Ctrl-z */

pNewtio->c_cc[VEOL] = 0;/* '\0' */

pNewtio->c_cc[VREPRINT] = 0;/* Ctrl-r */

pNewtio->c_cc[VDISCARD] = 0;/* Ctrl-u */

pNewtio->c_cc[VWERASE] = 0;/* Ctrl-w */

pNewtio->c_cc[VLNEXT] = 0;/* Ctrl-v */

pNewtio->c_cc[VEOL2] = 0;/* '\0' */

}

#defineBUFSIZE 512

intmain(intargc,char**argv)

{

intfd;

intnread;

charbuff[BUFSIZE];

structtermios oldtio, newtio;

structtimeval tv;

char*dev ="/dev/ttyS1";

fd_set rfds;

if((fd =open(dev, O_RDWR | O_NOCTTY))<0)

{

printf("err: can't open serial port!\n");

return-1;

}

tcgetattr(fd, &oldtio);/* save current serial port settings */

setTermios(&newtio, B115200);

tcflush(fd, TCIFLUSH);

tcsetattr(fd, TCSANOW, &newtio);

tv.tv_sec=30;

tv.tv_usec=0;

while(TRUE)

{

printf("wait...\n");

FD_ZERO(&rfds);

FD_SET(fd, &rfds);

if(select(1+fd, &rfds, NULL, NULL, &tv)>0)

{

if(FD_ISSET(fd, &rfds))

{

nread=read(fd, buff, BUFSIZE);

printf("readlength=%d\n", nread);

buff[nread]='\0';

printf("%s\n", buff);

}

}

}

tcsetattr(fd, TCSANOW, &oldtio);

close(fd);

}

= = = = = send.c= = = = = =

#include

#include

#include

#include

#include

#include

#include

#include

#include

//初始化串口选项:

voidsetTermios(structtermios * pNewtio,intuBaudRate)

{

bzero(pNewtio,sizeof(structtermios));/* clear struct for new port settings */

//8N1

pNewtio->c_cflag = uBaudRate | CS8 | CREAD | CLOCAL;

pNewtio->c_iflag = IGNPAR;

pNewtio->c_oflag = 0;

pNewtio->c_lflag = 0;//non ICANON

/*

initialize all control characters

default values can be found in /usr/include/termios.h, and

are given in the comments, but we don't need them here

*/

pNewtio->c_cc[VINTR] = 0;/* Ctrl-c */

pNewtio->c_cc[VQUIT] = 0;/* Ctrl-\ */

pNewtio->c_cc[VERASE] = 0;/* del */

pNewtio->c_cc[VKILL] = 0;/* @ */

pNewtio->c_cc[VEOF] = 4;/* Ctrl-d */

pNewtio->c_cc[VTIME] = 5;/* inter-character timer, timeout VTIME*0.1 */

pNewtio->c_cc[VMIN] = 0;/* blocking read until VMIN character arrives */

pNewtio->c_cc[VSWTC] = 0;/* '\0' */

pNewtio->c_cc[VSTART] = 0;/* Ctrl-q */

pNewtio->c_cc[VSTOP] = 0;/* Ctrl-s */

pNewtio->c_cc[VSUSP] = 0;/* Ctrl-z */

pNewtio->c_cc[VEOL] = 0;/* '\0' */

pNewtio->c_cc[VREPRINT] = 0;/* Ctrl-r */

pNewtio->c_cc[VDISCARD] = 0;/* Ctrl-u */

pNewtio->c_cc[VWERASE] = 0;/* Ctrl-w */

pNewtio->c_cc[VLNEXT] = 0;/* Ctrl-v */

pNewtio->c_cc[VEOL2] = 0;/* '\0' */

}

intmain(intargc,char**argv)

{

intfd;

intnCount, nTotal, i;

structtermios oldtio, newtio;

char*dev ="/dev/ttyS1";

if((argc!=3) || (sscanf(argv[1],"%d", &nTotal) != 1))

{

printf("err: need tow arg!\n");

return-1;

}

if((fd =open(dev, O_RDWR | O_NOCTTY))<0)

{

printf("err: can't open serial port!\n");

return-1;

}

tcgetattr(fd, &oldtio);/* save current serial port settings */

setTermios(&newtio, B115200);

tcflush(fd, TCIFLUSH);

tcsetattr(fd, TCSANOW, &newtio);

for(i=0; i

{

nCount=write(fd, argv[2],strlen(argv[2]));

printf("send data\n");

sleep(1);

}

tcsetattr(fd, TCSANOW, &oldtio);

close(fd);

return0;

}

= = = = = =.makefile= = = = = =

CC = /usr/local/arm/2.95.3/bin/arm-linux-gcc

all:receive send

receive: receive.c

$(CC)receive.c -o  receive

send: send.c

$(CC)send.c -o  send

clean:

-rm -rf testCOM receive send

到此基本就结束了,可能代码注释比较少些,写的太着急了,等有时间整理一下。最好再看看上一篇blog这样能更好的理解串口。

linux通过串口读取文件,Linux 串口读写(二)相关推荐

  1. jy61 树莓派_用Linux树莓派来读取JY61的串口数据

    简述 有很多的小伙伴说用Linux树莓派来读取JY61的串口数据不知道怎么操作.今天我和大家分享下我是从三个方面分享的.1.JY61和树莓派的连接方式及VNC的使用:2.下载到树莓派的程序是如何编写的 ...

  2. Linux shell逐行读取文件的方法

    Linux shell逐行读取文件的方法 来源:互联网  在linux中有很多方法逐行读取一个文件的方法,其中最常用的就是下面的脚本里的方法,而且是效率最高,使用最多的方法.为了给大家一个直观的感受, ...

  3. linux重命名乱码文件,Linux中重命名乱码文件

    Linux下,如何将一个乱码的文件进行重命名 方法一: 命令格式:mv $(ls |egrep "[^a-zA-Z0-9.-]") tandao.tx [root@nb o]# l ...

  4. Linux C try 头文件,linux c 头文件

    //1.Linux中一些头文件的作用: #include //ANSI C.提供断言,assert(表达式) #include //GCC.GTK,GNOME的基础库,提供很多有用的函数,如有数据结构 ...

  5. Linux shell逐行读取文件的方法-比较

    From: http://www.embeddedlinux.org.cn/html/jishuzixun/201211/19-2387.html 在linux中有很多方法逐行读取一个文件的方法,其中 ...

  6. linux删除、读取文件原理

    linux删除文件原理 LINUX的文件名是存在父目录的block里面,并指向这个文件额inode节点,这个文件的inode节点再标记指向存放这个文件的block的数据块.我们删除一个文件,实际上并不 ...

  7. 从Java中的串口读取文件

    我是java技术的初学者,我必须从端口读取文件. 首先,我将"FLASH"写入输出流然后我将从目标设备获得响应作为"FLASH_OK",在获得FLASH_OK作 ...

  8. linux 内存block读取6,Linux硬盘 和文件系统维护

    1. 分区 MBR(Master Boot Recorder)主引导分区仅提供最多4个分区,主分区(Primary,P)与扩展分区(Extended,E),如3P+1E,扩展分区最多只好 有1个. 2 ...

  9. linux shell读取文件,Linux shell逐行读取文件的方法

    方法1:while循环中执行效率最高,最常用的方法. function while_read_LINE_bottm(){ While read LINE do echo $LINE done } 注释 ...

最新文章

  1. python运维实战--跨堡垒机连接二级服务器上传文件
  2. 网络yum源 自定义yum仓库 zip备份 编译安装
  3. Oracle学习:数据的插入、修改和删除
  4. js防止表单重复提交
  5. jenkins搭建_自动化测试系列之jenkins配置搭建环境
  6. HTML+CSS+JS实现 ❤️贪吃蛇游戏、你能吃过我?❤️【源码送给你一起来玩-建议收藏】
  7. 回调机制在 Android 监听用户界面操作中的体现
  8. mysql中datediff跨年的用法_Mysql 函数使用记录(一)——DATEDIFF、CONCAT
  9. 云服务器更换系统后tomcat,如何对云服务器装tomcat
  10. Thymeleaf本页面通过controller跳转到本页面的坑
  11. ext--fileset控件示例
  12. 由级别和性格特征将程序员分类 ---看看你属于哪一种
  13. python 编程 安卓脚本_详解基于Android的Appium+Python自动化脚本编写
  14. markdown笔记1--设置字体、颜色、图片、背景色
  15. RationalDMIS 2020 手动特征测量注意事项
  16. matlab中工作空间的作用,MATLAB的工作空间
  17. 计算机网络中的OSI模型和TCP/IP模型
  18. 将vue-admin-template组件默认英文语言改成中文
  19. Android开发:手机震动工具类
  20. 微信5.0即将横“扫”一切

热门文章

  1. 实例讲解决策树分类器
  2. 干货|了解机器学习常用数据预处理
  3. 线性判别分析(LDA)原理总结
  4. 基于转移学习的图像识别
  5. Factory-pattern 三种工厂模式
  6. 【最短路】 ZOJ 1544 Currency Exchange 推断负圈
  7. 玩转 iOS 开发:《iOS 设计模式 — 工厂模式》
  8. PHP CURL方法,GETPOST请求。
  9. Win7:“找不到该项目”错误解决大法
  10. windows8.1与centos7.0双系统启动项设置