snifer

【原创】嵌入式开发中串口配置知多少

0
阅读(2725)

串口是计算机一种常用的接口,常用的串口有RS-232-C接口。它是于1970年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准,它的全称是“数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准”。

常见的数据通信的基本方式可分为并行通信与串行通信两种。 并行通信是指利用多条数据传输线将一个字数据的各比特位同时传送。它的特点是传输速度快,适用于传输距离短且传输速度较高的通信。 }串行通信是指利用一条传输线将数据以比特位为单位顺序传送。特点是通信线路简单,利用简单的线缆就可实现通信,降低成本,适用于传输距离长且传输速度较慢的通信。

串口是计算机一种常用的接口,常用的串口有RS-232-C接口。

blob.png

串口设置主要是设置

struct termios结构体的各个成员

#include

struct termios

{    

  unsigned short  c_iflag;  /* 输入模式标志 *

  unsigned short  c_oflag;  /* 输出模式标志 *

  unsigned short  c_cflag;  /* 控制模式标志*/

  unsigned short  c_lflag;  /* 本地模式标志 */

  unsigned char   c_line;  /* 线路规程 */

  unsigned char   c_cc[NCC];      /* 控制特性 */

  speed_t     c_ispeed;  /* 输入速度 */

  speed_t     c_ospeed;  /* 输出速度 */

};

}保存原先串口设置 

为了安全起见和以后调试程序方便,可以先保存原先串口的配置,在这里可以使用函数tcgetattr(fd, &old_cfg)。该函数得到由fd指向的终端的配置参数,并将它们保存于termios结构变量old_cfg中。该函数还可以测试配置是否正确、该串口是否可用等。若调用成功,函数返回值为0,若调用失败,函数返回值为-1 }示例:

  if  (tcgetattr(fd, &old_cfg) !=  0)

   {

  perror("tcgetattr");

  return -1;

  }

}激活选项 }CLOCALCREAD分别用于本地连接和接受使能,因此,首先要通过位掩码的方式激活这两个选项。

  newtio.c_cflag  |=  CLOCAL | CREAD;

}调用cfmakeraw()函数可以将终端设置为原始模式,在后面的实例中,采用原始模式进行串口数据通信。

  cfmakeraw(&new_cfg);

}设置波特率 }设置波特率有专门的函数,用户不能直接通过位掩码来操作。设置波特率的主要函数有:cfsetispeed()cfsetospeed()。 }示例:

cfsetispeed(&new_cfg, B115200);

cfsetospeed(&new_cfg, B115200);

}设置字符大小 }与设置波特率不同,设置字符大小并没有现成可用的函数,需要用位掩码。一般首先去除数据位中的位掩码,再重新按要求设置 }示例:

  new_cfg.c_cflag &= ~CSIZE; /* 用数据位掩码清空数据位设置 */

  new_cfg.c_cflag |= CS8;

}设置奇偶校验位 }设置奇偶校验位需要用到termios中的两个成员:c_cflagc_iflag。首先要激活c_cflag中的校验位使能标志PARENB和是否要进行校验,这样会对输出数据产生校验位,而输入数据进行校验检查。同时还要激活c_iflag中的对于输入数据的奇偶校验使能(INPCK)。 }示例: }奇校验

  new_cfg.c_cflag |= (PARODD | PARENB);

  new_cfg.c_iflag |= INPCK;

}偶校验

  new_cfg.c_cflag |= PARENB;

  new_cfg.c_cflag &= ~PARODD;

  new_cfg.c_iflag |= INPCK;

}设置停止位 }设置停止位是通过激活c_cflag中的CSTOPB而实现的。若停止位为一个,则清除CSTOPB,若停止位为两个,则激活CSTOPB。 }示例:

  new_cfg.c_cflag &=  ~CSTOPB;  /* 将停止位设置为一个比特 */

  new_cfg.c_cflag |=  CSTOPB;  /* 将停止位设置为两个比特 */

}设置最少字符和等待时间 }在对接收字符和等待时间没有特别要求的情况下,可以将其设置为0,则在任何情况下read()函数立即返回,此时串口操作会设置为非阻塞方式。 }示例:

  new_cfg.c_cc[VTIME]  = 0;

  new_cfg.c_cc[VMIN] = 0;

}清除串口缓冲 }由于串口在重新设置之后,需要对当前的串口设备进行适当的处理,这时就可调用在中声明的tcdrain()tcflow()tcflush()等函数来处理目前串口缓冲中的数据。 }原型:

  int tcflush(int fd, int queue_selector); /* 用于清空输入/输出缓冲区*/

}  tcflush()函数,对于在缓冲区中的尚未传输的数据,或者收到的但是尚未读取的数据,其处理方法取决于queue_selector的值,它可能的取值有以下几种。

  ·  TCIFLUSH:对接收到而未被读取的数据进行清空处理。

  ·  TCOFLUSH:对尚未传送成功的输出数据进行清空处理。

  ·  TCIOFLUSH:包括前两种功能,即对尚未处理的输入输出数据进行清空处理。

}示例:tcflush(fd, TCIFLUSH);

}激活配置 }在完成全部串口配置之后,要激活刚才的配置并使配置生效。这里用到的函数是tcsetattr(),它的函数原型是: }tcsetattr(int fd, int optional_actions, const struct termios *termios_p);

  其中参数termios_ptermios类型的新配置变量。

  参数optional_actions可能的取值有以下三种:

  ·  TCSANOW:配置的修改立即生效。

  ·  TCSADRAIN:配置的修改在所有写入fd的输出都传输完毕之后生效。

  ·  TCSAFLUSH:所有已接受但未读入的输入都将在修改生效之前被丢弃。

该函数若调用成功则返回0,若失败则返回-1,代码如下所示:

打开串口 使用open函数打开串口 }读写串口 }使用read/write函数读写串口

打开文件: 打开文件有三个标准函数,分别为:fopen()fdopen()freopen()。它们可以以不同的模式打开,但都返回一个指向FILE的指针,该指针指向对应的I/O流。