简单RS232通信程序

发表于:2007-07-04来源:作者:点击数: 标签:
/**********************************rs232.h 头文件*******************************/ #include s td io.h #include stdlib.h #include unistd.h #include sys/types.h #include sys/socket.h #include gt; #include arpa/inet.h #include sys/stat.h #incl

/**********************************rs232.h 头文件*******************************/

#include     <stdio.h>     
#include     <stdlib.h>    
#include     <unistd.h>    
#include     <sys/types.h> 
#include     <sys/socket.h>
#include     <.netinet/in.h>
#include     <arpa/inet.h>
#include     <sys/stat.h>  
#include     <fcntl.h>     
#include     <termios.h>   
#include     <errno.h>    
#include     <sys/select.h>
#include     <time.h>
#include     <sys/time.h>
#define FALSE  -1
#define TRUE   0
#define NET_PORT 19988

/**打开设备**/
extern int opendev(char *dev,mode_t mode);

/** 设置串口通信速率×*/
void set_speed(int fd, int speed);
 
/** 设置串口数据位,停止位和效验位×*/
extern int set_parity(int fd,int databits,int stopbits,int parity);

#define MAX_BUF_SIZE 4096
struct net2net_buf{
 int len;
 char buf[MAX_BUF_SIZE];
};

/********************************** set232.c 串口打开,设置函数********************************/
/**
#include "rs232.h"

*brief  设置串口通信速率
*param  fd     类型 int  打开串口的文件句柄
*param  speed  类型 int  串口速度
*return  void
*/
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;
 struct termios   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);  
  } 
 }
}

/**
*brief   设置串口数据位,停止位和效验位
*param  fd     类型  int  打开的串口文件句柄
*param  databits 类型  int 数据位   取值 为 7 或者8
*param  stopbits 类型  int 停止位   取值为 1 或者2
*param  parity  类型  int  效验类型 取值为N,E,O,,S
*/
int set_parity(int fd,int databits,int stopbits,int parity)
{
 struct termios options;
 if  ( tcgetattr( fd,&options)  !=  0) {
  perror("SetupSerial 1");    
  return(FALSE); 
 }
 options.c_cflag &= ~CSIZE;
 switch (databits) /*设置数据位数*/
 {  
 case 7:  
  options.c_cflag |= CS7;
  break;
 case 8:    
  options.c_cflag |= CS8;
  break;  
 default:   
  fprintf(stderr,"Unsupported data size\n");
  return (FALSE); 
 }
 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,"Unsupported parity\n");   
   return (FALSE); 
 } 
 /* 设置停止位*/ 
 switch (stopbits)
 {  
  case 1:   
   options.c_cflag &= ~CSTOPB; 
   break; 
  case 2:   
   options.c_cflag |= CSTOPB; 
   break;
  default:   
    fprintf(stderr,"Unsupported stop bits\n"); 
    return (FALSE);
 }
 /* Set input parity option */
 if (parity != 'n' && parity != 'N')  
  options.c_iflag |= INPCK;
 tcflush(fd,TCIFLUSH);
 options.c_clearcase/" target="_blank" >cc[VTIME] = 30;  /* 设置超时3 seconds*/  
 options.c_cc[VMIN] = 0;  /* Update the options and do it NOW */
 /**
 *如果不是开发终端之类的,只是串口传输数据,
 *而不需要串口来处理,那么使用原始模式(Raw Mode)方式来通讯
 **/
 options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON | IXOFF | IXANY);
 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG |IEXTEN);
 options.c_oflag &= ~OPOST;
 
 if (tcsetattr(fd,TCSANOW,&options) != 0)  
 {
  perror("SetupSerial 3");  
  return (FALSE); 
 }
 return (TRUE); 
}

/**打开串口
 * dev 串口设备名
 * mode 打开方式
**/

int opendev(char *dev,mode_t mode)
{
 int fd;
 fd = open(dev, mode);
 if (-1 == fd){    
  perror("Can't Open Serial Port");
  return -1;  
 } 
 else{
  fcntl(fd, F_SETFL, FNDELAY);
  return fd;
 }
}
/********************************** input232.c 写串口********************************/

#include "rs232.h"
#define RSDEV_NAME "/dev/ttyS1"

int main(void)
{
 
 int rsfd = 0;
 int nwrite;
 char input_buf[64];
 rsfd = opendev(RSDEV_NAME,O_RDWR | O_NOCTTY | O_NDELAY);
 if(rsfd < 0){
  printf("open error:\n");
  exit(-1);
 }
 set_speed(rsfd,9600);    /*设置速率B9600*/
 if (set_parity(rsfd,8,1,'N') == FALSE){ /*8位数据位,一位停止位*/
  printf("Set Parity Error\n");
  exit (-1);
 }
 while(1) {
  fgets(input_buf,sizeof(input_buf),stdin);
  printf("input_buf = %s", input_buf);
  nwrite = write(rsfd, input_buf, strlen(input_buf));
                if ( nwrite == -1 ) {
                        perror("ERROR!");
                        exit(1);
                }else {
                        printf("ret=%d\n", nwrite);
                }
        }  
}
/********************************** read232.c 读串口********************************/

#include "rs232.h"
#define RSDEV_NAME "/dev/ttyS1"
int read_rs232(int rsfd);
int main(void)
{
 
 int rsfd = 0;
 int nwrite;
 fd_set  fdR;
 struct timeval  timev;
 int n = 0;
 char input_buf[64];
 rsfd = opendev(RSDEV_NAME,O_RDWR | O_NOCTTY | O_NDELAY);
 if(rsfd < 0){
  printf("open error:\n");
  exit(-1);
 }
 set_speed(rsfd,9600);    /*设置速率B9600*/
 if (set_parity(rsfd,8,1,'N') == FALSE){ /*8位数据位,一位停止位*/
  printf("Set Parity Error\n");
  exit (-1);
 }
 while(1) {
  FD_ZERO(&fdR);
  FD_SET(rsfd, &fdR);
  timev.tv_sec  = 0;
  timev.tv_usec = 100000;
  n = select(rsfd+1, &fdR, NULL, NULL, &timev);
  if(n <= 0)
   continue;
  if (FD_ISSET(rsfd,&fdR)) {
   printf("rs232 recv\n");
   read_rs232(rsfd);
  }
        }  
}
int read_rs232(int rsfd)
{
 int     retbytes = 0,nread = 0;
 int all_bytes = 0;
 struct  net2net_buf netbuf;
 int i;
 memset(&netbuf,0,sizeof(netbuf));
 while((nread = read(rsfd, &netbuf.buf[retbytes], 512))>0)
 {
  printf("nread:%d\n",nread);
  retbytes += nread;
  all_bytes  += nread;
 }
 return all_bytes;
}

原文转自:http://www.ltesting.net