linux java 串口编程_串口编程(3)--实现Linux、Unix串口通讯

Linux平台上的串口通讯API很简单,也很适用,使用C语言实现。我特别觉得它的读数据函数很好用,因为使用了select机制,可以很容易的做读数据超时。代码简单,不说了,自己下载了看就明白了。

/**

* @file serialport.c

* @brief serial port API implementation

* @author Deng Yangjun

* @date 2007-1-9

* @version 0.1

*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include"serialport.h"

#ifdef__cplusplus

extern"C" {

#endif

#defineMAX_DEV_NAME 256

intspeed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,

B38400, B19200, B9600, B4800, B2400, B1200, B300, };

intname_arr[] = {38400,19200,9600,4800,2400,1200,300,

38400,19200,9600, 4800, 2400, 1200,300, };

/**

* @briefset speed of the serial port

* @paramfd [in] file description of the serial port

* @paramspeed [in] speed that want to set value in speed array

* @return error code

*/

intset_serial_port_speed(int fd, int speed)

{

inti;

intstatus;

struct termiosopt;

tcgetattr(fd, &opt);

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]);

status = tcsetattr(fd, TCSANOW, &opt);

if(status != 0)

return status;

else

return 0;

}

tcflush(fd,TCIOFLUSH);

}

//invalid baud rate

assert(FALSE);

}

/**

* @briefset serial port control flag

* @paramfd [in] file description of the serial port

* @paramdatabits [in] data bits, it's value is 7 or 8

* @paramstopbits [in] stop bits, it's value is 1 or 2

* @paramparity[in] parity char, it's value is onef of 'N','E','O','S'

* @return error code

*/

intset_serial_port_ctrl_flag(int fd,int databits,int stopbits,int parity)

{

struct termios options;

int result = tcgetattr(fd,&options);

if(result != 0){

return result;

}

/*8N1*/

options.c_cflag &= ~CSIZE; /* Mask the character size bits */

switch (databits)

{

case 7:

options.c_cflag |= CS7;

break;

case 8:

options.c_cflag |= CS8;

break;

default:

assert(FALSE);

break;

}

switch (parity)

{

case 'n':

case 'N':

options.c_cflag &= ~PARENB;/* Clear parity enable */

options.c_iflag &= ~INPCK;/* Enable parity checking */

break;

case 'o':

case 'O':

options.c_cflag |= (PARODD | PARENB);/* Set odd checking*/

options.c_iflag |= INPCK;/* Disnable parity checking */

break;

case 'e':

case 'E':

options.c_cflag |= PARENB;/* Enable parity */

options.c_cflag &= ~PARODD;/* Set event checking*/

options.c_iflag |= INPCK;/* Disnable parity checking */

break;

case 'S':

case 's':/*as no parity*/

options.c_cflag &= ~PARENB;

options.c_cflag &= ~CSTOPB;

break;

default:

assert(FALSE);

break;

}

//set stop bits

switch (stopbits)

{

case 1:

options.c_cflag &= ~CSTOPB;

break;

case 2:

options.c_cflag |= CSTOPB;

break;

default:

assert(FALSE);

break;

}

/* Set input parity option */

if (parity != 'n') {

options.c_iflag |= INPCK;

}

options.c_cc[VTIME] = 150; // 15 seconds

options.c_cc[VMIN] = 0;

options.c_cflag &= ~CRTSCTS;//disable hardware flow control;

options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);/*raw input*/

options.c_oflag&= ~OPOST;/*raw output*/

tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */

result = tcsetattr(fd,TCSANOW,&options);

if ( result != 0)

{

return result;

}

return 0;

}

/**

* @breif open serial port device

* @param dev [in] name of the device

* @return file description of the device

*/

staticint open_dev(const char *dev)

{

intfd = open( dev, O_RDWR | O_NOCTTY | O_NDELAY );

if (fd != -1 ){

fcntl(fd, F_SETFL,0); //set to block

}

return fd;

}

/**

* @breif open serial port

* @param port_num [in] number of the serial port, from 0~255

* @return file description of the serial port

*/

int open_serial_port(int port_num)

{

assert(port_num > -1 && port_num < 256);

char dev[MAX_DEV_NAME]={0};

// dev/ttyS0 = serial port 0

sprintf(dev,"/dev/ttyS%d",port_num);

return open_dev(dev);

}

/**

* @brief write serial port data

* @param fd [in] file description of serial port

* @param buffer [in] write data buffer

* @param size [in] write data buffer size

* @return write data count,return -1, occur error

*/

int write_serial_port(int fd,unsigned char *buffer, size_t size)

{

int writecount = write(fd,buffer,size);

return writecount;

}

/**

* @briefread N data from serial port in time out

* @paramfd [in] file description of the serial port

* @parambuffer [in] read data buffer

* @paramsize [in] read data buffer size

* @param readcount [in,out] at last read (readcount) size data.

* set it equal to 0, read random count data.

* it will return received data count.

* return -1, the serial port closed

* return N, count of the serial port received

* @paramtimeout [in] read N count data's time out

* @returnreturn 0 : time out\n

* return -1 : error\n

* return N: received data count\n

*/

intread_serial_port(int fd, unsigned char *buffer,size_t size, size_t *readcount,

struct timeval *timeout)

{

assert(size >= *readcount);

fd_set inputs;

int result; //select result

int nread; //totla read count

int iread; //ont time read count

int maxfd;

maxfd = fd + 1; //NOTE

nread = 0 ;

FD_ZERO(&inputs);

FD_SET(fd, &inputs);

do {

result = select(maxfd, &inputs,(fd_set *)NULL, (fd_set *)NULL, timeout);

switch(result)

{

case 0: //time out

case -1: //error

return result;

default:

if(FD_ISSET(fd,&inputs)) {

ioctl(fd,FIONREAD,&iread);

if(iread == 0) {

*readcount = -1; //port closed

return TRUE;

}

int count = 0;

if(*readcount != 0) {

//only care buffer size

count = min(iread, size - nread);

}

nread += read(fd, buffer+nread, count);

}

else {

assert(FALSE);

}

}//end of switch

}while((*readcount != 0) && (nread < *readcount));

//receive random data, return data count

if( 0 == *readcount) {

*readcount = nread;

}

return TRUE;

}

/*

* @brief close serial port

* @param fd [in] file description of the serial port

*/

voidclose_serial_port(int fd)

{

close(fd);

}

#ifdef__cplusplus

} /* extern "C" */

#endif

posted on 2007-08-24 09:31 天下无双 阅读(2627) 评论(2)  编辑 收藏 引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值