Linux环境串口程序设计.docx

上传人:b****1 文档编号:15152601 上传时间:2023-07-01 格式:DOCX 页数:15 大小:18.81KB
下载 相关 举报
Linux环境串口程序设计.docx_第1页
第1页 / 共15页
Linux环境串口程序设计.docx_第2页
第2页 / 共15页
Linux环境串口程序设计.docx_第3页
第3页 / 共15页
Linux环境串口程序设计.docx_第4页
第4页 / 共15页
Linux环境串口程序设计.docx_第5页
第5页 / 共15页
Linux环境串口程序设计.docx_第6页
第6页 / 共15页
Linux环境串口程序设计.docx_第7页
第7页 / 共15页
Linux环境串口程序设计.docx_第8页
第8页 / 共15页
Linux环境串口程序设计.docx_第9页
第9页 / 共15页
Linux环境串口程序设计.docx_第10页
第10页 / 共15页
Linux环境串口程序设计.docx_第11页
第11页 / 共15页
Linux环境串口程序设计.docx_第12页
第12页 / 共15页
Linux环境串口程序设计.docx_第13页
第13页 / 共15页
Linux环境串口程序设计.docx_第14页
第14页 / 共15页
Linux环境串口程序设计.docx_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Linux环境串口程序设计.docx

《Linux环境串口程序设计.docx》由会员分享,可在线阅读,更多相关《Linux环境串口程序设计.docx(15页珍藏版)》请在冰点文库上搜索。

Linux环境串口程序设计.docx

Linux环境串口程序设计

Linux环境串口程序设计

串口是计算机上一种非常通用设备通信的协议,常用PC机上包含的是RS232规格的串口,具有连接线少,通讯简单,得到广泛的使用。

Linux对所有设备的访问是通过设备文件来进行的,串口也是这样,为了访问串口,只需打开其设备文件即可操作串口设备。

在linux系统下面,每一个串口设备都有设备文件与其关联,设备文件位于系统的/dev目录下面。

如linux下的/ttyS0,/ttyS1分别表示的是串口1和串口2。

在串口编程中,比较重要的是串口的设置,我们要设置的部分包括:

波特率,数据位,停止位,奇偶校验位;要注意的是,每台机器的串口默认设置可能是不同的,如果你没设置这些,仅仅按照默认设置进行发送数据,很可能出现n多异想不到而又查不出来的情况。

1)设置波特率

#include

#include

intcfsetispeed(structtermios*termios_p,speed_tspeed);

intcfsetospeed(structtermios*termios_p,speed_tspeed);

2)设置属性:

奇偶校验位、数据位、停止位。

主要设置中的termios结构体即可:

#defineNCCS19

structtermios{

tcflag_tc_iflag;/*inputmodeflags*/

tcflag_tc_oflag;/*outputmodeflags*/

tcflag_tc_cflag;/*controlmodeflags*/

tcflag_tc_lflag;/*localmodeflags*/

cc_tc_line;/*linediscipline*/

cc_tc_cc[NCCS];/*controlcharacters*/

};

有相应的函数供获取和设置属性:

inttcgetattr(intfd,structtermios*termios_p);

inttcsetattr(intfd,intoptional_actions,structtermios*termios_p);

3)打开、关闭和读写串口。

串口作为设备文件,可以直接用文件描述符来进行操作。

#include

#include

#include

intopen(constchar*pathname,intflags);

#include

intclose(intfd);

ssize_twrite(intfd,constvoid*buf,size_tcount);

ssize_tread(intfd,void*buf,size_tcount);

网上的一个例子:

/*串口设备无论是在工控领域,还是在嵌入式设备领域,应用都非常广泛。

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

偶然的一次机会,需要使用串口,而且操作系统还要求是Linux,因此,趁着这次机会,综合别人的代码,

进行了一次整理和封装。

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

都可以编译和使用。

代码的头文件如下:

*/

///////////////////////////////////////////////////////////////////////////////

//filename:

stty.h

#ifndef__STTY_H__

#define__STTY_H__

//包含头文件

#include

#include

#include

#include

#include

#include

#include

#include

#include

//

//串口设备信息结构

typedefstructtty_info_t

{

intfd;//串口设备ID

pthread_mutex_tmt;//线程同步互斥对象

charname[24];//串口设备名称,例:

"/dev/ttyS0"

structtermiosntm;//新的串口设备选项

structtermiosotm;//旧的串口设备选项

}TTY_INFO;

//

//串口操作函数

TTY_INFO*readyTTY(intid);

intsetTTYSpeed(TTY_INFO*ptty,intspeed);

intsetTTYParity(TTY_INFO*ptty,intdatabits,intparity,intstopbits);

