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

来源:互联网 发布:逍遥法外 知乎 编辑:程序博客网 时间:2024/04/29 18:14
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>



0 0
原创粉丝点击