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

                                                                 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



































  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值