在编写应用程序的时候,需要将前面提到的串口参数如波特率、数据位、奇偶校验位、停止位等设置好,通讯双方才能在约定好的参数下进行通讯。在哪里设置参数,通过什么设置参数,还有如何设置这些参数呢?下面分别进行介绍。 在哪里设置串口参数--termios结构体 POSIX规范中定义了标准接口-termios结构体,在linux中用termios来设置串口参数,如前面提到的波特率、停止位、校验位、数据位等。它的详细描述在中的。 查看termios.h: 可以看到termios结构体的定义: 在termios结构体中的四个标志控制了输入输出的四个不同部分。输入模式标志c_iflag决定如何解释和处理接收的字符;输出模式标志c_oflag决定如何解释和处理发送到tty设备的字符;控制模式c_cflag标志决定设备的一系列协议特征,这一标志只对物理设备有效;本地模式标志c_lflag决定字符在输出前如何收集和处理。 而c_cc[NCCS]数组包含了终端的所有特殊字符,可以修改特殊字符对应的键值;c_ispeed和c_ospeed则记录串口的输入和输出波特率(input speed和output speed)。 下面详细介绍各个结构体成员,列出的各个成员选项较多,大家不必每个都看,用到什么查询即可。结构体成员也只需重点关注输入模式c_iflag、控制模式c_cflag和传输速度c_ispeed、c_ospeed。 通过什么设置参数--结构体成员 c_iflag标志常量:Input mode(输入模式) 输入模式可以在输入值传给程序之前控制其处理的方式。其中输入值可能是由串口或键盘的终端驱动程序所接收到的字符。 c_iflag选项值表: 使用软件流控制是启用IXON、IXOFF和IXANY选项: 相反,要禁用软件流控,则禁止上面的选项: c_oflag标志常量:Output mode(输出模式) 输出模式主要负责控制输出字符的处理方式,即输出字符在传送到串口或显示器之前是如何被程序来处理。 输出模式是利用termios结构的c_oflag的标志来加以控制,其定义的方式皆以OR来加以组合。 c_oflag选项值表: 启用输出处理需要在c_oflag成员中启用OPOST选项: 使用原始输出,就是禁用输出处理,使数据能不经过处理、过滤的完整输出到串口。当OPOST被禁止,c_oflag其他选项也被忽略: c_cflag标志常量:Control mode(控制模式) 控制模式主要用于控制终端设备的硬件设置。利用termios结构的c_cflag的标志来加以控制。控制模式用在串口线连接到数据设备,也可以用在与终端设备的通讯。 c_cflag选项值表: c_lflag标志常量:Local mode(局部模式) Local mode主要用来控制终端设备不同的特色。利用termios结构里的c_lflag的标志来设定局部模式。 在表中有两个比较重要的标志: (1)ECHO:它可以让你阻止键入字符的回应。 (2)ICANON(正规模式)标志,它可以对所接收的字符在两种不同的终端设备模式之间来回切换。 c_lflag选项值表: 规范模式是行处理的。调用read读串口数据时,每次返回一样数据。如果选择规范模式需要启用ICANON、ECHO和ECHOE选项: 当串口设备作为用户终端时,通常要把串口设备配置成规范模式。 在原始模式下,串口输入数据是不经过处理的,在串口接收的数据被完整保留。要使串口设备工作在原始模式,需要关闭ICANON、ECHO、ECHOE和ISIG选项: c_cc数组:特殊控制字符 可提供使用者设定一些特殊的功能,如Ctrl+C的字符组合。特殊控制字符主要是利用termios结构里c_cc的数组成员来做设定。c_cc数组主要用于正规与非正规两种环境,但要注意的是正规与非正规不可混为一谈。其定义了特殊的控制字符。符号下标(初始值)和意义为: c_cflag选项值表: 特别说明: 这些符号下标值是互不相同的,除了 VtiME,VMIN 的值可能分别与 VEOL,VEOF 相同。 (在 非正规模式下,特殊字符的含义更改为延时含义。MIN 表示应当被读入的最小字符数。TIME 是以十分之一秒为单位的计时器。如果同时设置了它们,read 将等待直到至少读入一个字符,一旦读入 MIN 个字符或者从上次读入字符开始经过了 TIME 时间就立即返回。如果只设置了 MIN,read 在读入 MIN 个字符之前不会返回。如果只设置了 TIME,read 将在至少读入一个字符,或者计时器超时的时候立即返回。如果都没有设置,read 将立即返回,只给出当前准备好的字符。)MIN与TIME组合有以下四种: (1)MIN = 0 , TIME =0; 有READ立即回传;否则传回 0 ,不读取任何字符。 (2)MIN = 0 , TIME >0; READ传回读到的字符,或在十分之一秒后传回TIME;若来不及读到任何字符,则传回0。 (3)MIN > 0 , TIME =0; READ 会等待,直到MIN字符可读。 (4)MIN > 0 , TIME > 0; 每一格字符之间计时器即会被启动,READ会在读到MIN字符,传回值或TIME的字符计时(1/10秒)超过时将值传回。 c_ispeed和c_ospeed:记录串口的输入和输出波特率(input speed 和 output speed) 通过如下命令查看可用波特率: 如何设置串口参数--相关函数 前面知道了需要设置哪些参数,但如何获取当前配置的参数,如何把想要的配置写入使配置生效以及其他可能用到的串口操作具体怎么实现,下面介绍实现这些操作的函数。 tcgetattr() (1)原型 (2)功能 取得文件描述符(fd)初始值,并把其值赋给temios_p;函数可以从后台进程中调用;但是,终端属性可能被后来的前台进程所改变。 tcsetattr() (1)原型 (2)功能 设置与终端相关的参数 (除非需要底层支持却无法满足),使用termios_p引用的termios结构。optional_actions(tcsetattr函数的第二个参数)指定了什么时候改变会起作用: TCSANOW:改变立即发生; TCSADRAIN:改变在所有写入 fd 的输出都被传输后生效。这个函数应当用于修改影响输出的参数时使用。(当前输出完成时将值改变); TCSAFLUSH :改变在所有写入 fd 引用的对象的输出都被传输后生效,所有已接受但未读入的输入都在改变发生前丢弃(同TCSADRAIN,但会舍弃当前所有值); tcsendbreak() 传送连续的0值比特流,持续一段时间,如果终端使用异步串行数据传输的话。如果 duration是0,它至少传输0.25秒,不会超过0.5秒。如果duration非零,它发送的时间长度由实现定义。 如果终端并非使用异步串行数据传输,tcsendbreak()什么都不做,成功返回0,错误返回-1,并且为errno置值来指示错误; tcdrain() 等待直到所有写入fd引用的对象的输出都被传输。成功返回0,错误返回-1,并且为errno置值来指示错误; tcflush() 丢弃要写入引用的对象,但是尚未传输的数据,或者收到但是尚未读取的数据,成功返回0,错误返回-1,并且为errno置值来指示错误;取决于queue_selector的值: TCIFLUSH :刷新收到的数据但是不读; TCOFLUSH :刷新写入的数据但是不传送; TCIOFLUSH :同时刷新收到的数据但是不读,并且刷新写入的数据但是不传送; tcflow() 挂起 fd 引用的对象上的数据传输或接收成功返回0,错误返回-1,并且为errno置值来指示错误;,取决于 action 的值: TCOOFF :挂起输出; TCOON :重新开始被挂起的输出; TCIOFF :发送一个 STOP 字符,停止终端设备向系统传送数据; TCION :发送一个 START 字符,使终端设备向系统传输数据; 打开一个终端设备时的默认设置是输入和输出都没有挂起。 波特率函数 被用来获取和设置 termios 结构中,输入和输出波特率的值。新值不会马上生效,直到成功调用了 tcsetattr() 函数。 设置速度为 B0 使得 modem "挂机"。与 B38400 相应的实际比特率可以用 setserial(8) 调整。 输入和输出波特率被保存于 termios 结构中。 cfmakeraw 设置终端属性如下: (1)termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); (2)termios_p->c_oflag &= ~OPOST; (3)termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); (4)termios_p->c_cflag &= ~(CSIZE|PARENB); (5)termios_p->c_cflag |= CS8; ①cfgetospeed() 返回值为termios_p 指向的 termios 结构中存储的输出波特率 ; ②cfsetospeed() 设置 termios_p 指向的 termios 结构中存储的输出波特率为 speed。取值必须是以下常量之一: ③cfgetispeed() 返回值为termios 结构中存储的输入波特率; ④cfsetispeed() 设置 termios 结构中存储的输入波特率为 speed。如果输入波特率被设为0,实际输入波特率将等于输出波特率;
|