文件I/O编程之: 嵌入式Linux串口应用编程
6.4嵌入式Linux串口应用编程
6.4.1串口概述
常见的数据通信的基本方式可分为并行通信与串行通信两种。
n 并行通信是指利用多条数据传输线将一个字数据的各比特位同时传送。它的特点是传输速度快,适用于传输距离短且传输速度较高的通信。
n 串行通信是指利用一条传输线将数据以比特位为单位顺序传送。特点是通信线路简单,利用简单的线缆就可实现通信,降低成本,适用于传输距离长且传输速度较慢的通信。
串口是计算机一种常用的接口,常用的串口有RS-232-C接口。它是于1970年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通信的标准,它的全称是“数据终端设备(DTE)和数据通信设备(DCE)之间串行二进制数据交换接口技术标准”。该标准规定采用一个DB25芯引脚的连接器或9芯引脚的连接器,其中25芯引脚的连接器如图6.3所示。
图6.325引脚串行接口图
S3C2410X内部具有两个独立的UART控制器,每个控制器都可以工作在Interrupt(中断)模式或者DMA(直接存储访问)模式。同时,每个UART均具有16字节的FIFO(先入先出寄存器),支持的最高波特率可达到230.4Kbps。UART的操作主要可分为以下几个部分:数据发送、数据接收、产生中断、设置波特率、Loopback模式、红外模式以及硬软流控模式。
串口参数的配置读者在配置超级终端和minicom时也已经接触过,一般包括波特率、起始位比特数、数据位比特数、停止位比特数和流控模式。在此,可以将其配置为波特率115200、起始位1b、数据位8b、停止位1b和无流控模式。
在Linux中,所有的设备文件一般都位于“/dev”下,其中串口1和串口2对应的设备名依次为“/dev/ttyS0”和“/dev/ttyS1”,而且USB转串口的设备名通常为“/dev/ttyUSB0”和“/dev/ttyUSB1”(因版本不同该设备名会有所不同),可以查看在“/dev”下的文件以确认。在本章中已经提到过,在Linux下对设备的操作方法与对文件的操作方法是一样的,因此,对串口的读写就可以使用简单的read()、write()函数来完成,所不同的只是需要对串口的其他参数另做配置,下面就来详细讲解串口应用开发的步骤。
6.4.2串口设置详解
串口的设置主要是设置structtermios结构体的各成员值,如下所示:
#includetermios.h>
structtermios
{
unsignedshortc_iflag;/*输入模式标志*/
unsignedshortc_oflag;/*输出模式标志*/
unsignedshortc_cflag;/*控制模式标志*/
unsignedshortc_lflag;/*本地模式标志*/
unsignedcharc_line;/*线路规程*/
unsignedcharc_cc[NCC];/*控制特性*/
speed_tc_ispeed;/*输入速度*/
speed_tc_ospeed;/*输出速度*/
};
termios是在POSIX规范中定义的标准接口,表示终端设备(包括虚拟终端、串口等)。口是一种终端设备,一般通过终端编程接口对其进行配置和控制。在具体讲解串口相关编程之前,先了解一下终端相关知识。
终端有3种工作模式,分别为规范模式(canonicalmode)、非规范模式(non-canonicalmode)和原始模式(rawmode)。
通过在termios结构的c_lflag中设置ICANNON标志来定义终端是以规范模式(设置ICANNON标志)还是以非规范模式(清除ICANNON标志)工作,默认情况为规范模式。
在规范模式下,所有的输入是基于行进行处理。在用户输入一个行结束符(回车符、EOF等)之前,系统调用read()函数读不到用户输入的任何字符。除了EOF之外的行结束符(回车符等)与普通字符一样会被read()函数读取到缓冲区之中。在规范模式中,行编辑是可行的,而且一次调用read()函数最多只能读取一行数据。如果在read()函数中被请求读取的数据字节数小于当前行可读取的字节数,则read()函数只会读取被请求的字节数,剩下的字节下次再被读取。
在非规范模式下,所有的输入是即时有效的,不需要用户另外输入行结束符,而且不可进行行编辑。在非规范模式下,对参数MIN(c_cc[VMIN])和TIME(c_cc[VTIME])的设置决定read()函数的调用方式。设置可以有4种不同的情况。
n MIN=0和TIME=0:read()函数立即返回。若有可读数据,则读取数据并返回被读取的字节数,否则读取失败并返回0。
n MIN>0和TIME=0:read()函数会被阻塞直到MIN个字节数据可被读取。
n MIN=0和TIME>0:只要有数据可读或者经过TIME个十分之一秒的时间,read()函数则立即返回,返回值为被读取的字节数。如果超时并且未读到数据,则read()函数返回0。
n MIN>0和TIME>0:当有MIN个字节可读或者两个输入字符之间的时间间隔超过TIME个十分之一秒时,read()函数才返回。因为在输入第一个字符之后系统才会启动定时器,所以在这种情况下,read()函数至少读取一个字节之后才返回。
按照严格意义来讲,原始模式是一种特殊的非规范模式。在原始模式下,所有的输入数据以字节为单位被处理。在这个模式下,终端是不可回显的,而且所有特定的终端输入/输出控制处理不可用。通过调用cfmakeraw()函数可以将终端设置为原始模式,而且该函数通过以下代码可以得到实现。
termios_p->c_iflag=~(IGNBRK|BRKINT|PARMRK|ISTRIP
|INLCR|IGNCR|ICRNL|IXON);
termios_p->c_oflag=~OPOST;
termios_p->c_lflag=~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
termios_p->c_cflag=~(CSIZE|PARENB);
termios_p->c_cflag|=CS8;
下面讲解设置串口的基本方法。设置串口中最基本的包括波特率设置,校验位和停止位设置。在这个结构中最为重要的是c_cflag,通过对它的赋值,用户可以设置波特率、字符大小、数据位、停止位、奇偶校验位和硬软流控等。另外c_iflag和c_cc也是比较常用的标志。在此主要对这3个成员进行详细说明。c_cflag支持的常量名称如表6.11所示。其中设置波特率宏名为相应的波特率数值前加上‘B’,由于数值较多,本表没有全部列出。
linux操作系统文章专题:linux操作系统详解(linux不再难懂)linux相关文章:linux教程
评论