intcleanTTY(TTY_INFO*ptty);

intsendnTTY(TTY_INFO*ptty,char*pbuf,intsize);

intrecvnTTY(TTY_INFO*ptty,char*pbuf,intsize);

intlockTTY(TTY_INFO*ptty);

intunlockTTY(TTY_INFO*ptty);

#endif

/*从头文件中的函数定义不难看出,函数的功能,使用过程如下:

(1)打开串口设备,调用函数setTTYSpeed();

(2)设置串口读写的波特率,调用函数setTTYSpeed();

(3)设置串口的属性,包括停止位、校验位、数据位等,调用函数setTTYParity();

(4)向串口写入数据,调用函数sendnTTY();

(5)从串口读出数据,调用函数recvnTTY();

(6)操作完成后,需要调用函数cleanTTY()来释放申请的串口信息接口;

其中,lockTTY()和unlockTTY()是为了能够在多线程中使用。

在读写操作的前后,需要锁定和释放串口资源。

具体的使用方法,在代码实现的原文件中,main()函数中进行了演示。

下面就是源代码文件:

*/

////////////////////////////////////////////////////////////////////////////////

//stty.c

#include

#include

#include"stty.h"

///////////////////////////////////////////////////////////////////////////////

//初始化串口设备并进行原有设置的保存

TTY_INFO*readyTTY(intid)

{

TTY_INFO*ptty;

ptty=(TTY_INFO*)malloc(sizeof(TTY_INFO));

if(ptty==NULL)

returnNULL;

memset(ptty,0,sizeof(TTY_INFO));

pthread_mutex_init(&ptty->mt,NULL);

sprintf(ptty->name,"/dev/ttyS%d",id);

//

//打开并且设置串口

ptty->fd=open(ptty->name,O_RDWR|O_NOCTTY|O_NDELAY);

if(ptty->fd<0)

{

free(ptty);

returnNULL;

}

//

//取得并且保存原来的设置

tcgetattr(ptty->fd,&ptty->otm);

returnptty;

}

///////////////////////////////////////////////////////////////////////////////

//清理串口设备资源

intcleanTTY(TTY_INFO*ptty)

{

//

//关闭打开的串口设备

if(ptty->fd>0)

{

tcsetattr(ptty->fd,TCSANOW,&ptty->otm);

close(ptty->fd);

ptty->fd=-1;

free(ptty);

ptty=NULL;

}

return0;

}

///////////////////////////////////////////////////////////////////////////////

//设置串口通信速率

//ptty参数类型(TTY_INFO*),已经初始化的串口设备信息结构指针

//speed参数类型(int),用来设置串口的波特率

//return返回值类型(int),函数执行成功返回零值,否则返回大于零的值

///////////////////////////////////////////////////////////////////////////////

intsetTTYSpeed(TTY_INFO*ptty,intspeed)

{

inti;

//

//进行新的串口设置,数据位为8位

bzero(&ptty->ntm,sizeof(ptty->ntm));

tcgetattr(ptty->fd,&ptty->ntm);

ptty->ntm.c_cflag=/*CS8|*/CLOCAL|CREAD;

switch(speed)

{

case300:

ptty->ntm.c_cflag|=B300;

break;

case1200:

ptty->ntm.c_cflag|=B1200;

break;

case2400:

ptty->ntm.c_cflag|=B2400;

break;

case4800:

ptty->ntm.c_cflag|=B4800;

break;

case9600:

ptty->ntm.c_cflag|=B9600;

break;

case19200:

ptty->ntm.c_cflag|=B19200;

break;

case38400:

ptty->ntm.c_cflag|=B38400;

break;

case115200:

ptty->ntm.c_cflag|=B115200;

break;

}

ptty->ntm.c_iflag=IGNPAR;

ptty->ntm.c_oflag=0;

//

//

tcflush(ptty->fd,TCIFLUSH);

tcsetattr(ptty->fd,TCSANOW,&ptty->ntm);

//

//

return0;

}

//设置串口数据位,停止位和效验位

//ptty参数类型(TTY_INFO*),已经初始化的串口设备信息结构指针

//databits参数类型(int),数据位,取值为7或者8

//stopbits参数类型(int),停止位,取值为1或者2

//parity参数类型(int),效验类型取值为N,E,O,,S

//return返回值类型(int),函数执行成功返回零值,否则返回大于零的值

///////////////////////////////////////////////////////////////////////////////

intsetTTYParity(TTY_INFO*ptty,intdatabits,intparity,intstopbits)

