linux c串口程序

以下是一个典型的串口初始化程序:

 

#include "uart.h"
#include <stdio.h> 
#include <unistd.h> 
#include <fcntl.h>
#include <termios.h>  
#include <errno.h> 

int open_uart(char *Dev)
{
  int fd=open(Dev,O_RDWR|O_NOCTTY|O_NDELAY);   //1
  if(-1==fd)
  {
    perror("open serail port");
    return -1;
  }

  if(isatty(fd)==0)  //2
  {
    perror("This is not a terminal device");
  }
  return fd;
}


char config_uart(int fd,int baud_rate,int data_bits,int stop_bits,char parity)
{
  struct termios termios_p,termios_save;
  int speed;
  if(tcgetattr(fd,&termios_save)!=0)  //3
  {
    perror("tcgetattr");
    return -1;
  }

termios_p = termios_save;
cfmakeraw(&termios_p);   //4


termios_p.c_cflag &= ~CSIZE;
switch(data_bits)
{
  case 7:
    termios_p.c_cflag |= CS7;
    break;
  case 8:
    termios_p.c_cflag |= CS8;
    break;
  default:
    termios_p.c_cflag |= CS8;
    break;
}
switch(parity)
{
   case 'n':
   case 'N':
     termios_p.c_cflag &= ~PARENB;
     termios_p.c_iflag &= ~INPCK;
     break;
   case 'o':
   case 'O':
     termios_p.c_cflag |= (PARENB | PARODD);
     termios_p.c_iflag |= INPCK;
     break;
   case 'e':
   case 'E':
     termios_p.c_cflag |= PARENB;
     termios_p.c_cflag &= ~PARODD; 
     termios_p.c_iflag |= INPCK;
     break;
   case 's':
   case 'S':
     termios_p.c_cflag &= ~PARENB;
     termios_p.c_cflag &= ~CSTOPB;
     termios_p.c_iflag |= INPCK;
     break;
   default:
     termios_p.c_cflag &= ~PARENB;
     termios_p.c_iflag &= ~INPCK;
     break;
}
switch(baud_rate)
{
    case 9600:
      speed = B9600;
      break;
    case 19200:
      speed = B19200;
      break;
    case 38400:
      speed = B38400;
      break;
    case 57600:
      speed = B57600;
      break;
    case 115200:
      speed = B115200;
      break;
    default:
      speed = B115200;
    break;
}

 

cfsetispeed(&termios_p, speed);  //5
cfsetospeed(&termios_p, speed);
switch(stop_bits)
{
    case 1:
      termios_p.c_cflag &= ~CSTOPB;
      break;
    case 2:
      termios_p.c_cflag |= CSTOPB;
      break;
    default:
      break;
}

 

tcflush(fd, TCIFLUSH); //6
if((tcsetattr(fd,TCSANOW,&termios_p))!=0) //7
{
  perror("tcsetattr error");
  return -1;
}
printf("Configure UART done.\n");
return 0;
}

 

//1 int open(“/dev/ttyS0”, status)   失败返回-1

除了使用O_RDWR标志之外,通常还会使用O_NOCTTY和O_NDELAY这两个标志。
O_NOCTTY:告诉Unix这个程序不想成为“控制终端”控制的程序,不说明这个标志的话,任何输入都会影响你的程序。
O_NDELAY:告诉Unix这个程序不关心DCD信号线状态,即其他端口是否运行,不说明这个标志的话,该程序就会在DCD信号线为低电平时停止。

 

//2 int isatty(int desc) 检测是否为终端   终端机则返回1,否则返回0

 

//3 int tcgetattr(int fd, struct termios *termios_p);tcgetattr函数用于获取与终端相关的参数。参数fd为终端的文件描述符,返回的结果保存在termios 结构体中

 

//4 将终端设置为原始模式

 

//5 设置输入输出波特率

 

//6 int tcflush(int fd, int queue_selector) 清空输入输出请求

TCIFLUSH
清除正收到的数据,且不会读取出来。
TCOFLUSH
清除正写入的数据,且不会发送至终端。
TCIOFLUSH
清除所有正在发生的I/O数据。
TCOOFF
挂起输出
TCOON
重启挂起的输出
TCIOFF
发送一个停止位
TCION
发送一个起始位

 

//7 int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);

tcsetattr函数用于设置终端参数。函数在成功的时候返回0,失败的时候返回-1,并设置errno的值。
参数fd为打开的终端文件描述符,参数optional_actions用于控制修改起作用的时间,而结构体termios_p中保存了要修改的参数。
optional_actions可以取如下的值。
TCSANOW
不等数据传输完毕就立即改变属性。
TCSADRAIN
等待所有数据传输结束才改变属性。
TCSAFLUSH
清空输入输出缓冲区才改变属性。

 

posted @ 2014-11-30 15:46  lomo1219  阅读(881)  评论(0编辑  收藏  举报