C++ 串口学习
C++ 串口学习

C++ 串口学习

1 open( 返回int 类型) 功能:用于打开或创建文件

#include<fcntl.h>

基本形式: open( “/dev/ttyUSB0”, O_RDWR|O_NOCTTY|O_NDELAY);

""内为串口 在Ubuntu 被看做一个文件夹

通过 ls | grep USB 可以找到连接的串口

如果为阻塞状态会返回-1(perror显示在报错消息之前)

O_RDONLY只读模式  O_WRONLY只写模式  O_RDWR读写模式(必选一个)

O_APPEND每次写操作都写入文件的末尾

O_CREAT如果指定文件不存在,则创建这个文件

O_EXCL如果要创建的文件已存在,则返回 -1,并且修改 errno 的值

O_TRUNC如果文件存在,并且以只写/读写方式打开,则清空文件全部内容

O_NOCTTY如果路径名指向终端设备,不要把这个设备用作控制终端

对于串口的打开操作,必须使用O_NOCTTY参数,它表示打开的是一个终端设备,程序不会成为该端口的控制终端。 如果不使用此标志,任务的一个输入(比如键盘终止信号等)都会影响进程。

O_NONBLOCK如果路径名指向 FIFO/块文件/字符文件,则把文件的打开和后继 I/O设置为非阻塞模式(nonblocking mode)

O_DSYNC等待物理 I/O 结束后再 write。在不影响读取新写入的数据的前提下,不等待文件属性更新。

O_RSYNC读(read)等待所有写入同一区域的写操作完成后再进行

O_SYNC等待物理 I/O 结束后再 write,包括更新文件属性的 I/O

O_NDELAY表示不关心DCD信号所处的状态(端口的另一端是否激活或者停止)

2 fcntl 功能:根据文件描述词来操作文件的特性,返回-1代表出错

int fcntl(int fd,int cmd);

int fcntl(int fd,int cmd,long arg);

i nt fcntl(int fd,int cmd,struct flock *lock);

cmd:

1. 复制一个现有的描述符(cmd=F_DUPFD).

2. 获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD).

3. 获得/设置文件状态标记(cmd=F_GETFL或F_SETFL).

4. 获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN).

5. 获得/设置记录锁(cmd=F_GETLK , F_SETLK或F_SETLKW).

3 isatty 功能:检查是否为串口终端

终端设备返回1 否则返回0

isatty(STDIN_FILENO)==0  

4 struct termios

{

tcflag_t c_iflag;//输入模式

tcflag_t c_oflag;//输出模式

tcflag_t c_cflag;//控制模式

tcflag_t c_lflag;//本地模式

cc_t c_cc[NCCS];//特殊控制模式

};

c_cflag 代表控制模式

CLOCAL 含义为忽略所有调制解调器的状态行,这个目的是为了保证程序不会占用串口。

CREAD 代表启用字符接收器,目的是是的能够从串口中读取输入的数据。

CS5/6/7/8 表示发送或接收字符时使用5/6/7/8比特。

CSTOPB 表示每个字符使用两位停止位。

HUPCL 表示关闭时挂断调制解调器。

PARENB: 启用奇偶校验码的生成和检测功能。

PARODD: 只使用奇校验而不使用偶校验。

c_iflag 代表输入模式

BRKINT: 当在输入行中检测到一个终止状态时,产生一个中断。

TGNBRK: 忽略输入行中的终止状态。

TCRNL: 将接受到的回车符转换为新行符。

TGNCR: 忽略接受到的新行符。

INLCR: 将接受到的新行符转换为回车符。

IGNPAR: 忽略奇偶校检错误的字符。

INPCK: 对接收到的字符执行奇偶校检。

PARMRK: 对奇偶校检错误作出标记。

ISTRIP: 将所有接收的字符裁减为7比特。

IXOFF: 对输入启用软件流控。

IXON: 对输出启用软件流控

c_cc 特殊

标准模式: 非标准模式:

VEOF: EOF字符 VINTR: INTR字符

VEOL: EOF字符 VMIN: MIN值

VERASE: ERASE字符 VQUIT: QUIT字符

VINTR: INTR字符 VSUSP: SUSP字符

VKILL: KILL字符 VTIME: TIME值

VQUIT: QUIT字符 VSTART: START字符

VSTART: START字符  VSTOP: STOP字符

VSTOP: STOP字符

5 tcgetattr可以初始化一个终端对应的termios结构

int tcgetattr(int fd, struct termios *termios_p);

int tcsetattr(int fd , int actions , const struct termios *termios_h);

#include<termios.h>

action:模式

TCSANOW:立刻对值进行修改

TCSADRAIN:等当前的输出完成后再对值进行修改

TCSAFLUSH:等当前的输出完成之后,再对值进行修改,但丢弃还未从read调用返回的当前的可用的任何输入。

6 tcflush 用于清空中端为完成的输入/输出请求及数据

int tcflush(int fd, int queue_selector);

TCIFLUSH清楚正收到的数据,且不会读出来;

TCOFLUSH清楚正写入的数据,且不会发送至终端;

TCIOFLUSH清除所有正在发送的I/O数据

我的串口代码

#include <iostream>

#include <stdio.h>

#include <fcntl.h>

#include <termios.h>

#include <unistd.h>

//#define SendBuf_LIMIT 20

using namespace std;

char usart(char Output)

{

int fd;

int wr_num=0;

struct termios options, newstate;

char * buf = new char[8];//分配内存空间

// 读、写打开|非阻塞方式|不作为控制终端|防低电平睡眠

fd = open(/dev/ttyUSB0, O_RDWR|O_NONBLOCK|O_NOCTTY|O_NDELAY); //打开串口

if(fd==-1)//串口未打开

perror(通道堵塞);

else//正常打开

cout<<正常打开!<<endl;

if(fcntl(fd, F_SETFL, 0) < 0 ) //改为阻塞模式

{

cout<<fcntl 失败<<endl;

}

else

//获取串口

tcgetattr(fd, &options);

//设置波特率

//WARNING: B9600

cfsetispeed(&options, B115200);

cfsetospeed(&options, B115200);

//获取波特率

tcgetattr(fd, &newstate);

//串口设置

options.c_cflag |= (CLOCAL | CREAD);

options.c_cflag &= ~PARENB; //设置无奇偶校验位

options.c_cflag &= ~CSTOPB; //设置停止位1

options.c_cflag &= ~CSIZE;

options.c_cflag |= CS8; //设置数据位

options.c_cc[VTIME] = 0; //阻塞模式的设置 TIME值

options.c_cc[VMIN] = 1; //MIN值

//激活新配置

tcsetattr(fd, TCSANOW, &options);//初始化termios

cout<<buf[0]<<endl;

sprintf(buf, %c, Output);

wr_num = write(fd, buf, sizeof(buf));

if(wr_num > 0)

printf(Write 成功!\n);

else

printf(Write 失败!\n);

// cout<<超时<<endl;

tcflush(fd, TCIOFLUSH);//清除所有正在发送的I/O数据

// cout<<ERROR<<endl;

read(fd, buf, size_t(buf));

cout<<buf<<endl;

return buf[0];

}

https://github.com/gbmhunter/CppLinuxSerial

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注