嵌入式linux串口编程

 

串口的设置主要是设置struct termios结构体

#include<termios>

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 c_ispeed;//输入速度

 speed_t c_ospeed;//输出速度

 

};

中端有三种工作模式:c_lflag:规范模式(ICANNON)非规范模式(清除ICANNON)原始模式(调用函数cfmakeraw())

在规范模式下,所有的输入是基于行进行处理。在用户输入一个行结束符(回车符,EOF等)之前,系统调用read()函数读不到用户输入的任何字符。除了EOF之外的行结束符(回车符等)与普通字符一样会被read()函数读到缓冲区中。在规范模式中,行编程是可行的,而且一次调用read()函数最多只能读到一行的数据。如果在read()函数中北请求读取的数据字节数小于当前行可读取的字节数,则read()函数只会读取被请求的字节数,剩下的字节下次在被读取。

在非规范模式下,所有的输入是即时有效的,不需要用户另外输入行结束符,而且不可进行行编程。在非规范模式下,对参数MIN(c_cc[VMIN])和TIME(c_cc[VTIME])的设置决定read(0函数的调用方式。设置可用有4中不同的情况。

MIN=0和TIME=0:read()函数立即返回。若有可读数据,则读取数据并返回被读取的字节数,否则读取失败并返回0.

MIN>0和TIME=0:read()函数会被阻塞直到MIN个字节数据可被读取。

MIN=0和TIME>0:只要有数据或者经过TIME个十分之一秒得时间,read()函数则立即返回,返回值为被读取的字节数。如果超时并且未数据,则read()函数返回0.

MIN>0和TIME>0:当有MIN个字节可读或着两个输入字符之间的时间间隔超过TIME个十分之一秒时,read()函数才返回。因为在输入第一个字符之后系统才会启动定时器,所以在这种情况下,read()函数至少读取一个字节之后才返回。

按照严格的意义来讲,原始模式是一种特殊的非规范模式。在原始模式下,所有的输入数据以字节为单位被处理。在这个模式下,终端是不可回显的,而且所有特定的终端输入输出控制处理不可用。通过嗲用cfmakeraw()函数可以将终端设置为原始模式。

设置串口属性的基本流程

1保存原先传奇偶配置tcgetattr(fd,&old_cfg)

2激活选项 CLOCAL和CREAD分别用于本地连接和接收使能。new_cfg.c_cflag |= CLOCAL | CREAD;

3设置波特率 cfsetispeed(&new_cfg,B115200) cfsetospeed(&new_cfg,B115200)

4设置字符大小 new_cfg.c_cflag &= ~CSIZE;new_cfg.c_cflag |=CS8;

5设置奇偶校验位

6设置停止位new_cfg.c_cflag &= ~CSTOPB; new_cfg.c_cflag |=CSTOPB;

7设置最少字符和等待时间

8清除串口缓冲

9激活配置tcsetattr(int fd,int optional_actions,const struct termios *termios_p)

optional_actions 可能的取值有3种:

TCSANOW:配置的修改立即生效。

TCSADRAIN:配置的修改在所有写入fd的输出都传输完毕之后生效

TCSAFLUSH:所有已接收但未读入的输入都将在修改生效之前被丢弃。

下面是串口配置的完整函数:

int  set_con_config(int fd,int baud_rate,int data_bits,cha parity,int stop_bits)

{

   strut termios new_cfg,old_cfg;

   int speed;

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

   {

    perror("tcgetattr");

    return -1;

    }

  

    new_cfg= old_cfg;

    cfmakeraw(&new_cfg);

    new_cfg.c_cflag &=~CSSIZE;

    switch(baud_rate)

   {

      case 2400:

       {

      speed=B2400;

       }

      case 2400:

       {

      speed=B2400;

       }

....

 

 

 

 

    }

 

}

 

串口使用:

1打开串口

fd= open("/dev/ttys0",ORDWR|O_NOCTTY|O_NDELAY);

O_NOCTTY 标志用于通知linux系统,改参数不会是打开的文件成为这个进程的控制终端。如果没有指定这个标志,那么任何一个输入都将会影响用户的进程。

O_NDELAY 标志通知linux系统,这个程序不关心DCD信号线所处的状态(端口的另一端是否激活或者停止)。如果用户指定了这个标志,则就能成将会一直处于睡眠状态,直到DCD信号线被激活。

 

设置串口的状态为阻塞状态,用于等待串口数据的读入,可用fcntl()

fcntl(fd,F_SETFL,0);

 

测试打开文件描述符是否连接到一个终端设备,以进一步确认串口是否正确打开

isatty(STDIN_FILENO);

 

2读写串口

write(fd,buff,strlen(buff));

read(fd,buff,BUFF_SIZE);

你可能感兴趣的:(编程,c,linux,struct,嵌入式,终端)