linux串口编程超详尽版

合集下载

Linux下串口通信编程

Linux下串口通信编程

Linux下串口通信编程一、什么是串口通信?串口通信是指计算机主机与外设之间以及主机系统与主机系统之间数据的串行传送。

使用串口通信时,发送和接收到的每一个字符实际上都是一次一位的传送的,每一位为1或者为0。

二、串口通信的分类串口通信可以分为同步通信和异步通信两类。

同步通信是按照软件识别同步字符来实现数据的发送和接收,异步通信是一种利用字符的再同步技术的通信方式。

2.1 同步通信同步通信是一种连续串行传送数据的通信方式,一次通信只传送一帧信息。

这里的信息帧与异步通信中的字符帧不同,通常含有若干个数据字符。

它们均由同步字符、数据字符和校验字符(CRC)组成。

其中同步字符位于帧开头,用于确认数据字符的开始。

数据字符在同步字符之后,个数没有限制,由所需传输的数据块长度来决定;校验字符有1到2个,用于接收端对接收到的字符序列进行正确性的校验。

同步通信的缺点是要求发送时钟和接收时钟保持严格的同步。

2.2 异步通信异步通信中,数据通常以字符或者字节为单位组成字符帧传送。

字符帧由发送端逐帧发送,通过传输线被接收设备逐帧接收。

发送端和接收端可以由各自的时钟来控制数据的发送和接收,这两个时钟源彼此独立,互不同步。

接收端检测到传输线上发送过来的低电平逻辑"0"(即字符帧起始位)时,确定发送端已开始发送数据,每当接收端收到字符帧中的停止位时,就知道一帧字符已经发送完毕。

在异步通行中有两个比较重要的指标:字符帧格式和波特率。

(1)字符帧,由起始位、数据位、奇偶校验位和停止位组成。

1.起始位:位于字符帧开头,占1位,始终为逻辑0电平,用于向接收设备表示发送端开始发送一帧信息。

2.数据位:紧跟在起始位之后,可以设置为5位、6位、7位、8位,低位在前高位在后。

3.奇偶校验位:位于数据位之后,仅占一位,用于表示串行通信中采用奇校验还是偶校验。

(2)波特率,波特率是每秒钟传送二进制数码的位数,单位是b/s。

异步通信的优点是不需要传送同步脉冲,字符帧长度也不受到限制。

linux串口编程参数配置详解

linux串口编程参数配置详解

linux串口编程参数配置详解1.linux串口编程需要的头文件#include <stdio.h> //标准输入输出定义#include <stdlib.h> //标准函数库定义#include <unistd.h> //Unix标准函数定义#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h> //文件控制定义#include <termios.h> //POSIX中断控制定义#include <errno.h> //错误号定义2.打开串口串口位于/dev中,可作为标准文件的形式打开,其中:串口1 /dev/ttyS0串口2 /dev/ttyS1代码如下:int fd;fd = open(“/dev/ttyS0”, O_RDWR);if(fd == -1){Perror(“串口1打开失败!”);}//else//fcntl(fd, F_SETFL, FNDELAY);除了使用O_RDWR标志之外,通常还会使用O_NOCTTY和O_NDELAY这两个标志。

O_NOCTTY:告诉Unix这个程序不想成为“控制终端”控制的程序,不说明这个标志的话,任何输入都会影响你的程序。

O_NDELAY:告诉Unix这个程序不关心DCD信号线状态,即其他端口是否运行,不说明这个标志的话,该程序就会在DCD信号线为低电平时停止。