{

//

//取得串口设置

if(tcgetattr(ptty->fd,&ptty->ntm)!

=0)

{

printf("SetupSerial[%s]\n",ptty->name);

return1;

}

bzero(&ptty->ntm,sizeof(ptty->ntm));

ptty->ntm.c_cflag=CS8|CLOCAL|CREAD;

ptty->ntm.c_iflag=IGNPAR;

ptty->ntm.c_oflag=0;

//

//设置串口的各种参数

ptty->ntm.c_cflag&=~CSIZE;

switch(databits)

{//设置数据位数

case7:

ptty->ntm.c_cflag|=CS7;

break;

case8:

ptty->ntm.c_cflag|=CS8;

break;

default:

printf("Unsupporteddatasize\n");

return5;

}

//

//

switch(parity)

{//设置奇偶校验位数

casen:

caseN:

ptty->ntm.c_cflag&=~PARENB;/*Clearparityenable*/

ptty->ntm.c_iflag&=~INPCK;/*Enableparitychecking*/

break;

caseo:

caseO:

ptty->ntm.c_cflag|=(PARODD|PARENB);/*设置为奇效验*/

ptty->ntm.c_iflag|=INPCK;/*Disnableparitychecking*/

break;

casee:

caseE:

ptty->ntm.c_cflag|=PARENB;/*Enableparity*/

ptty->ntm.c_cflag&=~PARODD;/*转换为偶效验*/

ptty->ntm.c_iflag|=INPCK;/*Disnableparitychecking*/

break;

caseS:

cases:

/*asnoparity*/

ptty->ntm.c_cflag&=~PARENB;

ptty->ntm.c_cflag&=~CSTOPB;

break;

default:

printf("Unsupportedparity\n");

return2;

}

//

//设置停止位

switch(stopbits)

{

case1:

ptty->ntm.c_cflag&=~CSTOPB;

break;

case2:

ptty->ntm.c_cflag|=CSTOPB;

break;

default:

printf("Unsupportedstopbits\n");

return3;

}

//

//

ptty->ntm.c_lflag=0;

ptty->ntm.c_cc[VTIME]=0;//inter-charactertimerunused

ptty->ntm.c_cc[VMIN]=1;//blockingreaduntil1charsreceived

tcflush(ptty->fd,TCIFLUSH);

if(tcsetattr(ptty->fd,TCSANOW,&ptty->ntm)!

=0)

{

printf("SetupSerial\n");

return4;

}

return0;

}

intrecvnTTY(TTY_INFO*ptty,char*pbuf,intsize)

{

intret,left,bytes;

left=size;

while(left>0)

{

ret=0;

bytes=0;

pthread_mutex_lock(&ptty->mt);

ioctl(ptty->fd,FIONREAD,&bytes);

if(bytes>0)

{

ret=read(ptty->fd,pbuf,left);

}

pthread_mutex_unlock(&ptty->mt);

if(ret>0)

{

left-=ret;

pbuf+=ret;

}

usleep(100);

}

returnsize-left;

}

intsendnTTY(TTY_INFO*ptty,char*pbuf,intsize)

{

intret,nleft;

char*ptmp;

ret=0;

nleft=size;

ptmp=pbuf;

while(nleft>0)

{

pthread_mutex_lock(&ptty->mt);

ret=write(ptty->fd,ptmp,nleft);

pthread_mutex_unlock(&ptty->mt);

if(ret>0)

{

nleft-=ret;

ptmp+=ret;

}

//usleep(100);

}

returnsize-nleft;

}

intlockTTY(TTY_INFO*ptty)

{

if(ptty->fd<0)

{

return1;

}

returnflock(ptty->fd,LOCK_EX);

}

intunlockTTY(TTY_INFO*ptty)

{

if(ptty->fd<0)

{

return1;

}

returnflock(ptty->fd,LOCK_UN);

}

#ifdefLEAF_TTY_TEST

///////////////////////////////////////////////////////////////////////////////

//接口测试

intmain(intargc,char**argv)

{

TTY_INFO*ptty;

intnbyte,idx;

unsignedcharcc[16];

ptty=readyTTY(0);

if(ptty==NULL)

{

printf("readyTTY(0)error\n");

return1;

}

//

//

lockTTY(ptty);

if(setTTYSpeed(ptty,9600)>0)

{

printf("setTTYSpeed()error\n");

return-1;

}

if(setTTYParity(ptty,8,N,1)>0)

{

printf("setTTYParity()error\n");

return-1;

}

//

idx=0;

while

(1)

{

cc[0]=0xFA;

sendnTTY(ptty,&cc[0],1);

nbyte=recvnTTY(ptty,cc,1);

printf("%d:

%02X\n",idx++,cc[0]);

}

cleanTTY(ptty);

}

#endif

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 考试认证 > 其它考试

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2