1.
串口编程所需要的头文件
#include<stdio.h> // Standard input/output definitions
#include <string.h> // String function definitions
#include <unistd.h> // UNIX standard function definitions
#include<fcntl.h> // File control definitions
#include<errno.h> // Error number definitions
#include <termios.h> // POSIXterminal control definitions
2.
*************************************************************************
打开串口
DEV :要打开的串口 "/dev/ttySx"
failure: return -1
sucess : return fd
open()参数说明:
O_RDWR: 可读写操作。
O_NOCTTY:串口不作为终端控制端
O_NDELAY:以不可阻断的方式打开文件,也就是无论有无数据读取或等待,都会立即返回进程之中。
设置是否阻塞方式的方法:
方法一:
fcntl(fd, F_SETFL, FNDELAY); //设置为非阻塞方式
fcntl(fd, F_SETFL,0); //设置为阻塞方式
方法二:在open时候设置为 O_NDELAY
*************************************************************************
int OpenDev(char *Dev)
{ printf("* Open Serial Port:%s......",Dev);
int fd = open( Dev, O_RDWR |O_NOCTTY | O_NDELAY);
if (-1 ==fd)
{
//perror("Can'tOpen Serial Port");
//printf("Can'tOpen Serial Port: %s\n",Dev);
printf("[Failure]\n\n");
return-1;
}
else
{fcntl(fd, F_SETFL, 0); //阻塞式
//printf("Open Serial Portsuccess: %s\n",Dev);
printf("[OK]\n");
}
return fd;
}
3.
******************************************
设置串口通信速率
fd: 打开串口的文件句柄
speed : 串口波特率
*****************************************
int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200,B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = { 38400, 19200, 9600, 4800, 2400, 1200, 300,
38400, 19200, 9600, 4800, 2400,1200, 300, };
void set_speed(int fd, int speed)
{
int i;
int status;
structtermios Opt;
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)
perror("tcsetattr fd1");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
4.
*********************************************
设置串口数据位,停止位和效验位
fd: 打开的串口文件句柄
databits : 数据位 取值 为 7 或者8
stopbits : 停止位 取值为 1 或者2
parity : 效验类型取值为N,E,O,,S
sucess: return 1
failure: return 0
**********************************************
int set_Parity(int fd,int databits,int stopbits,intparity)
{
struct termios options;
if ( tcgetattr(fd,&options) != 0)
{
perror("SetupSerial 1");
return(0);
}
//*****************************************************************
options.c_lflag &= ~(ICANON |ECHO | ECHOE ); //Raw Input
options.c_oflag &= ~OPOST; //RawOutput
options.c_iflag &= ~(IXON |IXOFF | IXANY);//disable software flow control
//******************************************************************
options.c_cflag &= ~CSIZE;
switch (databits) //设置数据位数
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupporteddata size\n");
return (0);
}
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); // 设置为奇效验
options.c_iflag |=INPCK; // Disnable parity checking
break;
case 'e':
case 'E':
options.c_cflag |=PARENB; // Enable parity
options.c_cflag&= ~PARODD; //转换为偶效验
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:
fprintf(stderr,"Unsupportedparity\n");
return (0);
}
//设置停止位//
switch (stopbits)
{
case 1:
options.c_cflag&= ~CSTOPB;
break;
case 2:
options.c_cflag |=CSTOPB;
break;
default:
fprintf(stderr,"Unsupportedstop bits\n");
return (0);
}
// Set input parity option //
if (parity != 'n')
options.c_iflag |= INPCK;
options.c_cc[VTIME] = 1; // unit=100ms delay100ms,理解为阻塞接收100ms
options.c_cc[VMIN] = 0;
tcflush(fd,TCIFLUSH); // Update the optionsand do it NOW //
if(tcsetattr(fd,TCSANOW,&options) != 0)
{
perror("SetupSerial 3");
return (0);
}
return (1);
}
5.
***************************************
Serial Port TX
int fd : open()返回的句柄
char *buf: 写入的数据
***************************************
int COM_TX(char * buf,int fd)
{ int nwrite;
nwrite =write(fd ,buf ,5);
if(-1 == nwrite)
{printf("COM write failure! & fd =%d\n",fd);
return -1;
}
else
printf("COM write success! &nwrite =%d\n",nwrite);
return 0;
}
6.
*********************************
Serial Port RX
int fd : open()返回的句柄
char *buf: 返回数据的指针
*********************************
void *COM_RX(char *buf ,int fd)
{ int nread;
if ( (nread = read(fd,buf,512)) >0)
{
printf("Receive Data& nread= %d\n",nread);
buf[nread+1]='\0';
return buf;
}
else
printf("No Data or ReceiveError!\n");
}
7.Close a Serial Port
using: close(fd);
参考资料:
《Serial Programming Guide for POSIX Operating Systems》
url: http://digilander.libero.it/robang/rubrica/serial.htm