3.设置波特率最基本的串口设置包括波特率、校验位和停止位设置,且串口设置主要使用termios.h头文件中定义的termios结构,如下:struct termios{tcflag_t c_iflag; //输入模式标志tcflag_t c_oflag; //输出模式标志tcflag_t c_cflag; //控制模式标志tcflag_t c_lflag; //本地模式标志cc_t c_line; //line disciplinecc_t c_cc[NCC]; //control characters}代码如下:int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300, B384 00, B19200, B9600, B4800, B2400, B1200, B300, };int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9 600, 4800, 2400, 1200, 300, };void SetSpeed(int fd, int speed){int i;struct termios Opt; //定义termios结构if(tcgetattr(fd, &Opt) != 0){perror(“tcgetattr fd”);return;}for(i = 0; i < sizeof(speed_arr) / sizeof(int); i++){if(speed == name_arr[i]){tcflush(fd, TCIOFLUSH);cfsetispeed(&Opt, speed_arr[i]);cfsetospeed(&Opt, speed_arr[i]);if(tcsetattr(fd, TCSANOW, &Opt) != 0){perror(“tcsetattr fd”);return;}tcflush(fd, TCIOFLUSH);}}}注意tcsetattr函数中使用的标志:TCSANOW:立即执行而不等待数据发送或者接受完成。

嵌入式linux串口应用程序编写流程

嵌入式linux串口应用程序编写流程

嵌入式linux串口应用程序编写流程嵌入式Linux系统提供了丰富的串口接口,可以通过串口与其他设备进行通信,这为开发嵌入式系统提供了很多可能性。

下面是编写嵌入式Linux串口应用程序的流程:1. 确定串口设备:首先要确定要使用的串口设备,可以使用命令`ls /dev/tty*`来查看系统中可用的串口设备列表。

根据需要选择合适的串口设备。

2. 打开串口设备:在Linux系统中,使用文件的方式来操作串口设备。

可以使用C语言中的open函数来打开串口设备文件,并返回串口设备的文件描述符。

例如:`int serial_fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);`。

其中,`O_RDWR`表示以读写模式打开串口设备,`O_NOCTTY`表示打开设备后不会成为该进程的控制终端,`O_NDELAY`表示非阻塞模式。

3. 配置串口参数:打开串口设备后,需要配置串口参数,包括波特率、数据位、停止位、校验位等。

可以使用C语言中的termios库来进行串口参数的配置。

例如:```cstruct termios serial_config;tcgetattr(serial_fd, &serial_config);cfsetispeed(&serial_config, B115200);cfsetospeed(&serial_config, B115200);serial_config.c_cflag |= CS8;serial_config.c_cflag &= ~PARENB;serial_config.c_cflag &= ~CSTOPB;tcsetattr(serial_fd, TCSANOW, &serial_config);```上述代码将波特率设置为115200,数据位设置为8位,无校验位,一个停止位。

Linux下串口通信详解(上)打开串口和串口初始化详解

Linux下串口通信详解(上)打开串口和串口初始化详解

Linux下串口通信详解(上)打开串口和串口初始化详解Linux下串口通信主要有下面几个步骤串口通信流程图下面我会一一介绍这几个步骤。

1.打开串口代码(串口为ttyUSB0)[java] view plain copy1.//打开串口2.int open_port(void)3.{4.int fd;5.6.fd=open("/dev/ttyUSB0",O_RDWR | O_NOCTTY | O_NON BLOCK);//O_NONBLOCK设置为非阻塞模式,在read时不会阻塞住,在读的时候将read放在while循环中,下一节篇文档将详细讲解阻塞和非阻塞7.// printf("fd=%d\n",fd);8.9.if(fd==-1)10.{11.perror("Can't Open SerialPort");12.}13.14.return fd;15.}打开串口时也可以多加一些内容,比如判断串口为阻塞状态、测试是否为终端设备等,这些是必要的,所以较上面的基本的打开串口的代码,更加完整健壮一些的代码流程如下所示:打开串口较完整流程图代码:[cpp] view plain copy1./**2.* open port3.* @param fd4.* @param comport 想要打开的串口号5.* @return 返回-1为打开失败6.*/7.int open_port(int fd,int comport)8.{9.char *dev[]={"/dev/ttyUSB0","/dev/ttyS1","/dev/ttyS2"};10.11.if (comport==1)//串口112.{13.fd = open( "/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_N DELAY);14.if (-1 == fd)15.{16.perror("Can't Open Serial Port");17.return(-1);18.}19.}20.else if(comport==2)//串口221.{22.fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDEL AY); //没有设置<span style="font-family: Arial, Helvetica, sans-serif;">O_NONBLOCK非阻塞模式,也可以设置为非阻塞模式,两个模式在下一篇博客中具体说明</span>23.24.if (-1 == fd)25.{26.perror("Can't Open Serial Port");27.return(-1);28.}29.}30.else if (comport==3)//串口331.{32.fd = open( "/dev/ttyS2", O_RDWR|O_NOCTTY|O_NDEL AY);33.if (-1 == fd)34.{35.perror("Can't Open Serial Port");36.return(-1);37.}38.}39./*恢复串口为阻塞状态*/40.if(fcntl(fd, F_SETFL, 0)<0)41.printf("fcntl failed!\n");42.else43.printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));44./*测试是否为终端设备*/45.if(isatty(STDIN_FILENO)==0)46.printf("standard input is not a terminal device\n");47.else48.printf("isatty success!\n");49.printf("fd-open=%d\n",fd);50.return fd;51.}关键函数解释:功能描述:用于打开或创建文件,成功则返回文件描述符,否则返回-1,open返回的文件描述符一定是最小的未被使用的描述符[cpp] view plain copy1.#include<fcntl.h>2.int open(const char *pathname, int oflag, ... );参数解释:pathname:文件路径名,串口在linux中被看做是一个文件oflag:一些文件模式选择,有如下几个参数可以设置•O_RDONLY只读模式•O_WRONLY只写模式•O_RDWR读写模式上面三个参数在设置的时候必须选择其中一个下面的是可选的•O_APPEND每次写操作都写入文件的末尾•O_CREAT如果指定文件不存在,则创建这个文件•O_EXCL如果要创建的文件已存在,则返回 -1,并且修改 errno 的值•O_TRUNC如果文件存在,并且以只写/读写方式打开,则清空文件全部内容•O_NOCTTY如果路径名指向终端设备,不要把这个设备用作控制终端。

linux下的串口通信原理及编程实例

linux下的串口通信原理及编程实例

linux下的串⼝通信原理及编程实例linux下的串⼝通信原理及编程实例⼀、串⼝的基本原理1 串⼝通讯串⼝通讯(Serial Communication),是指外设和计算机间,通过数据信号线、地线等,按位进⾏传输数据的⼀种通讯⽅式。

串⼝是⼀种接⼝标准,它规定了接⼝的电⽓标准,没有规定接⼝插件电缆以及使⽤的协议。

2 串⼝通讯的数据格式 ⼀个字符⼀个字符地传输,每个字符⼀位⼀位地传输,并且传输⼀个字符时,总是以“起始位”开始,以“停⽌位”结束,字符之间没有固定的时间间隔要求。

每⼀个字符的前⾯都有⼀位起始位(低电平),字符本⾝由7位数据位组成,接着字符后⾯是⼀位校验位(检验位可以是奇校验、偶校验或⽆校验位),最后是⼀位或⼀位半或⼆位停⽌位,停⽌位后⾯是不定长的空闲位,停⽌位和空闲位都规定为⾼电平。

实际传输时每⼀位的信号宽度与波特率有关,波特率越⾼,宽度越⼩,在进⾏传输之前,双⽅⼀定要使⽤同⼀个波特率设置。

3 通讯⽅式单⼯模式(Simplex Communication)的数据传输是单向的。

通信双⽅中,⼀⽅固定为发送端,⼀⽅则固定为接收端。

信息只能沿⼀个⽅向传输,使⽤⼀根传输线。

半双⼯模式(Half Duplex)通信使⽤同⼀根传输线,既可以发送数据⼜可以接收数据,但不能同时进⾏发送和接收。

数据传输允许数据在两个⽅向上传输,但是,在任何时刻只能由其中的⼀⽅发送数据,另⼀⽅接收数据。

因此半双⼯模式既可以使⽤⼀条数据线,也可以使⽤两条数据线。

半双⼯通信中每端需有⼀个收发切换电⼦开关,通过切换来决定数据向哪个⽅向传输。

因为有切换,所以会产⽣时间延迟,信息传输效率低些。

全双⼯模式(Full Duplex)通信允许数据同时在两个⽅向上传输。

因此,全双⼯通信是两个单⼯通信⽅式的结合,它要求发送设备和接收设备都有独⽴的接收和发送能⼒。

在全双⼯模式中,每⼀端都有发送器和接收器,有两条传输线,信息传输效率⾼。

显然,在其它参数都⼀样的情况下,全双⼯⽐半双⼯传输速度要快,效率要⾼。

Linux串口通信编程

Linux串口通信编程

2) 设置属性:奇偶校验位、数据位、停止位。

主要设置<termbits.h>中的termios3) 打开、关闭和读写串口。

