串口设置,select和 signal 在linux编程中的使用实例
以下程序包括串口的波特率,数据位,停止位,奇偶校验位的设置代码,是封装好的可以直接使用的,还包括select和signal在监听端口的使用方法,也是可以直接套用!#include#include#include //get local time#include /*Unix标准函数定义*/#include /**/
·
以下程序包括串口的波特率,数据位,停止位,奇偶校验位的设置代码,是封装好的可以直接使用的,
还包括select和signal在监听端口的使用方法,也是可以直接套用!
#include <stdio.h>
#include <stdlib.h>#include <sys/time.h> //get local time
#include <unistd.h> /*Unix标准函数定义*/
#include <sys/types.h> /**/
#include <sys/stat.h> /**/
#include <fcntl.h> /*文件控制定义*/
#include <termios.h> /*PPSIX终端控制定义*/
#include <errno.h> /*错误号定义*/
#include <string.h> // 提供bzero函数
#include <linux/kernel.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/mman.h>
#define TRUE 0
#define FALSE -1
static struct termios termios_old, termios_new;
static int fd_ser; //File descriptor for the serial zigbee
static fd_set fs_read;
static struct timeval tv_timeout={1,0};
static struct sigaction sigaction_io; /* definition of signal action */
static int set_port_sig ();
static void setbaudrate (int);
static int getbaudrate ();
static void setdatabit (int databit);
static int BAUDRATE (int baudrate);
static int _BAUDRATE (int baudrate);
static int setportattr (int baudrate, int databit,
const char *stopbit, char parity);
static void setstopbit (const char *stopbit);
static void setparitycheck (char parity);
int open_port (int comport, int baudrate, int databit,
const char *stopbit, char parity)
{
char *pcomport;
int retval;
switch (comport) {
case 0:
pcomport = "/dev/ttySAC0";
break;
case 1:
pcomport = "/dev/ttySAC1";
break;
case 2:
pcomport = "/dev/ttySAC2";
break;
case 3:
pcomport = "/dev/ttySAC3";
break;
default:
pcomport = "/dev/ttySAC1";
break;
}
fd_ser = open (pcomport, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (-1 == fd_ser) {
return (-1);
}
tcgetattr (fd_ser, &termios_old); /* save old termios value */
/* 0 on success, -1 on failure */
retval = setportattr (baudrate, databit, stopbit, parity);
if (-1 == retval) {
return (-1);
}
return (retval);
}
/* get serial port baudrate */
static int getbaudrate ()
{
return (_BAUDRATE (cfgetospeed (&termios_new)));
}
/* set serial port baudrate by use of file descriptor fd_ser */
static void setbaudrate (int baudrate)
{
termios_new.c_cflag = BAUDRATE (baudrate); /* set baudrate */
}
static void setdatabit (int databit)
{
termios_new.c_cflag &= ~CSIZE;
switch (databit) {
case 8:
termios_new.c_cflag |= CS8;
break;
case 7:
termios_new.c_cflag |= CS7;
break;
case 6:
termios_new.c_cflag |= CS6;
break;
case 5:
termios_new.c_cflag |= CS5;
break;
default:
termios_new.c_cflag |= CS8;
break;
}
}
static void setstopbit (const char *stopbit)
{
if (0 == strcmp (stopbit, "1")) {
termios_new.c_cflag &= ~CSTOPB; /* 1 stop bit */
}
else if (0 == strcmp (stopbit, "1.5")) {
termios_new.c_cflag &= ~CSTOPB; /* 1.5 stop bits */
}
else if (0 == strcmp (stopbit, "2")) {
termios_new.c_cflag |= CSTOPB; /* 2 stop bits */
}
else {
termios_new.c_cflag &= ~CSTOPB; /* 1 stop bit */
}
}
static void setparitycheck (char parity)
{
switch (parity) {
case 'N': /* no parity check */
termios_new.c_cflag &= ~PARENB;
break;
case 'E': /* even */
termios_new.c_cflag |= PARENB;
termios_new.c_cflag &= ~PARODD;
break;
case 'O': /* odd */
termios_new.c_cflag |= PARENB;
termios_new.c_cflag |= ~PARODD;
break;
default: /* no parity check */
termios_new.c_cflag &= ~PARENB;
break;
}
}
static int setportattr (int baudrate,
int databit, const char *stopbit, char parity)
{
bzero (&termios_new, sizeof (termios_new));
cfmakeraw (&termios_new);
setbaudrate (baudrate);
termios_new.c_cflag |= CLOCAL | CREAD; /* | CRTSCTS */
setdatabit (databit);
setparitycheck (parity);
setstopbit (stopbit);
termios_new.c_oflag = 0;
termios_new.c_lflag |= 0;
termios_new.c_oflag &= ~OPOST;
termios_new.c_cc[VTIME] = 10; /* unit: 1/10 second. */
termios_new.c_cc[VMIN] = 128; /* minimal characters for reading */
tcflush (fd_ser, TCIFLUSH);
return (tcsetattr (fd_ser, TCSANOW, &termios_new));
}
static int BAUDRATE (int baudrate)
{
switch (baudrate) {
case 2400:
return (B2400);
case 9600:
return (B9600);
case 19200:
return (B19200);
case 38400:
return (B38400);
case 57600:
return (B57600);
case 115200:
return (B115200);
default:
return (B9600);
}
}
static int _BAUDRATE (int baudrate)
{
/* reverse baudrate */
switch (baudrate) {
case B2400:
return (2400);
case B9600:
return (9600);
case B19200:
return (19200);
case B38400:
return (38400);
case B57600:
return (57600);
case B115200:
return (115200);
default:
return (9600);
}
}
void close_port()
{
tcsetattr (fd_ser, TCSADRAIN, &termios_old);
close (fd_ser);
}
/* *************************************************
* name:insert_data_db()
*brief: pick up parameter from recvbuf
* return value:
*************************************************/
/*
static int insert_data_db(char *data)
{
if(*data==0xfe)
{
int temp;//存放提取后的数据,为了区别于前面的定义所以使用了简写
int hum;
int illum;
int carb;
temp=*(data+temperature);
hum=*(data+humidity);
illum=*(data+illumination);
carb=*(data+carbon);
temp=(temp/10)+(temp%10);
hum=(hum/10)+(hum%10);
illum=(illum/10)+(illum%10);
carb=(carb/10)+(carb%10);
insert_db(temp,hum,illum,carbon);
}
}*/
/* *************************************************
* name:read_port()
*brief:read data from port
* return value: all data of read
*************************************************/
static int read_port (char *data, int datalength)
{
int retval = 0;
FD_ZERO (&fs_read);
FD_SET (fd_ser, &fs_read);
retval = select (fd_ser+1, &fs_read, NULL, NULL, &tv_timeout); //Linux下用select查询串口数据
if (retval>0) {
if(FD_ISSET(fd_ser,&fs_read))
{ return(read(fd_ser,data,datalength));
tcflush(fd_ser,TCIOFLUSH);
}
}
else
return (-1);
}
/**************************************************************
name :signal_handler_IO()
brief :execute the reaction of signal
*************************************************************/
static void signal_handler_IO ()
{printf(" break begin \r\n");
int i = 0, start = 0;
int status;
char recvbuf[256];
int numflag = 0;
status=read_port(recvbuf, 128);
if(status>0)
{
//insert_data_db(recvbuf);
printf("status=%d\r\n",status);
printf("%s",recvbuf);
}
close_port();
if(open_port(1,115200,8,"1",'N')<0)
printf("open port erro!");
set_port_sig();
printf(" break over\r\n");
//bzero(recvbuf,sizeof(recvbuf));
}
/**************************************************************
name:set_port_sig()
brief:install the signal handler before making the device asynchronous
*************************************************************/
static int set_port_sig ()
{
sigaction_io.sa_handler = signal_handler_IO;
sigemptyset (&(sigaction_io.sa_mask));
sigaction_io.sa_flags = 0;
sigaction_io.sa_restorer = NULL;
sigaction (SIGIO, &sigaction_io, NULL);
/* allow the process to receive SIGIO */
if (-1 == fcntl (fd_ser, F_SETFL, O_ASYNC))
return (-1);
if (-1 == fcntl (fd_ser, F_SETOWN, getpid ()))
return (-1);
/* Make the file descriptor asynchronous (the manual page says only
O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
return (0);
}
int main()
{
if(open_port(1,115200,8,"1",'N')<0)
printf("open port erro!");
set_port_sig();
while(1)
{usleep(20000);}
close_port();
}
更多推荐
已为社区贡献1条内容
所有评论(0)