Linux 串口编程

来源:互联网 发布:mac开机怎么切换系统 编辑:程序博客网 时间:2024/06/14 10:31


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

 

 

 

0 0
原创粉丝点击