串口作为设备文件,可以直接用文件描述符来进行网上的一个例子:/*串口设备无论是在工控领域,还是在嵌入式设备领域,应用都非常广泛。

而串口编程也就显得必不可少。

偶然的一次机会,需要使用串口,而且操作系统还要求是Linux,因此,趁着这次机会,综合别人的代码,进行了一次整理和封装。

具体的封装格式为C代码,这样做是为了很好的移植性,使它可以在C和C++环境下,都可以编译和使用。

代码的头文件如下: *//////////////////////////////////////////////////////////////////// //////////////filename:stty.h#ifndef__STTY_H__#define__STTY_H__//包含头文件#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<termios.h>#include<errno.h>#include<pthread.h>//// 串口设备信息结构typedef struct tty_info_t{int fd;// 串口设备IDpthread_mutex_t mt;// 线程同步互斥对象char name[24];// 串口设备名称,例:"/dev/ttyS0"struct termios ntm;// 新的串口设备选项struct termios otm;// 旧的串口设备选项}TTY_INFO;//// 串口操作函数TTY_INFO *readyTTY(int id);int setTTYSpeed(TTY_INFO *ptty,int speed);int setTTYParity(TTY_INFO *ptty,int databits,int parity,int st opbits);int cleanTTY(TTY_INFO *ptty);int sendnTTY(TTY_INFO *ptty,char*pbuf,int size);int recvnTTY(TTY_INFO *ptty,char*pbuf,int size);int lockTTY(TTY_INFO *ptty);int unlockTTY(TTY_INFO *ptty);#endif/*从头文件中的函数定义不难看出,函数的功能,使用过程如下:(1)打开串口设备,调用函数setTTYSpeed();(2)设置串口读写的波特率,调用函数setTTYSpeed();(3)设置串口的属性,包括停止位、校验位、数据位等,调用函数setTTYParity ();(4)向串口写入数据,调用函数sendnTTY();(5)从串口读出数据,调用函数recvnTTY();(6)操作完成后,需要调用函数cleanTTY()来释放申请的串口信息接口;其中,lockTTY()和unlockTTY()是为了能够在多线程中使用。

linux串口编程中非标准波特率的实现

linux串口编程中非标准波特率的实现

linux串口编程中非标准波特率的实现linux串口编程中非标准波特率的实现时间:2012-11-20 16:07来源:未知作者:long 点击:270次linux下实现标准波特率的编程非常方便,这方面的资料也举不胜举。

通常,在linux下面,设置串口使用终端IO的相关函数设置,如tcsetattr等函数,linux内部有一个对常用波特率列表的索引,根据设置的波特率用底层驱动来设置异步通信芯片的寄存器但是在一些特定应用中需要用到非标准的波特率,比如125000、28800等,这种情况下,如何实现串口通信呢?linux同样提供了对非标准波特率的支持:对于非标准的任意波特率需要用ioctl(fd, TIOCGSERIAL, p)和ioctl(fd, TIOCSSERIAL, p)的配合,ioctl的最后一个参数是struct serial_struct *类型,在linux/serial.h中定义。

其中baud_base是基准晶振频率/16(对于SEP4020来说,baud_base=sysclk/16),你需要设的是custom_divisor这个值,最终的波特率计算公式为baud=baud_base /custom_divisor,所以要设置custom_divisor=baud_base/baud,。

具体过程为,先设置波特率设为38400(tcsetattr),然后用TIOCGSERIAL得到当前的设置,将flags设置ASYNC_SPD_CUST位,设置custom_divisor,最后用TIOCSSERIAL设置。

相关代码如下:void set_baud(int fd, int baud){int status;struct termios Opt;struct serial_struct Serial;tcgetattr(fd, &Opt); /*Get current options*/tcflush(fd, TCIOFLUSH);/*Flush the buffer*/cfsetispeed(&Opt, B38400);/*Set input speed,38400 is necessary? who can tell me why?*/cfsetospeed(&Opt, 38400); /*Set output speed*/tcflush(fd,TCIOFLUSH); /*Flush the buffer*/status = tcsetattr(fd, TCSANOW, &Opt); /*Set the 38400 Options*/if (status != 0){perror("tcsetattr fd1");return;}if((ioctl(fd,TIOCGSERIAL,&Serial))<0)/*Get configurations vim IOCTL*/{printf("Fail to get Serial!\n");return;}Serial.flags = ASYNC_SPD_CUST;/*We will use custom buad,May be standard,may be not */Serial.custom_divisor=Serial.baud_base/baud;/*InSep4020,baud_base=sysclk/16*/printf("divisor is %x\n",Serial.custom_divisor);if((ioctl(fd,TIOCSSERIAL,&Serial))<0)/*Set it*/{printf("Fail to set Serial\n");return;}ioctl(fd,TIOCGSERIAL,&Serial);/*Get it again,not necessary.*/ printf("\nBAUD: success set baudto %d,custom_divisor=%d,baud_base=%d\n",baud,Serial.custo m_divisor,Serial.baud_base);}附件是一个在SEP4020开发板上实现的波特率为125000的串口通信例子,用跳线将两块4020开发板(俺用的一块Mini4020,一块Micro4020)的T/R交叉连接(两块开发板都使用的uart1,注意共地):在Micro上用ADS初始化波特率后暂停程序运行,用内存察看窗口打开0x10006000地址,并打开定时刷新功能观察这个地址的内容变化,这个地址就是RX_FIFO,有数据收到的话会有变化,看变化的数据与发送方是否一致即可简单验证波特率设置是否正确。

Linux C 串口编程

Linux C 串口编程

