LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2179|回复: 4

求助,如何从串口读取数据

[复制链接]
发表于 2004-5-18 13:53:09 | 显示全部楼层 |阅读模式
我想从串口读取一行字符串,如何实现?
发表于 2004-5-18 22:11:45 | 显示全部楼层
摘自perldoc perlfaq8。
我也是在学习试用PERL,希望下面的对你有用。


       How do I read and write the serial port?

       This depends on which operating system your program is running on.  In the case of Unix, the
       serial ports will be accessible through files in /dev; on other systems, device names will
       doubtless differ.  Several problem areas common to all device interaction are the following:

       lockfiles
           Your system may use lockfiles to control multiple access.  Make sure you follow the cor-
           rect protocol.  Unpredictable behavior can result from multiple processes reading from one
           device.

       open mode
           If you expect to use both read and write operations on the device, you'll have to open it
           for update (see "open" in perlfunc for details).  You may wish to open it without running
           the risk of blocking by using sysopen() and "O_RDWR|O_NDELAY|O_NOCTTY" from the Fcntl mod-
           ule (part of the standard perl distribution).  See "sysopen" in perlfunc for more on this
           approach.

       end of line
           Some devices will be expecting a "\r" at the end of each line rather than a "\n".  In some
           ports of perl, "\r" and "\n" are different from their usual (Unix) ASCII values of "\012"
           and "\015".  You may have to give the numeric values you want directly, using octal
           ("\015"), hex ("0x0D"), or as a control-character specification ("\cM").

               print DEV "atv1\012";       # wrong, for some devices
               print DEV "atv1\015";       # right, for some devices

           Even though with normal text files a "\n" will do the trick, there is still no unified
           scheme for terminating a line that is portable between Unix, DOS/Win, and Macintosh,
           except to terminate ALL line ends with "\015\012", and strip what you don't need from the
           output.  This applies especially to socket I/O and autoflushing, discussed next.

       flushing output
           If you expect characters to get to your device when you print() them, you'll want to aut-
           oflush that filehandle.  You can use select() and the $| variable to control autoflushing
           (see "$|" in perlvar and "select" in perlfunc, or perlfaq5, ``How do I flush/unbuffer an
           output filehandle?  Why must I do this?''):

               $oldh = select(DEV);
               $| = 1;
               select($oldh);
           You'll also see code that does this without a temporary variable, as in

               select((select(DEV), $| = 1)[0]);

           Or if you don't mind pulling in a few thousand lines of code just because you're afraid of
           a little $| variable:

               use IO::Handle;
               DEV->autoflush(1);

           As mentioned in the previous item, this still doesn't work when using socket I/O between
           Unix and Macintosh.  You'll need to hard code your line terminators, in that case.

       non-blocking input
           If you are doing a blocking read() or sysread(), you'll have to arrange for an alarm han-
           dler to provide a timeout (see "alarm" in perlfunc).  If you have a non-blocking open,
           you'll likely have a non-blocking read, which means you may have to use a 4-arg select()
           to determine whether I/O is ready on that device (see "select" in perlfunc.

       While trying to read from his caller-id box, the notorious Jamie Zawinski <jwz@netscape.com>,
       after much gnashing of teeth and fighting with sysread, sysopen, POSIX's tcgetattr business,
       and various other functions that go bump in the night, finally came up with this:

           sub open_modem {
               use IPC::Open2;
               my $stty = `/bin/stty -g`;
               open2( \*MODEM_IN, \*MODEM_OUT, "cu -l$modem_device -s2400 2>&1");
               # starting cu hoses /dev/tty's stty settings, even when it has
               # been opened on a pipe...
               system("/bin/stty $stty");
               $_ = <MODEM_IN>;
               chomp;
               if ( !m/^Connected/ ) {
                   print STDERR "$0: cu printed `$_' instead of `Connected'\n";
               }
           }
 楼主| 发表于 2004-5-19 08:42:21 | 显示全部楼层
谢谢了,我已经实现了简单的从一个串口进行读写(Linux环境下),但是当我用到CYGWIN下时发现只能写不能读,有谁知道原因和解决的方法嘛?
 楼主| 发表于 2004-5-19 08:45:01 | 显示全部楼层
以下是我的代码
#!/usr/bin/perl
system("stty -echo raw 9600");
system("stty -echo raw 9600 </dev/ttyS0");
$key="";
$stop=0;
open(TEL,'+</dev/ttys0');
if ($pid = fork()) {
   while($key ne '!'){
# send the data from standard input to RS-232C port
      $key=getc(STDIN);
      print TEL "$key";
   }
   $stop=1;
}

# send the data from RS-232C port to standard output
else {
   $term="";
   while($term ne '!'){
      read(TEL,$term,1);
      if($term eq \015) {
         print "\015\012";
      }
      else {
         print "$term";
      }
   }
   exit;
}
 楼主| 发表于 2004-5-26 11:19:50 | 显示全部楼层
up,继续求助
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表