您的位置:首页 > 运维架构 > Linux

linux 串口初始化 基于FL2440开发板

2016-03-10 17:12 561 查看
linux 串口初始化

基于FL2440开发板

串口设置说明:数据位8位,停止位1位,没有校验位,串口输入输出波特率为9600.

一、打开串口

1. 在linux系统下,串口的设备名为ttyS0,ttyS1,ttyS3,位于dev目录下。

2. 打开文件的模式采用O_RDWR | O_NOCTTY | O_NONBLOCK 。

O_NOCTTY 当打开文件为tty(终端设备)时,不将此设备分配作为进程的控制终端,

O_NONBLOCK 当打开的设备是FIFO、一个块特殊文件或一个字符特殊文件,设置设备的打开和后续 I/O操作设置为非阻塞方式。

二、设置串口

1. 串口的配置是通过struct termios进行配置的

struct termios

{

tcflag_t c_iflag; //input flags

tcflag_t c_oflag; //output flags

tcflag_t c_cflag; //control flags

tcflag_t c_lflag; //local flags

cc_t c_cc[NCCS]; //control characters

};

2.串口设置函数

tcgetattr 取属性(termios结构)

tcsetattr 设置属性(termios结构)

cfgetispeed 得到输入速度

cfgetospeed 得到输出速度

cfsetispeed 设置输入速度

cfsetospeed 设置输出速度

tcdrain 等待所有输出都被传输

tcflow 挂起传输或接收

tcflush 刷清未决输入和/或输出

tcsendbreak 送BREAK字符

tcgetpgrp 得到前台进程组ID

tcsetpgrp 设置前台进程组ID

三、配置串口

1. struct termios new_termios;

2. 设置串口数据位

new_termios.c_cflag &= ~CSIZE; //字符大小屏蔽,以便设置数据位大小

new_termios.c_cflag |= CS8; //设置数据位为8位

3. 设置停止位

new_termios.c_cflag &= ~CSTOPB; //设置一位停止位

new_termios.c_cflag |= CSTOPB; //设置两位停止位

4. 设置奇偶校验位

设置奇校验:

newtio.c_cflag |= PARENB; //进行奇偶校验

newtio.c_cflag |= PARODD; //设置为奇校验

newtio.c_iflag |= (INPCK | ISTRIP);//打开输入校验,剥除数据的第8位

设置偶校验:

newtio.c_iflag |= (INPCK|ISTRIP);

newtio.c_cflag |= PARENB;

newtio.c_cflag |= ~PARODD; //设置为偶校验

没有奇偶校验

newtio.c_cflag &= ~PARENB;

5. 设置最少字符和等待时间

new_termios.c_cc[VTIME] = 0;

new_termios.c_cc[VMIN] = 0;

6. 硬件流控设置

new_termios.c_cflag &= ~(CRTSCTS); //关闭硬件流控制

options.c_cflag |= CNEW_RTSCTS;//打开硬件流控

7. 本地设置成员变量c_lflag可以使用的常量
FlagDescription
ISIG当接收到字符INTR,QUIT,SUSP或DSUSP时,产生相应的信号
XCASE(不属于POSIX;LINUX下不支持)如果同时设置了ICANON,终端只有大写。输入被转换为小写,除了以\前缀的字符。输出时,大写字符被前缀\,小写字符被转换成大写
ECHO回显输入字符
ECHOE如果同时设置了ICANON,字符ERASE擦除前一个输入字符,WERASE擦除前一个词
ECHOK如果同时设置了ICANON,字符KILL删除当前行
ECHONL如果同时设置了ICANON,回显字符NL,即使没有设置ECHO
ECHOCTL(不属于POSIX)如果同时设置了ECHO,除了TAB,NL,START和STOP之外的ASCII控制信号被回显为x,这里X是比控制信号大0x40的ASCII码。例如字符0x08(BS)被回显为H
ECHOPRT(不属于POSIX)如果同时设置了ICANON和IECHO,字符在删除的同时被打印
ECHOKE(不属于POSIX)如果同时设置了ICANON,回显KILL时将删除一行中的每个字符,如同指定了ECHOE和ECHORPT一样
DEFECHO(不属于POSIX)只在一个进程读的时候回显
FLUSHO(不属于POSIX;LINUX不支持)输出被刷新。这个标志可以通过键入字符DISCARD来打开和关闭
NOFLSH禁止产生SIGINT,SIGQUIT和SIGSUSP信号时刷新输入和输出队列
TOSTOP向试图写控制终端的后台进程组发送SIGTTOU信号
PENDIN(不属于POSIX;LINUX不支持)在读入一个字符时,输入队列中的所有字符被重新输出。(bash用他来处理typeahead)
IEXTEN启用实现自定义的输入处理。这个标志必须与ICANON同时使用,才能解释特殊字符EOL2,LNEXT,REPRINT和WERASE,IUCLC标志才有效
选择经典输入 经典输入是以面向行设计的。在经典输入模式中输入字符会被放入一个缓冲之中, 这样可以以与用户交互的方式编辑缓冲的内容,直到收到CR(carriage return)或者LF(line feed)字符。 选择使用经典输入模式的时候,你通常需要选择ICANON,ECHO和ECHOE选项:

new_termios.c_lflag |= (ICANON | ECHO | ECHOE);


选择原始输入 原始输入根本不会被处理。输入字符只是被原封不动的接收。一般情况中,如果要使用原始输入模式,程序中需要去掉ICANON,ECHO,ECHOE和ISIG选项:

new_termios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

8.输入模式