Linux C 串口编程arch/arm/include/asm/termbits.hstruct termios {tcflag_t c_iflag; /* input mode flags */tcflag_t c_oflag; /* output mode flags */tcflag_t c_cflag; /* control mode flags */tcflag_t c_lflag; /* local mode flags */cc_t c_line; /* line discipline */cc_t c_cc[NCCS]; /* control characters */ };串口的设置主要是设置struct termios结构体的各成员/***测试的时候应用程序在后台运行./serial_test &*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h> //文件控制定义#include <termios.h>//终端控制定义#include <errno.h>#define DEVICE "/dev/s3c2410_serial0"int serial_fd = 0;//打开串口并初始化设置init_serial(void){serial_fd = open(DEVICE, O_RDWR | O_NOCTTY | O_NDELAY);if (serial_fd < 0) {perror("open");return -1;}//串口主要设置结构体termios <termios.h>struct termios options;/**1. tcgetattr函数用于获取与终端相关的参数。

linux下485通讯c语言代码

linux下485通讯c语言代码

linux下485通讯c语言代码Linux下的485通讯C语言代码在嵌入式系统和工控领域中,485通讯是一种常见的串行通讯方式。

Linux作为一种常用的操作系统,也提供了相应的接口和工具来支持485通讯。

本文将介绍在Linux下使用C语言实现485通讯的代码。

在开始编写485通讯的C语言代码之前,我们需要先了解一些基本的概念和原理。

485通讯是一种半双工的串行通讯方式,它使用两根信号线进行数据的传输,一根用于发送数据(TX),一根用于接收数据(RX)。

通常情况下,485通讯使用的波特率较低,例如9600bps或者19200bps。

在Linux下,我们可以通过打开串口设备文件来实现485通讯。

串口设备文件的命名规则为/dev/ttySx,其中x表示串口的编号。

例如,/dev/ttyS0表示第一个串口设备,/dev/ttyS1表示第二个串口设备。

我们可以使用open函数来打开串口设备文件,并使用read 和write函数来进行数据的读写操作。

下面是一个简单的示例代码,演示了如何在Linux下使用C语言实现485通讯:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <unistd.h>#include <termios.h>int main(){int fd;char data[10];// 打开串口设备文件fd = open("/dev/ttyS0", O_RDWR);if (fd == -1) {printf("无法打开串口设备文件\n");return -1;}// 配置串口参数struct termios options;tcgetattr(fd, &options);cfsetispeed(&options, B9600); // 设置波特率为9600bps cfsetospeed(&options, B9600);options.c_cflag |= CLOCAL | CREAD;options.c_cflag &= ~CSIZE;options.c_cflag |= CS8;options.c_cflag &= ~PARENB;options.c_cflag &= ~CSTOPB;tcsetattr(fd, TCSANOW, &options);// 发送数据strcpy(data, "Hello");write(fd, data, strlen(data));// 接收数据read(fd, data, sizeof(data));printf("接收到的数据:%s\n", data);// 关闭串口设备文件close(fd);return 0;}```上述代码首先通过open函数打开了/dev/ttyS0这个串口设备文件,如果打开失败,则会提示无法打开串口设备文件并退出。

linux c语言编写modbus rtu例程 -回复

linux c语言编写modbus rtu例程 -回复

linux c语言编写modbus rtu例程-回复如何使用C语言在Linux下编写Modbus RTU例程,以实现数据的读取和写入。

Modbus是一种通信协议,用于在工业自动化系统中实现设备之间的数据通信。

RTU是Modbus协议的一种传输格式,其中数据以二进制形式传输。

在Linux系统中,我们可以使用C语言来编写Modbus RTU例程。

下面将一步一步回答如何实现数据的读取和写入。

第一步:设置串口参数在Linux中,我们可以使用串口来与Modbus设备进行通信。

首先,我们需要设置串口的波特率、数据位、停止位和校验位。

这可以通过C语言中的termios库函数来实现。

c#include <termios.h>int set_serial_port(int fd, int baudrate) {struct termios options;tcgetattr(fd, &options);cfsetispeed(&options, baudrate);cfsetospeed(&options, baudrate);options.c_cflag = (CLOCAL CREAD);options.c_cflag &= ~CSIZE;options.c_cflag = CS8;options.c_cflag &= ~PARENB;options.c_cflag &= ~CSTOPB;options.c_cflag &= ~CRTSCTS;tcsetattr(fd, TCSANOW, &options);}以上代码中,`set_serial_port`函数用于设置串口参数。

`fd`参数为串口文件描述符,`baudrate`参数为波特率。

其中,`cfsetispeed`和`cfsetospeed`函数用于设置输入和输出速度,`CLOCAL`和`CREAD`标志用于使串口工作在本地模式和可读模式,`CS8`标志用于设置8位数据位,`PARENB`标志用于禁用奇偶校验,`CSTOPB`标志用于设置停止位为1位,`CRTSCTS`标志用于禁用硬件流控制。

linux c语言 串口读取数据的方法

linux c语言 串口读取数据的方法

linux c语言串口读取数据的方法Linux下使用C语言读取串口数据的方法引言:串口是计算机和外部设备进行通信的一种重要的通信接口。

在Linux系统中,要使用C语言读取串口数据,需要通过打开串口设备文件,设置串口参数,并进行读取数据的操作。

本文将介绍如何通过C语言在Linux下读取串口数据的方法。

目录:1. 了解串口的工作原理2. 打开串口设备文件3. 设置串口参数4. 读取串口数据5. 示例程序6. 总结1. 了解串口的工作原理:在开始编写C语言读取串口数据的方法前,首先需要了解串口的工作原理。

串口是通过硬件电路实现两台设备之间的数据传输,属于一种异步串行通信方式。

典型的串口包含发送数据引脚(TX)、接收数据引脚(RX)、数据位、停止位、奇偶校验位等。

2. 打开串口设备文件:在Linux系统中,每个串口设备都被映射到一个设备文件上,例如/dev/ttyS0代表第一个串口设备,/dev/ttyUSB0代表第一个USB串口设备。

要使用C语言读取串口数据,需要首先打开相应的串口设备文件。

在C语言中,使用open()函数打开串口设备文件。

open()函数的原型如下:cint open(const char *pathname, int flags);其中pathname参数指定要打开的串口设备文件路径,flags参数指定打开方式。

常用的flags参数有O_RDONLY(只读方式打开)、O_WRONLY (只写方式打开)和O_RDWR(读写方式打开)。

例如,要打开第一个串口设备文件,可以调用open()函数如下:cint fd = open("/dev/ttyS0", O_RDWR);if (fd == -1){perror("Error opening serial port");return -1;}当open()函数成功打开串口设备文件时,会返回一个非负整数的文件描述符fd,用于后续的操作。

Linux串口编程笔记-详细剖析

Linux串口编程笔记-详细剖析

这半个月因肺部感染而不得不暂时终止那令人生厌的中石油巡检工作,闭门在家安静的修养。

整月的工钱自然是泡汤了,可却得来了极其珍贵的个人闲暇时光,让我能淋漓尽致的做软件方面的研究,虽是粗茶淡饭,针剂苦药,但可静心埋头于书房,却比天堂还甜美!恍惚已至月末,工作单位来了音讯,让我一下子从甜美的梦中惊醒,从哪里来,回哪里去,这种如"主体思想"一样可怕的思维是我挥之不去的梦魇,无奈、不知所措、病弱的身体却不由自主的向那发声的地方靠去!好了,还是不再发牢骚了,只是个人觉得这种臃肿低效的国企能够存在,本身就是对“国富论”绝佳的嘲讽,我只能用世界是多元的来啊Q一下了!切入正题,这段时间做GSM/GPRG和GPS的小东西,需要通过串口发送AT指令来控制,以前调试一直在用串口助手和minicom之类的现成软件,可是一点都不爽,为什么不自己写个操作串口的软件,就像在ARM和stm32上一样!这文章其实只是我的一个笔记,分为两篇,一篇是《storysnail的Windows串口编程笔记》,另一篇是《storysnail的Linux串口编程笔记》,由于网上已经有非常多的类似文章,有些大论,有些短小精悍,连我自己都思考过是否有必要再写一篇,但在Ling的鼓动下还是写了!本篇是Linux串口编程笔记,详细介绍了串口通信会用到的api函数,并提供了一个示例程序,这个示例程序是在EEEPC701的debian系统上编写测试的。

一:写串口程序用到的函数1:Linux与windows串口设备文件名对照2:写串口程序用到的函数串行通讯函数定义在termios.h头文件中,所以需要包含该文件。

下面是要介绍的函数列表open用途:打开串口原型:int open( const char * pathname,int flags);参数说明:pathname: 指向欲打开的文件路径字符串flags 所能使用的标志位:O_RDONLY 以只读方式打开文件O_WRONLY 以只写方式打开文件O_RDWR 以可读写方式打开文件。

简单的Linux串口通信程序

简单的Linux串口通信程序

int fd; /*以读写方式打开串口*/ fd = open( "/dev/ttyS0", O_RDWR); if (-1 == fd){ perror("error"); }
17:43
3. 设置串口
最基本的设置串口包括波特率设置,校验位和停止位设置,数 据位。串口的设置主要是设置struct termios结构体的各成员值。
1
• 实验步骤
– 1.阅读理解源码
• 源码位置:serial\serial.c • 阅读源码方法
– Linux下使用gedit编辑器 – windows下使用SourceInsight软件
– 2.编译应用程序
2
【基础知识】
Linux操作系统从一开始就对串行口提供了很好的支持,为进行
串行通讯提供了大量的函数,本实验主要是为掌握在Linux中进行 串行通讯编程的基本方法。
2. 打开串口
在Linux 下串口文件是位于/dev 下,com1为/dev/ttyS0 ,com2 为/dev/ttyS1 操作系统 串口1 Windows COM1 Linux /dev/ttyS0 串口2 COM2 /dev/ttyS1 USB/RS-232转换器 /dev/ttyUSB0
打开串口是通过使用标准的文件打开函数操作:
struct termios { unsigned short c_iflag; /* 输入模式标志*/ unsigned short c_oflag; /* 输出模式标志*/ unsigned short c_cflag; /* 控制模式标志*/ unsigned short c_lflag; /* local mode flags */ unsigned char c_line; /* line discipline */ unsigned char c_cc[NCC]; /* control characters */ };

