首页 > 范文大全 > 正文

嵌入式Linux下串口应用编程

开篇:润墨网以专业的文秘视角,为您筛选了一篇嵌入式Linux下串口应用编程范文,如需获取更多写作素材,在线客服老师一对一协助。欢迎您的阅读与分享!

【摘要】本文详细介绍了嵌入式linux串口应用编程,详细介绍了串口设置的步骤,可以更好的理解串口的工作原理。

【关键词】linux操作系统;串口设置;串口使用

一、引言

串口是一种常用的接口,常用的串口有RS-232-C接口。S3C2410X内部具有两个独立的UART控制器,每个控制器都可以工作在Interrupt(中断)模式或者DMA(直接存储访问)模式。同时,每个UART均具有16字节的FIFO(先入先出寄存器),支持的最高波特率可达到230.4kb/s。UART的操作主要可分为以下几个部分:数据发送、数据接收、产生中断、设置波特率、Loopback模式、红外模式以及硬软流控模式。在linux中,所有的设备文件一般都位于“/dev”下,其中串口1和串口2对应的设备名依次为“/dev/ttyS0”和“/dev/ttyS1”,而且USB转串口的设备名通常为“/dev/ttyUSB0”和“/dev/ttyUSB1”,下面就详细讲解串口应用编程。

二、串口设置详解

读写串口设备时需要设置串口的波特率、校验码、停止位等等,对于应用程序开发来说,对于串口设备的设置主要通过如下的结构体完成的:

#include

struct termios

{

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

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

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

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

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

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

speed_t cispeed; /*输入速度*/

speed_t c_ospeed; /*输出速度*/

};

termios是POSIX定义的标准接口,是对虚拟终端、串口等终端类设备的一种抽象。终端有规范模式、非规范模式和原始模式这三种工作模式。上述结构体成员的c_lflag的ICANNON标志位用于定义终端的工作模式类型,如果设置这一位说明终端工作与规范模式下,如果过清除该标志表明终端工作在非规范模式下。默认情况是工作在规范模式下。

在规范模式下,对输入是通过行的方式进行处理的。在输入行结束符(包括回车符、EOF等)之前,系统调用read()函数是读不到输入的数据。在非规范模式下,输入全部都是即时生效的,既不需要额外输入行结束符,也不需要进行行编辑。在该模式下,用户可以通过对参数MIN(c_cc[VMIN])和TIME(c_cc[VTIME])的设置来决定调用read()函数的方式。下面是4中不同的设置情况。

(1)MIN 以及TIME全部为0的情况下:read()函数立即返回。若有可读的数据时,则读取数据并返回被读取的字节数,否则读取失败并返回0。

(2)MIN大于0,TIME为0:read()函数会等待到有MIN个字节可以被读取 ,否则一直处于阻塞状态。

(3)MIN为0,而TIME>0:只要满足两种情形下:a、存在数据可读;b、阻塞TIME的十分之一秒,read函数就会返回,其中返回值为读取到的字节数。如果在有数据可读前超时,则read()函数返回值为0。

(4)MIN和TIME全都大于0:只有满足如下两种情形之一时,read()函数才会返回 :缓存区中有MIN个字节,或者在两个字符之间超时TIME个十分之一秒。

从严格意义上来讲,原始模式是一种特殊的非规范模式。在原始模式下,对输入数据的处理方式是按字节为单位,并且终端是不可回显的。通过调用cfmakeraw()函数就可以将把终端的该工作模式设置为原始模式。

三、简单的串口设置详解流程

下面以指纹识别系统为例介绍下串口的操作流程。

本系统中,对串口的操作和使用可以分为如下几个部分:串口的初始化(包括串口设备的打开、串口设备属性的设置)、串口数据单字节读取、串口数据的多字节读取、串口数据的单字节写入、串口数据的多字节写入、串口设备的关闭。

1.串口设备的初始化过程

(1)打开串口

在Linux系统中,对设备的操作如同普通文件一样,在本系统中打开串口设备的代码如下所示:

#define DEVICENAME0 "/dev/s3c2410_serial1"

fd=open(DEVICENAME0,O_RDWR| O_NONBLOCK);

