打印本文 打印本文 关闭窗口 关闭窗口
Linux 串口编程HOWTO 中英文简体对照 beta 版 (续)
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1885  更新时间:2009/4/22 20:45:36  文章录入:mintao  责任编辑:mintao
; 0, TIME serves as a timeout value. The read will be satisfied if a single character is read, or TIME is exceeded (t = TIME *0.1 s). If TIME is exceeded, no character will be returned.

If MIN > 0 and TIME > 0, TIME serves as an inter-character timer. The read will be satisfied if MIN characters are received, or the time between two characters exceeds TIME. The timer is restarted every time a character is received and only becomes active after the first character has been received.

If MIN = 0 and TIME = 0, read will be satisfied immediately. The number of characters currently available, or the number of characters requested will be returned. According to Antonino (see contributions), you could issue a fcntl(fd, F_SETFL, FNDELAY); before reading to get the same result.

By modifying newtio.c_cc[VTIME] and newtio.c_cc[VMIN] all modes described above can be tested.

 

在非标准输入模式中,输入的数据并不组合成行,也不会进行 erase, kill, delete 等输入处理。我们只是用两个参数来控制这种模式的输入行为: c_cc[VTIME] 设定字符输入间隔时间的计时器,而 c_cc[VMIN] 设置满足读取函数的最少字节数。

 

MIN > 0, TIME = 0 读取函数在读到了 MIN 值的字符数后返回。

 

MIN = 0, TIME > 0 TIME 决定了超时值,读取函数在读到一个字节的字符,或者等待读取时间超过 TIME t = TIME * 0.1s)以后返回,也就是说,即使没有从串口中读到数据,读取函数也会在 TIME 时间后返回。

 

MIN > 0, TIME > 0 读取函数会在收到了 MIN 字节的数据后,或者超过 TIME 时间没收到数据后返回。此计时器会在每次收到字符的时候重新计时,也只会在收到第一个字节后才启动。

 

MIN = 0, TIME = 0 读取函数会立即返回。实际读取到的字符数,或者要读到的字符数,会作为返回值返回。根据 Antonino(参考 conditions, 可以使用 fcntl(fd, F_SETFL, FNDELAY), 在读取前获得同样的结果。

 

改变了 nettio.c_cc[VTIME] newtio.c_cc[VMIN], 就可以测试以上的设置了。

 

#include <sys/types.h>     
#include <sys/stat.h>     
#include <fcntl.h>     
#include <termios.h>     
#include <stdio.h>             
#define BAUDRATE B38400     
#define MODEMDEVICE "/dev/ttyS1"     

#define _POSIX_SOURCE 1 /* POSIX compliant source */     

#define FALSE 0     
#define TRUE 1             

volatile int STOP=FALSE;       
    
main() {
 int fd,c, res;  
 struct termios oldtio,newtio;    
 char buf[255];             
 fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ); 
 if (fd <0) {perror(MODEMDEVICE); exit(-1); }   
 
 tcgetattr(fd,&oldtio); /* save current port settings */    
 bzero(&newtio, sizeof(newtio));  
 newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; 
 newtio.c_iflag = IGNPAR;  
 newtio.c_oflag = 0;        
 /* set input mode (non-canonical, no echo,...) */    
 // 设置输入模式为非标准输入   
    newtio.c_lflag = 0;            
    newtio.c_cc[VTIME] = 0;   /* inter-character timer unused */       
                           // 不是用字符间隔计时器  
 newtio.c_cc[VMIN] = 5;    /* blocking read until 5 chars received */
         //收到5个字符数以后,read 函数才返回      
 tcflush(fd, TCIFLUSH);  
 tcsetattr(fd,TCSANOW,&newtio);    
 while (STOP==FALSE) {       /* loop for input */  
  res = read(fd,buf,255);   /* returns after 5 chars have been input */    
  buf[res]=0;               /* so we can printf... */  
  printf(":%s:%d\n", buf, res);
  if (buf[0]==''''z'''') STOP=TRUE;   
    }     
 tcsetattr(fd,TCSANOW,&oldtio); 
}

3.3. Asynchronous Input 异步输入模式

#include <termios.h>   
#include <stdio.h>     
#include <unistd.h>     
#include <fcntl.h>     
#include <sys/signal.h>    
#include <sys/types.h>     
      
#define BAUDRATE B38400     
#define MODEMDEVICE "/dev/ttyS1"     

#define _POSIX_SOURCE 1 /* POSIX compliant source */     
#define FALSE 0     
#define TRUE 1     

volatile int STOP=FALSE;
void signal_handler_IO (int status);   /* definition of signal handler */ 
                                     // 定义信号处理程序
int wait_flag=TRUE;                   /* TRUE while no signal received */    
                                    // TRUE 代表没有受到信号,正在等待中  
main()   {       
 int fd,c, res;  
 struct termios oldtio,newtio; 
 struct sigaction saio;        
 /* definition of signal action */      
 // 定义信号处理的结构
 char buf[255];       
 
 /* open the device to be non-blocking (read will return immediatly) */    
 // 是用非阻塞模式打开设备 read 函数立刻返回,不会阻塞   
    fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);   
    if (fd <0) {perror(MODEMDEVICE); exit(-1); }       
 
 /* install the signal handler before making the device asynchronous */   
    // 在进行设备异步传输前,安装信号处理程序   
    saio.sa_handler = signal_handler_IO;    
 saio.sa_mask = 0; 
 saio.sa_flags = 0;    
 saio.sa_restorer = NULL;   
    sigaction(SIGIO,&saio,NULL);  

 /* allow the process to receive SIGIO */
 // 允许进程接收 SIGIO 信号     
 fcntl(fd, F_SETOWN, getpid());   
    /* Make the file descriptor asynchronous (the manual page says only 
 O_APPEND and O_NONBLOCK, will work with F_SETFL...) */  
 // 设置串口的文件描述符为异步,man上说,只有 O_APPEND 和 O_NONBLOCK 才能使用F_SETFL
 fcntl(fd, F_SETFL, FAS

上一页  [1] [2] [3]  下一页

打印本文 打印本文 关闭窗口 关闭窗口