Linux 串口读写

Linux 串口读写

Linux 串口读写串口简介串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用。

常用的串口是RS-232-C 接口(又称EIA RS-232-C)它是在1970 年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准。

它的全名是"数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准"该标准规定采用一个25 个脚的DB25 连接器,对连接器的每个引脚的信号内容加以规定,还对各种信号的电平加以规定。

传输距离在码元畸变小于4% 的情况下,传输电缆长度应为50 英尺。

Linux 操作系统从一开始就对串行口提供了很好的支持串口操作打开串口在Linux 下串口文件是位于/dev 下的串口一为/dev/ttyS0串口二为/dev/ttyS1设置串口最基本的设置串口包括波特率设置,效验位和停止位设置。

设置这个结构体很复杂,我这里就只说说常见的一些设置:波特率设置设置波特率的例子函数:/***@brief 设置串口通信速率*@param fd 类型 int 打开串口的文件句柄*@param speed 类型 int 串口速度*@return void*/int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,B38400, B19200, B9600, B4800, B2400,B1200, B300, };int name_arr[] ={38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, }; void set_speed(int fd, int speed){int i;int status;struct termios Opt;tcgetattr(fd, &Opt);for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) {if (speed == name_arr[i]) {/*** tcflush函数刷清(抛弃)输入缓存(终端驱动程序已接收到,但用户程序尚未读)或输出缓存(用户程序已经写,但尚未发送)。

基于linux (fedora 17)的QT串口通信实例

基于linux (fedora 17)的QT串口通信实例
下载到的文件为 qextserialport-1.2win-alpha.zip
2.解压下载的文件到当前目录
# unzip qextserialport-1.2win-alpha.zip
这里不对压缩包内的详细信息及qextserialport类的结构做详细介绍,直接说明需要用到的源文件
linux下:
myCom->setParity(PAR_NONE);
//奇偶校验设置,我们设置为无校验
myCom->setStopBits(STOP_1);
//停止位设置,我们设置为1位停止位
myCom->setFlowControl(FLOW_OFF);
//数据流控制设置,我们设置为无数据流控制
ui(new Ui::MainWindow){
ui->setupUi(this);
//myCom = new Win_QextSerialPort("COM1",QextSerialBase::EventDriven);
//【windows下使用】定义串口对象,指定串口名和查询模式,这里使用事件驱动EventDriven
3.打开Qt Creator集成开发环境,新建工程Qt4 Gui Application ,工程名为com ,其他默认即可。
4.将上述linux下需要用到的4个文件拷贝至com工程目录下,然后将该4个文件添加至工程。
5.将整个工程编译,会报错如下:
error: 'struct PortSettings' has no member named 'Timeout_Sec'
qextserialbase.cpp qextserialbase.h posix_qextserialport.cpp posix_qextserialport.h

串口编程的一般步骤及相关函数讲解

串口编程的一般步骤及相关函数讲解

串口编程的一般步骤及相关函数讲解串口编程是指通过串口与外部设备进行通信的程序设计。

一般步骤包括串口初始化、设置串口参数、打开串口、发送数据、接收数据和关闭串口等。

1. 串口初始化:首先需要导入串口编程相关的库文件,如pyserial 库。

然后通过serial.Serial(函数创建一个串口对象,指定串口号、波特率、停止位、数据位等参数,如:``````这里将串口号设置为/dev/ttyUSB0,波特率设置为9600,超时时间设置为1秒。

2.设置串口参数:通过串口对象的相关方法设置串口参数,如:```serial_port.setBaudrate(9600)serial_port.setParity(serial.PARITY_NONE)serial_port.setStopbits(serial.STOPBITS_ONE)serial_port.setByteSize(serial.EIGHTBITS)```这里设置了波特率为9600,无奇偶校验位,1位停止位,8位数据位。

3. 打开串口:使用串口对象的open(方法打开串口,如:serial_port.open```注意,打开串口之前要确保串口没有被其他程序占用。

4. 发送数据:使用串口对象的write(方法向串口发送数据,如:```data = 'Hello, World!'serial_port.write(data.encode()```这里将字符串'Hello, World!'转码为字节型数据并发送到串口。

5. 接收数据:使用串口对象的read(方法从串口读取数据,如:```received_data = serial_port.read(10)print(received_data.decode()```这里从串口读取10字节的数据,并将其解码为字符串输出。

6. 关闭串口:使用串口对象的close(方法关闭串口,如:```serial_port.close在程序结束时,记得关闭串口以释放资源。

Linux串口select编程

Linux串口select编程

Linux下串口程序开发串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用。

常用的串口是RS-232-C接口(又称EIA RS-232-C)它是在1970年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准。

它的全名是"数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准"该标准规定采用一个25个脚的DB25连接器,对连接器的每个引脚的信号内容加以规定,还对各种信号的电平加以规定。

传输距离在码元畸变小于4%的情况下,传输电缆长度应为50英尺。

在linux文件中,所有的设备文件一般都位于/dev下,其中串口一、串口二分别对应的设备名依次为“/dev/ttyS0”、“/dev/ttyS1”,可以查看在/dev下的文件以确认。

在linux下面对于串口的读写就可以通过简单的read、write函数来完成,所不同的是只是需要对串口的其他参数另坐配置。

1.串口编程需要用到的头文件#include <stdio.h> // 标准输入输出定义#include <stdlib.h>#include <fcntl.h> // 文件控制定义,主要完成串口通信中对文件的读写操作#include <unistd.h> // linux标准函数定义#include <sys/ioctl.h>#include <termios.h> // POSIX终端控制定义#include <sys/time.h>#include <sys/types.h>2.串口终端函数2.1打开串口设备int fd;char *device = "/dev/tts/0"; // 设备路径,初始使用UART0for(t=1;t<argc;t++) // 获取程序入口时输入的参数{if(!strcmp(argv[t],"-d") && (argc > (t+1))){device = argv[t+1];}}if(!strcmp(device,"/dev/tts/1")) // 不允许使用UART1,因为它已和PC相连。

linux 读取串口数据方法

linux 读取串口数据方法

linux 读取串口数据方法【原创实用版2篇】目录(篇1)一、Linux 读取串口数据的方法概述二、使用 C 语言读取串口数据三、使用 Qt 库读取串口数据四、使用 Python 读取串口数据五、总结正文(篇1)一、Linux 读取串口数据的方法概述在 Linux 系统中,串口是一种常用的设备接口,可以用于接收和发送数据。

Linux 提供了多种方法来读取和操作串口数据。

本文将介绍几种常见的方法,包括使用 C 语言、Qt 库和 Python 语言来读取串口数据。

二、使用 C 语言读取串口数据1.打开串口在 C 语言中,打开串口需要使用 fcntl 函数。

首先,需要包含头文件<fcntl.h>和<termios.h>。

然后,使用以下代码打开串口:```cint fd = open("/dev/ttyS0", O_RDWR);if (fd < 0) {perror("Can"t Open Serial Port");return -1;}```2.设置串口速度打开串口成功后,需要设置串口的波特率、数据位、校验位和停止位等参数。

可以使用以下代码设置串口速度:```cstruct termios tty;if (tcgetattr(fd, &tty)!= 0) {perror("Can"t Get Serial Port Attributes");return -1;}tty.c_cflag &= ~PARENB; // 清除奇偶校验位tty.c_cflag &= ~CSTOPB; // 使用一个停止位tty.c_cflag |= CS8; // 8 位数据位tty.c_cflag &= ~CRTSCTS; // 禁用硬件流控制tty.c_cflag |= CREAD | CLOCAL; // 使能读和忽略 modem 控制线if (tcsetattr(fd, TCSANOW, &tty)!= 0) {perror("Can"t Set Serial Port Attributes");return -1;}```3.读取串口数据使用以下代码读取串口数据:char buf[64];int len = read(fd, buf, sizeof(buf));if (len < 0) {perror("Can"t Read from Serial Port");return -1;}printf("Read data: %s", buf);```三、使用 Qt 库读取串口数据在 Qt 中,可以使用 QSerialPort 类来读取串口数据。

linux串口收发程序

linux串口收发程序

下面简单介绍了,在REDHAT9操作系统下的使用终端接收发送串口数据recive程序的使用,它通过串口接收其它计算机传送到本地计算机的数据,程序稳定可靠2.源代码:接收串口程序recive.c的源码#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <termios.h>#include <errno.h>#include <string.h>#define TRUE 1//初始化串口选项:void setTermios(struct termios * pNewtio, int uBaudRate){bzero(pNewtio, sizeof(struct termios)); /* clear struct for new port settings *///8N1pNewtio->c_cflag = uBaudRate | CS8 | CREAD | CLOCAL;pNewtio->c_iflag = IGNPAR;pNewtio->c_oflag = 0;pNewtio->c_lflag = 0; //non ICANON/*initialize all control charactersdefault values can be found in /usr/include/termios.h, andare 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' */}#define BUFSIZE 512int main(int argc, char **argv){int fd;int nread;int input;int *p=&input;//char buff[BUFSIZE];char buff[1024];struct termios oldtio, newtio;struct timeval tv;char *dev ="/dev/ttyS0";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, B9600);tcflush(fd, TCIFLUSH);tcsetattr(fd, TCSANOW, &newtio);//printf("Please input an integer.");//scanf("%d",&input);//*p=input;//printf("The integer you input is %d\n",*p);//printf("The integer you input is %d\n",&input); _sec=30;_usec=0;while (TRUE){printf("wait...\n");FD_ZERO(&rfds);FD_SET(fd, &rfds);if (select(1+fd, &rfds, NULL, NULL, &tv)>0) {printf("wait...\n");if (FD_ISSET(fd, &rfds)){//nread=read(fd, buff, BUFSIZE);nread=read(fd, buff ,1024);printf("readlength=%d\n", nread);//buff[nread]='\0';//printf("%s\n", buff);// buff='\0';printf("date=%d\n",buff);//printf("%d\n",fd);printf("%d\n", buff[1]);printf("%d\n", buff[2]);printf("%d\n", buff[3]);printf("%d\n", buff[4]);printf("%d\n", buff[5]);printf("%d\n", buff[6]);printf("%d\n", buff[7]);printf("%d\n", buff[8]);printf("%d\n", buff[9]);printf("%d\n", buff[10]);printf("%d\n", buff[11]);printf("%d\n", buff[12]);printf("%d\n", buff[13]);printf("%d\n", buff[14]);printf("%d\n", buff[15]);printf("%d\n", buff[16]);printf("%d\n", buff[17]);printf("%d\n", buff[18]);printf("%d\n", buff[19]);//printf("%d\n", buff[20]);//printf("%d\n", buff[21]);//printf("%d\n", buff[22]);//printf("%d\n", buff[23]);//printf("%d\n", buff[24]);//printf("%d\n", buff[25]);//printf("%d\n", buff[26]);//printf("%d\n", buff[27]);//printf("%d\n", buff[28]);//printf("%d\n", buff[29]);//printf("%d\n", buff[30]);//printf("%d\n", buff[31]);//printf("%d\n", buff[32]);//printf("%d\n", buff[1]);//printf("%d\n", buff[2]);//printf("%d\n", buff[3]);//printf("%d\n", buff[4]);//printf("%d\n", buff[5]);//printf("%d\n", buff[6]);//printf("%d\n", buff[7]);//printf("%d\n", buff[8]);//printf("%d\n", buff[9]);//printf("%d\n", buff[10]);//printf("%d\n", buff[32]);//printf("%d\n", buff[12]);//printf("%d\n", buff[13]);//printf("%d\n", buff[14]);//printf("%d\n", buff[15]);//printf("%d\n", buff[16]);}}}tcsetattr(fd, TCSANOW, &oldtio); close(fd);}串口发送程序send.c的源码#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <termios.h>#include <errno.h>#include <string.h>//初始化串口选项:void setTermios(struct termios * pNewtio, int uBaudRate){bzero(pNewtio, sizeof(struct termios)); /* clear struct for new port settings */ //8N1pNewtio->c_cflag = uBaudRate | CS8 | CREAD | CLOCAL;pNewtio->c_iflag = IGNPAR;pNewtio->c_oflag = 0;pNewtio->c_lflag = 0; //non ICANON/*initialize all control charactersdefault values can be found in /usr/include/termios.h, andare 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' */}int main(int argc, char **argv){int fd;int input;int *p=&input;int nCount, nTotal, i;struct termios oldtio, newtio;char *dev ="/dev/ttyS0";//if ((argc!=3) || (sscanf(argv[1], "%d", &nTotal) != 1))//{//printf("err: need tow arg =%d!\n", argc );//return -1;//}//sscanf(argv[1], "%d", &nTotal)//{//printf("send date!\n", argc );//return -1;//}if ((fd = open(dev, O_RDWR | O_NOCTTY))<0){printf("err: can't open serial port!\n");return -1;}while (1) //循环读取数据{tcgetattr(fd, &oldtio); /* save current serial port settings */ setTermios(&newtio, B9600);tcflush(fd, TCIFLUSH);tcsetattr(fd, TCSANOW, &newtio);//for (i=0; i<nTotal; i++)//{//nCount=write(fd, argv[2], s]trlen(argv[2]));//argv[]={010*********d5ca};printf("Please input an integer.");scanf("%d",&input);*p=input;//nCount=write(fd,argv[p],strlen(argv[]));printf("The integer you input is %d\n",*p);printf("The integer you input is %d\n",&input);nCount=write(fd,"010*********d5ca/r",512);nCount=write(fd,p,1024);nCount=write(fd,&input,1024);printf("send date *p");printf("send date input");printf("send date 010*********d5ca\n"); //sleep(1);}tcsetattr(fd, TCSANOW, &oldtio); close(fd);return 0;}。

linux串口配置参数

linux串口配置参数

linux串口配置参数Linux操作系统提供了丰富的串口资源,支持通过串口与外部设备进行通信。

在Linux下配置串口参数需要关注以下几个关键要素:串口号、波特率、数据位、停止位、校验位和流控制等。

下面将详细介绍如何配置这些参数。

一、确定串口号在Linux系统中,每个串口设备都有一个唯一的串口号,可以通过ls/dev/tty*命令查看系统中的所有串口设备。

在配置串口参数之前,需要确定要使用的串口号。

通常,串口号以/dev/ttyS或/dev/ttyUSB开头,可以根据实际情况进行判断。

二、配置波特率波特率是串口通信中最基本的参数之一,它决定了数据传输的速度。

在Linux系统中,可以使用minicom或screen等终端仿真器进行串口通信,这些工具默认使用9600波特率。

可以根据实际需求进行调整,常见的波特率有115200、57600等。

可以使用cat/proc/stty串口文件查看当前配置的波特率。

三、设置数据位、停止位和校验位数据位、停止位和校验位是串口通信中的其他重要参数。

数据位决定了传输的数据位数,常见的有5、6、7和8位等;停止位决定了传输的停顿时间,常见的有1、1.5和2位等;校验位则用于检查数据传输过程中的错误,常见的有奇校验和偶校验等。

这些参数可以在终端仿真器的配置中进行设置,也可以使用stty命令进行全局配置。

四、启用流控制流控制用于控制数据传输过程中的流量,避免数据传输过快导致丢包或溢出等问题。

常见的流控制方式有软件流控制(xon/xoff)和硬件流控制(rts/cts)。

软件流控制通过检测串口输入流控制信号(xon/xoff)来实现流量控制;硬件流控制通过控制数据端口的电平来实现流量控制。

可以在终端仿真器的配置中启用相应的流控制方式。

五、测试配置效果完成串口参数配置后,可以通过串口通信测试来验证配置是否正确。

可以使用cat或echo命令将数据发送到串口设备,并使用另一终端仿真器接收数据,观察是否能够正常通信。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

串行端口程序设计

c_iflag 输入模式标志,控制终端输入方式,具体参数如下表所示。
键 值 说 明 IGNBRK BRKINT IGNPAR PARMRK INPCK ISTRIP INLCR IGNCR ICRNL IUCLC IXON IXANY IXOFF IMAXBEL 忽略BREAK键输入 如果设置了IGNBRK,BREAK键的输入将被忽略,如果设置了BRKINT ,将 产生SIGINT中断 忽略奇偶校验错误 标识奇偶校验错误 允许输入奇偶校验 去除字符的第8个比特 将输入的NL(换行)转换成CR(回车) 忽略输入的回车 将输入的回车转化成换行(如果IGNCR未设置的情况下) 将输入的大写字符转换成小写字符(非POSIX) 允许输入时对XON/XOFF流进行控制 输入任何字符将重启停止的输出 允许输入时对XON/XOFF流进行控制 当输入队列满的时候开始响铃,Linux在使用该参数而是认为该参数总是已经 设置
串口详细配置


在使用串口之前必须设置相关配置,包括:波特率、数据位、 校验码、停止位等。串口设置由下面结构体实现: struct termios { tcflag_t c_iflag; /* 输入模式 */ tcflag_t c_oflag; /* 输出模式 */ tcflag_t c_cflag; /* 控制模式 */ tcflag_t c_lflag; /* 本地模式 */ cc_t c_cc[NCCS]; /* 控制字符 */ } 在<arm2410s/kernel-2410s/include/asm-i386/termbits.h> 中.
VQUIT
Quit字符
VTIME
非规范模式读取时的超时时间
VERASE
Erase字符
VSTOP
Stop字符
VKILL
Kill字符
VSTART
Start字符
VEOF
End-of-file字符
VSUSP
Suspend字符
VMIN
非规范模式读取时的最小字符数
12ห้องสมุดไป่ตู้
串口控制函数
tcgetattr tcsetattr cfgetispeed cfgetospeed cfsetispeed cfsetospeed tcdrain tcflow tcflush tcsendbreak tcgetpgrp tcsetpgrp 取属性( t e r m i o s结构) 设置属性( t e r m i o s结构) 得到输入速度 得到输出速度 设置输入速度 设置输出速度 等待所有输出都被传输 挂起传输或接收 刷清未决输入和/或输出 送B R E A K字符 得到前台进程组I D 设置前台进程组I D
打开串口

1、打开串口是通过使用标准的文件打开函数操作: int fd; /*以读写方式打开串口*/ fd = open( "/dev/ttyS0", O_RDWR); if (-1 == fd){ /* 不能打开串口一*/ perror(" 提示错误!"); }
14/30
打开串口
#include <fcntl.h> int open(const char *pathname, int oflag) 返回值:成功则返回文件描述符,否则返回 -1 对于 open 函数来说,第三个参数(...)仅当创建新文件时 才使用,用于指定文件的访问权限位(access permission bits)。 pathname 是待打开/创建文件的路径名(如 C:/cpp/a.cpp ); oflag 用于指定文件的打开/创建模式,这个参数可由以下常 量(定义于 fcntl.h)通过逻辑或构成。 O_RDONLY 只读模式 O_WRONLY 只写模式 O_RDWR 读写模式

15/30
设置串口



所有对串口的操作都是通过结构体 struct termios和几个函 数实现的,其中两个最常用的函数是tcgetattr()和 tcsetattr() 几乎在所有情况下,程序都是通过tcgetattr()函数获取设 备当前的设置,然后修改这些设置,最后用tcsetattr()使 这些设置生效。 许多程序会保存终端初始的设置并在终止运行前恢复这些设 置。

tcflush(fd,TCIFLUSH);
21/30
读写串口


5、设置好串口之后,读写串口就很容易了,可以把串口当 作文件读写 发送数据: char buffer[1024]; int Length=1024; int nByte; nByte = write(fd, buffer ,Length)
BSDLY
VTDLY FFDLY
空格输出延迟,可以取BS0或BS1
垂直制表符输出延迟,可以取VT0或VT1 换页延迟,可以取FF0或FF1
9
串行端口程序设计

c_cflag 控制模式标志,指定终端硬件控制信息,具体参数如下表所示。
键 值 说 明 CBAUD CBAUDEX CSIZE CSTOPB CREAD PARENB PARODD HUPCL CLOCAL CRTSCTS 波特率(4+1位)(非POSIX) 附加波特率(1位)(非POSIX) 字符长度,取值范围为CS5、CS6、CS7或CS8 设置两个停止位 使用接收器 使用奇偶校验 对输入使用奇偶校验,对输出使用偶校验 关闭设备时挂起 忽略调制解调器线路状态 使用RTS/CTS流控制
10
串行端口程序设计

c_lflag 本地模式标志,控制终端编辑功能,具体参数如下表所示。
键 ISIG ICANON XCASE 值 说 明 当输入INTR、QUIT、SUSP或DSUSP时,产生相应的信号 使用标准输入模式 在ICANON和XCASE同时设置的情况下,终端只使用大写。如果只设置 了XCASE,则输入字符将被转换为小写字符,除非字符使用了转义字符 (非POSIX,且Linux不支持该参数) 显示输入字符 如果ICANON同时设置,ERASE将删除输入的字符,WERASE将删除输 入的单词 如果ICANON同时设置,KILL将删除当前行 如果ICANON同时设置,即使ECHO没有设置依然显示换行符 如果ECHO和ICANON同时设置,将删除打印出的字符(非POSIX) 向后台输出发送SIGTTOU信号
Linux下串口程序设计
1/30
嵌入式系统设计实验二


实验时间 1班 10月27日 19:00 – 21:25 2班 10月28日 08:00 – 10:25 实验内容 串行端口程序设计(2.3必做,并提交实验报告) 第二章 其他实验(选做) 实验报告提交 时间:下周实验之前 提交方式: 发送到邮箱: chhli@(1班), chenbo2008@(2班), 文件命名:学号+姓名+实验二.doc 邮件主题:嵌入式系统设计实验二
20/30
设置串口


4、处理要写入的数据对象:
tcflush()函数 tcflush函数刷清(抛弃)输入缓存(终端驱动程序已收到,但用户程序 尚未读)或输出缓存(用户程序已经写,但尚未发送)。 原型为:int tcflush(int fd ,int queue_selector) queue_selector数应当是下列三个数之一: TCIFLUSH——丢弃驱动上已经接收到但还没读入的所有数据 TCOFLUSH——丢弃所有已经写入驱动但还没发送的数据 TCIOFLUSH——丢弃所有输入输出队列上还没有读取或发送的数据


19/30
设置串口

3、激活配置: int tcsetattr (int fd, int options ,struct termios *t) 用来将termios结构指针t内的设置值赋给当前用文件描述符 fd表示的设备终端

参数options决定什么时候改变才生效 TCSANOW———修改立即生效 TCSADRAIN——所有已经发送的输出写入fd后生效 TCSAFLUSH——输出队列为空时生效
4
实验目的


������ 了解在 linux 环境下串行程序设计的基本方法。 ������ 掌握终端的主要属性及设置方法,熟悉终端 I /O 函数 的使用。 ������ 学习使用多线程来完成串口的收发处理。
5/30
实验原理与程序分析


Linux 对所有各类设备文件的输入输出操作,看上去就像对 普通文件的输入输出一样,所以Linux 对串口的操作,也是 通过设备文件访问的。为了访问串口,只需要打开相应的设 备文件即可。 默认地,在Linux 下,串行口COM1 和COM2对应的设备分 别为/dev/ttyS0 和/dev/ttyS1。
2

串行端口程序设计

实验步骤 1.阅读理解源码 源码位置:exp\basic\03_tty 阅读源码方法 Linux下使用vi编辑器(Linux、VI常用命令参考实 验指导书第七章附录7.1、7.2) windows下使用SourceInsight软件 2.编译应用程序
3
16/30
保存串口当前状态

2、保存原先串口配置使用tcgetattr(fd,&oldtio)

int tcgetattr (int fd ,struct termios *t) 用于获得文件描述符fd所表示设备的当前设置值,并写入指 针 t内 .
struct termios oldtio, oldstdtio; tcgetattr(0,&oldstdtio); tcgetattr(fd,&oldtio); /* save current modem settings */
相关文档
最新文档