DEVICENAME0表示要打开的串口设备名称,这个和特定的设备相关,在Linux桌面系统上一般为/dev/ttyS*,而在嵌入式系统中,这个根据UART驱动对的板级信息不同而不同,没有统一的规定,在本系统中是/dev/s3c2410_serial1。

O_RDWR表示以读写方式打开串口设备

O_NONBLOCK标志代表将以后的读写操作全以非阻塞模式。注意,这里必须选择非阻塞方式打开,否则会导致程序运行出错。

为了读写串口设备,需要恢复串口读写方式为阻塞状态,以用于等待数据,可用fcntl()函数实现

if(fcntl(fd,F_SETFL,0)

{

printf(“fcntl F_SETFL\n”);

return 1;

}

(2)配置串口设备的属性

在打开串口设备之后,需要对串口设备的属性进行配置。主要包括设置波特率、设置字符大小、设置奇偶校验位、设置停止位以及设置最小字符和等待时间等。

设置串口设备之前,需要先获取当前串口设备的属性,这是因为结构体termios的成员都是和特定寄存器对应的,如果不先获取以前的状态,可能将寄存器中的值全部覆盖,从而导致通信失败,并且在操作完串口设备以后,需要将串口设备的属性恢复到以前的值。获取当前串口设备属性的过程如下:

tcgetattr(fd,&new_cfg); //从fd代表的串口设备中获取当前的状态并将其保存在new_cfg中。

接下来是将串口设备设置为原始模式,在本系统中需要使用原始模式进行通信

cfmakeraw(&new_cfg);

将串口通信的字符大小设为8个字符

new_cfg.c_cflag &= ~CSIZE;

new_cfg.c_cflag |= CS8;

设置波特率

cfsetispeed(&new_cfg,BARDRATE); //设置输入波特率

cfsetospeed(&new_cfg,BARDRATE); //设置输出波特率

设置奇偶校验位,不适用奇偶校验

new_cfg.c_cflag &= ~PARENB;

new_cfg.c_iflag &= ~INPCK;

设置停止位,使用一个byte

new_cfg.c_cflag &= ~CSTOPB;

设置读取字符大小以及等待时间

new_cfg.c_cc[VTIME]=50; //两个字符之间等待超过5s返回

new_cfg.c_cc[VMIN]=1; //最少读取一个字符

清除串口缓存

该操作是必不可少的,否则会导致串口通信失败。

tcflush(fd,TCIOFLUSH);

其中TCIOFLUSH表示清空串口的缓存。

接下来需要激活配置

if((tcsetattr(fd,TCSANOW,&new_cfg))!=0)

{

// perror("tcsetattr");

return 1;

}

串口初始化、串口属性的设置的流程图,如图1所示。

2.串口的读写和关闭

利用串口通信的过程就是对串口设备的读写过程,只需要利用read()函数和write()函数对打开的串口设备的文件描述符操作即可。在操作完串口退出程序时,需要将打开的串口关闭,这个过程和关闭普通的文件一样,调用close()函数即可完成。

四、结束语

本文以指纹识别系统的串口编程为例,阐述了Linux系统下,串口编程的具体设置方法,在本文的基础上再添加上层软件的设计即可完成一个指纹识别系统。

参考文献

[1]于明,范书瑞,曾祥烨.ARM9嵌入式系统设计与开发教程[M].北京:电子工业出版社,2006.

[2]冷玉林.基于ARM的嵌入式Linux系统构建与应用研究[D].重庆:重庆大学硕士学位论文,2010.

[3]华清远见嵌入式培训中心.嵌入式Linux应用程序开发详解[M].北京:人民邮电出版社,2009.

[4]韦东山.嵌入式Linux应用开发完全手册[M].北京:人民邮电出版社,2008.4.

[5]鸟哥著,王世江.鸟哥的Linux私房菜基础学习篇(第三版)[M].北京:人民邮电出版社,2010.

作者简介:

孙甲凯,中北大学信息与通信工程学院硕士研究生,主要从事嵌入式系统开发。

韩慧莲,中北大学信息与通信工程学院教授,硕士生导师。

范敏,中北大学信息与通信工程学院硕士研究生,主要从事信号与信息处理。

刘寅,中北大学信息与通信工程学院硕士研究生,主要从事电气控制与自动测试。