有关linux串口通信
Talk is cheap,show me the code.
COM_Linux.h
#ifndef __COM_LINUX_H__
#define __COM_LINUX_H__
#define MAX_BUF 512
#define MIN(A,B) (A<B?A:B)
int COM_open(char *);
int COM_set(int ,int ,int ,int ,char ,char );
int COM_BufQueSize(int ,int *);
int COM_recv(int ,char *,int );
int COM_transmit(int ,char *,int );
#endif
#include <stdio.h> /*开头两个头文件就不多说了*/
#include <stdlib.h>
#include <string.h> /*字符串操作会用到*/
#include <unistd.h> /*Unix标准函数定义 unix std*/
#include <fcntl.h> /*文件控制定义 file control*/
#include <termios.h> /*POSIX 终端控制定义*/
#include <errno.h> /*错误号定义*/
#include <sys/ioctl.h>
#include "COM_Linux.h"
int COM_open(char * port)
{
int fd=-1 ;
fd=open(port,O_RDWR|O_NOCTTY|O_NDELAY);
if (-1 == fd){
perror("Unable to Open Uart\n" );
return -1 ;
}else {
printf ("fd->open=%d\n" ,fd);
}
if (fcntl(fd,F_SETFL,0 )<0 ){
printf ("set flag error!\n" );
return -1 ;
}else {
printf ("fcntl=%d\n" ,fcntl(fd,F_SETFL,0 ));
}
return fd;
}
int COM_close(fd)
{
if (fd<0 ) return -1 ;
if (close(fd)==-1 ) return -1 ;
printf ("Close Uart\n" );
return 0 ;
}
int COM_set(int fd,int baud,int data_bit,int stop_bit,char parity,char flow_ctrl)
{
struct termios options;
if (tcgetattr(fd,&options)!=0 ){
perror("Set com error\n" );
return -1 ;
}
switch (baud){
case 4800 :
options.c_cflag=B4800;
break ;
case 9600 :
options.c_cflag=B9600;
break ;
case 115200 :
options.c_cflag=B115200;
break ;
default :
options.c_cflag=B9600;
break ;
}
switch (data_bit){
case 7 :
options.c_cflag&=~CSIZE;
options.c_cflag|=CS7;
break ;
case 8 :
options.c_cflag&=~CSIZE;
options.c_cflag|=CS8;
break ;
default :
options.c_cflag&=~CSIZE;
options.c_cflag|=CS8;
break ;
}
switch (stop_bit){
case 1 :
options.c_cflag&=~CSTOPB;
break ;
case 2 :
options.c_cflag|=CSTOPB;
break ;
default :
options.c_cflag&=~CSTOPB;
break ;
}
switch (parity){
case 'N' :
options.c_cflag&=~PARENB;
options.c_iflag&=~(INPCK|ISTRIP);
options.c_iflag|=IGNPAR;
break ;
case 'O' :
options.c_cflag|=(PARENB|PARODD);
options.c_iflag|=(INPCK|ISTRIP);
options.c_iflag&=~IGNPAR;
break ;
case 'E' :
options.c_cflag|=PARENB;
options.c_cflag&=~PARODD;
options.c_iflag|=(INPCK|ISTRIP);
options.c_iflag&=~IGNPAR;
break ;
default :
options.c_cflag&=~PARENB;
options.c_iflag&=~(INPCK|ISTRIP);
options.c_iflag|=IGNPAR;
break ;
}
switch (flow_ctrl){
case 'N' :
options.c_cflag&=~CRTSCTS;
options.c_iflag&=~(IXON|IXOFF|IXANY);
options.c_cflag|=CLOCAL;
break ;
case 'S' :
options.c_cflag&=~CRTSCTS;
options.c_iflag|=(IXON|IXOFF|IXANY);
options.c_cflag&=~CLOCAL;
break ;
case 'H' :
options.c_cflag|=CRTSCTS;
options.c_iflag&=~(IXON|IXOFF|IXANY);
options.c_cflag&=~CLOCAL;
break ;
default :
options.c_cflag&=~CRTSCTS;
options.c_iflag&=~(IXON|IXOFF|IXANY);
options.c_cflag|=CLOCAL;
break ;
}
options.c_cflag|=CREAD;
options.c_iflag|=IGNBRK;
options.c_lflag=0 ;
options.c_oflag=0 ;
options.c_cc[VMIN] = 1 ;
options.c_cc[VTIME] = 0 ;
if (tcsetattr(fd,TCSANOW,&options)==-1 ){
printf ("set error\n" );
return -1 ;
}
tcflush(fd,TCIFLUSH);
tcflush(fd,TCOFLUSH);
return 0 ;
}
int COM_BufQueSize(int fd,int * buf_size)
{
int byte_count=0 ;
if (fd == -1 )
return -1 ;
if (ioctl(fd,FIONREAD,&byte_count)!=-1 ){
*buf_size=byte_count;
return 0 ;
}
return -1 ;
}
int COM_recv(int fd,char * recv_buf,int data_len)
{
int rCount=0 ;
int recvBytes=0 ;
int QueSize=0 ;
if (fd<0 ){
perror("file description is valid\n" );
return -1 ;
}
if (recv_buf==NULL){
perror("read buf is NULL\n" );
return -1 ;
}
if (data_len>MAX_BUF)
recvBytes=MAX_BUF;
else
recvBytes=data_len;
memset (recv_buf,'\0' ,recvBytes);
if (COM_BufQueSize(fd,&QueSize)!=-1 ){
printf ("Uart Queue have %d bytes\n" ,QueSize);
recvBytes=MIN(recvBytes,QueSize);
}
if (!recvBytes) return -1 ;
rCount=read(fd,recv_buf,recvBytes);
if (rCount<0 ){
perror("read error\n" );
return -1 ;
}
return rCount;
}
int COM_transmit(int fd,char * mit_buf,int data_len)
{
int wCount=0 ;
int mitBytes=data_len;
if (fd<0 ){
perror("file description is valid\n" );
return -1 ;
}
if ((mitBytes>MAX_BUF)||!mitBytes) return -1 ;
wCount=write(fd,mit_buf,mitBytes);
if (wCount<0 ){
perror("write error\n" );
return -1 ;
}
while (tcdrain(fd)==-1 );
return wCount;
}
main.c
#include "COM_Linux.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CMD_MAX_LEN 255
int main(int argc,char *argv[])
{
char Read_Buf[MAX_BUF+1 ];
char Write_Buf[MAX_BUF+1 ];
char CMD[CMD_MAX_LEN+1 ];
int rCount=0 ;
int wCount=0 ;
int fd,com_port;
if (argc<3 ){
printf ("please fill the parameter\n" );
return -1 ;
}
if ((fd=COM_open(argv[1 ]))==-1 ) return -1 ;
com_port=atoi(argv[2 ]);
if (COM_set(fd,com_port,8 ,1 ,'N' ,'N' )==-1 ){
COM_close(fd);
return -1 ;
}
while (1 ){
memset (CMD,'\0' ,CMD_MAX_LEN+1 );
printf ("Enter Command: \n" );
if (!fgets(CMD,CMD_MAX_LEN+1 ,stdin)){
perror("fget error\n" );
return -1 ;
}
CMD[strlen (CMD)-1 ]='\0' ;
if (strncmp (CMD,"quit" ,sizeof ("quit" ))==0 ) break ;
if (strncmp (CMD,"read" ,sizeof ("read" ))==0 ){
memset (Read_Buf,'\0' ,MAX_BUF+1 );
rCount=COM_recv(fd,Read_Buf,MAX_BUF);
if (rCount>0 ){
printf ("ReadBuffer: %s\n" ,Read_Buf);
printf ("Read com char num: %d\n" ,rCount);
}
}
if (strncmp (CMD,"write" ,sizeof ("write" ))==0 ){
memset (Write_Buf,'\0' ,MAX_BUF+1 );
strcpy (Write_Buf,"Hello" );
printf ("Write_Buf:%s\n" ,Write_Buf);
wCount=COM_transmit(fd,Write_Buf,strlen ((char *)Write_Buf));
sleep(1 );
memset (Read_Buf,'\0' ,MAX_BUF+1 );
}
}
COM_close(fd);
return 0 ;
}