FlagDescription
IGNBRK忽略输入中的BREAK状态
BRKINT如果设置了IGNBRK,将忽略BREAK。如果没有设置,但是设置了 BRKINT,那么BREAK将使得输入和输出队列被刷新,如果终端是一个前台进程组的控制终端,这个进程组中所有进程将收到SIGINT信号。如果既未设置IGNBRK也未设置BRKINT,BREAK将视为NUL同义字符,除非设置了PARMRK,这种情况下被视为序列\377
IGNPAR忽略桢错误和奇偶校验错误
PARMRK如果没有设置IGNPAR,在有奇偶校验错误或者桢错误的字符前插入\377。如果既没有设置IGNPAR也没有设置PARMRK,将所有奇偶校验错误或者桢错误的字符视为
INPCK启用输入奇偶校验检测
ISTRIP去掉第八位
INLCR将输入的NL翻译为CR
IGNCR忽略输入中的回车
ICRNL将输入中的回车翻译为新行字符(除非设置了IGNCR)
IUCLC(不属于POSIX)将输入中的大写字母映射为小写字母
IXON启用输出的XON/XOFF流控制
IXANY(不属于POSIX。1;XSI)允许任何字符来重新开始输出
IXOFF启用输入的XON/XOFF流控制
IMAXBEL(不属于POSIX)当输入队列满时响铃。LINUX没有实现该位,总是将其视为已设置
new_termios.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);

9. 输出模式标志 c_oflag的常量

IGNBRK忽略输入中的BREAK状态
BRKINT如果设置了IGNBRK,将忽略BREAK。如果没有设置,但是设置了 BRKINT,那么BREAK将使得输入和输出队列被刷新,如果终端是一个前台进程组的控制终端,这个进程组中所有进程将收到SIGINT信号。如果既未设置IGNBRK也未设置BRKINT,BREAK将视为NUL同义字符,除非设置了PARMRK,这种情况下被视为序列\377
IGNPAR忽略桢错误和奇偶校验错误
PARMRK如果没有设置IGNPAR,在有奇偶校验错误或者桢错误的字符前插入\377。如果既没有设置IGNPAR也没有设置PARMRK,将所有奇偶校验错误或者桢错误的字符视为
INPCK启用输入奇偶校验检测
ISTRIP去掉第八位
INLCR将输入的NL翻译为CR
IGNCR忽略输入中的回车
ICRNL将输入中的回车翻译为新行字符(除非设置了IGNCR)
IUCLC(不属于POSIX)将输入中的大写字母映射为小写字母
IXON启用输出的XON/XOFF流控制
IXANY(不属于POSIX。1;XSI)允许任何字符来重新开始输出
IXOFF启用输入的XON/XOFF流控制
IMAXBEL(不属于POSIX)当输入队列满时响铃。LINUX没有实现该位,总是将其视为已设置
10. 控制模式标志 c_cflag常量

FlagDescription
CBAUD(不属于POSIX)波特率掩码(4+1位)
CBAUDEX(不属于POSIX)扩展的波特率掩码(1位),包含在CBAUD中
CSIZE字符长度掩码。取值为CS5,CS6,CS7或CS8
CSTOPB设置两个停止位
CREAD打开接受者
PARENB允许输出产生奇偶信息以及输入的奇偶校验
PARODD输入和输出是奇校验
HUPCL在最后一个进程关闭设备后,降低MODEM控制线(挂断)
CLOCAL忽略MODEM控制线
LOBLK(不属于POSIX)从非当前SHELL层阻塞输出(用于sh1)
CIBAUD(不属于POSIX)输入速度的掩码。CIBAUD各位的值与CBAUD各位相同,左移了IBSHIFT位
CRTSCTS(不属于POSIX)启用RTS/CTS(硬件)控制流
11.设置串口输入输出波特率

cfsetispeed(&new_termios, B9600);

cfsetospeed(&new_termios,B9600);

12.设置串口,使配置生效

tcsetattr(fd, TCSANOW, &new_termios); //成功返回0

四、串口设置函数

#include <stdio.h>

#include <errno.h>

#include <stdlib.h>

#include <unistd.h>

#include <fcntl.h>

#include <termios.h>

#include <string.h>

#include "at.h"

#define SERIAL "/dev/ttyS1"

#define MODE O_RDWR | O_NOCTTY | O_NONBLOCK

int init_serial()

{

int retval;

int fd;

fd=open(SERIAL,MODE);

if(fd<0)

{

printf("open file error,%s\n",strerror(errno));

return -1;

}

else

{

printf("open file successful\n");

}

struct termios old_cfg, new_cfg;

if(tcflush(fd, TCIOFLUSH)<0)

{

retval=-1;

goto error;

}

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

{

retval = -2; // Failed to get Com settings

goto error;

}

memset(&new_cfg, 0, sizeof(new_cfg));

new_cfg.c_cflag &= ~CSIZE;

new_cfg.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

new_cfg.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);

new_cfg.c_oflag &= ~(OPOST);

new_cfg.c_cflag |= CS8;

new_cfg.c_cflag &= ~PARENB;

new_cfg.c_cflag &= ~CSTOPB;

new_cfg.c_cflag &= ~(CRTSCTS);

new_cfg.c_iflag &= ~(IXON | IXOFF);

cfsetispeed(&new_cfg, B9600);

cfsetospeed(&new_cfg,B9600);

new_cfg.c_cc[VMIN] = 0;

new_cfg.c_cc[VTIME] = 0;

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

{

retval = -3; // Failed to set device com port settings

goto error;

}

printf("init successful\n");

return 0;

error:

printf("error\n");

return retval;

}

参考文章:
http://blog.chinaunix.net/uid-28458801-id-4243864.html http://www.cnblogs.com/wblyuyang/archive/2011/11/21/2257544.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: