您的位置:首页 > 运维架构 > Linux

【代码参考网上的】linux串口编程学习笔记

2015-10-07 19:47 651 查看
1.串口通信:
同步通信:将很多字符组成一个信息组进行发送
异步通信:一个字符一符的发送。(可靠性高,但是效率相对降低)

2.通过echo和cat来测试串口通信 echo “Hello” >/dev/ttyS0   cat /dev/ttyS1

3.直接通过read/write函数来读写串口  用select()函数来监听

4.struct termios opt;/*定义指向termios结构类型的指针opt*/
cfsetispeed(&opt,B9600);/*制定输入波特率 ,9600bps*/
cfsetospeed(&opt,B9600);/*制定输出波特率,9600bps*/

5.fd=open("/dev/ttyS0",O_RDWR|O_NOCTTY);/*以读写方式打开设备*/
int read(int fd,*buffer,length);
int write(int fd,*buffer,length);
int close(int fd);

6.串口操作需要的头文件:
#include <stdio.h>/*标准输入输出定义*/
#include <stdlib.h>/*标准函数库定义*/
#include <unistd.h>/*Unix标准函数定义*/
#include <sys/types.h>
#include <sys/stat.h>
#include  <fcntl.h>/*文件控制定义*/
#include <termios.h>/*PPSIX终端控制定义*/
#include <errno.h>/*错误号定义*/

7.RTS/CTS 请求数据发送/清楚数据发送

8.设置串口流程
1.保存运来串口配置使用tcgetattr(fd,&oldtio)函数
struct termios newtio,oldtio;
tcgetattr(fd,&oldtio);
2.激活选项有CLOCAL和CREAD,用于本地连接和接收使能
newtio.c_cflag |= CLOCAL|CREAD;
3.设置波特率,使用函数cfsetispeed,cfsetospeed
cfsetispeed(&newtio,B115200);
cfsetospeed(&newtio,B115200);
4.设置数据位,需使用掩码设置
newtio.c_cflag&=~CSIZE;
newtio.c_cflag|=CS8;
5.设置奇偶校验位,使用c_cflag和c_iflag.
设置奇校验:
newtio.c_cflag|=PARENB;
newtio.c_cflag|=PARODD;
newtio.c_iflag|=(INPACK|ISTRIP);
设置偶校验:
newtio.c_iflag|=(INPACK|ISTRIP);
newtio.c_cflag|=PARENB;
newtio.c_cflag&=~PARODD;
7.设置停止位,通过激活c_cflag中的CSTOPB实现,若停止位为1,则
清除CSTOPB,若停止位为2,则激活
newtio.c-cfalg&~CSTOPB;
8。设置最少字符和等待时间,对于接收字符和等待时间没有特别要求时,可设为0;
newtio.c_cc[VTIME]=0;

newtio.c_cc[VMIN]=0;
9.处理要写入的引用对象
tcflush函数刷清(抛弃)输入缓存(终端驱动程序已经接收到但是用户程序尚未读)或者输出缓存
int tcflush(int filedes,int queue);
queue数应当是下列三个常数之一:TCIFLUSH刷清输入队列,TCOFLUSH抒情输出队列,TCIOFLUSH刷清输入输出队列
比如:tcflush(fd,TCIFLUSH);

10激活配置。用tsettattr();比如:tcsetattr(fd,TCSANOW,&newtio);



</pre><pre name="code" class="cpp"><span style="font-size:18px;"><strong>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>

/*
**@名称:open_port
**@功能:打开串口
**@参数 fd 类型 int 含义 文件标号
**@参数 comport 类型 int 含义 用户选择的串口号
**@返回值: -1 打开串口失败
**@返回值: 0 打开串口成功
*/
int open_port(int fd,int comport)
{
char *dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};
long vdisable;
if(1==comport)
{
fd=open(dev[0],O_RDWR|NOCTTY|NDELAY);
if(-1==fd)
{
perror("can`t open serial port!!!\n");
return -1;
}
else
{
printf("open ttyS0");
}
}
else if(comport==2)
{    fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY);
if (-1 == fd)
{
perror("Can't Open Serial Port");
return(-1);
}
else
{
printf("open ttyS1 .....\n");
}
}
else if (comport==3)
{
fd = open( "/dev/ttyS2", O_RDWR|O_NOCTTY|O_NDELAY);
if (-1 == fd)
{
perror("Can't Open Serial Port");
return(-1);
}
else
{
printf("open ttyS2 .....\n");
}
}
/*然后恢复串口的状态为阻塞状态,用于等待串口数据的读入,用fcntl函数:
**fcntl(fd,F_SETFL,0);  //F_SETFL:设置文件flag为0,即默认,即阻塞状态****
** 接着测试打开的文件描述符是否应用一个终端设备,以进一步确认串口是否正确打开.
**isatty(STDIN_FILENO);
*/

if(fcntl(fd,F_SETFL,0)<0)
{
printf("fcntl failed!!!\n");
}
else
{
printf("fcntl=%d\n",fcntl(fd,F_SETFL,0));
}
if(0==isatty(STDIN_FILENO))
{
printf("standard input is not a terminal device!!!\n");
}
else
{
printf("isatty success!!\n");
}
printf("fd-open%d\n",fd);
return fd;
}

/*
**@名称:set_port
**@功能:设置串口
**@参数 fd 类型 int 含义 文件标号
**@参数 nSpeed 类型 int 含义 速度
**@参数 nBits 类型 int 含义 数据位
**@参数 nEvent类型 int 含义 奇偶校验
**@参数 nStop类型 int 含义 停止位
**@返回值: -1 设置串口失败
**@返回值: 0 设置串口成功
*/
int set_port(int fd,int nSpeed,int nBits,char nEvent,int nStop)
{
struct termios newtio,oldtio;
if(tcgetattr(fd,&oldtio)!=0)
{//获取终端相关参数失败
perror("setupSerial 1");
return -1;
}
bzero(&newtio,sizeof(newtio));//值前n个字节为0
/*
** 2>激活选项有CLOCAL和CREAD,用于本地连接和接收使用
** newtio.c_cflag | = CLOCAL | CREAD;
*/
newtio.c_cflag|=CLOACAL|CREAD;
newtio.c_cflag&=~CSIZE;//将数据位清零
switch(nBits)
{
case 7:
newtio.c_cflag|=CS7;
break;
case 8:
newtio.c_cflag|=CS8;
break;

}

switch(nEvent)
{
case 'o'://奇校验
case 'O':
newtio.c_cflag|=PARENB;
newtio.c_cflag|=PARODD;
newtio.c_iflag|=(INPCK|ISTRIP);
case 'e'://偶校验
case 'E':
newtio.c_iflag|=(INPCK|ISTRIP);
newtio.c_cflag|=PARENB;
newtio.c_cflag&=~PARODD;
break;
case 'n'://无校验
case 'N':
newtio.c_cflag&=~PARENB;
break;

}

switch(nSpeed)
{
case 4800:
cfsetispeed(&newtio, B4800);
cfsetospeed(&newtio, B4800);
break;
case 115200:
cfsetispeed(&newtio,B115200);
cfsetospeed(&newtio,B115200);
break;
default:
printf("set error!!!\n");
}
switch(nStop)
{
case 1:
newtio.c_cflag&=~CSTOPB;
break;
case 2:
newtio.c_cflag|=CSTOPB;
break;
}

newtio.c_cc[VTIME]=0;
newtio.c_cc[VMIN]=0;

tcflush(fd,TCIFLUSH);
if((tcsetattr(fd,TCSANOW,&newtio))!=0)
{
perror("com set error!!!\n");
return -1;
}
printf("set done!!!\n");
return 0;
}

int main()
{
int fd;//用于接收打开串口的状态
int i;//用于接收设置串口的状态
int nread;//用于接收read的返回值
char buff[]="zhang lei\n";
if((fd=open_port(fd,1))<0)
{//打开串口不成功
perror("open_port error!!!\n");
return -1;
}
if((i=set_port(fd,115200,8,'N',1))<0)
{//设置串口不成功
perror("set_port error!!!\n");
return -1;
}
printf("fd=%d",fd);
nread=read(fd,buff,8);
close(fd);
return 0;
}</strong></span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux 串口编程