Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1040032
  • 博文数量: 264
  • 博客积分: 6005
  • 博客等级: 大校
  • 技术积分: 2798
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-08 20:15
文章分类

全部博文(264)

文章存档

2011年(42)

2010年(213)

2009年(4)

2008年(2)

2007年(3)

分类:

2010-06-10 10:46:22

ASIO不仅支持网络通信,还能支持串口通信。要让两个设备使用串口通信,关键是要设置好正确的参数,这些参数是:波特率、奇偶校验 位、停止位、字符大小和流量控制。两个串口设备只有设置了相同的参数才能互相交谈。

ASIO提供了boost::asio::serial_port类, 它有一个set_option(const SettableSerialPortOption& option)方法就是用于设置上面列举的这些参数的,其中的option 可以是:

  • serial_port::baud_rate    波特率,构造参数为unsigned int
  • serial_port::parity        奇偶校验,构造参数为serial_port::parity::type,enum类型,可以是none, odd, even。
  • serial_port::flow_control    流量控制,构造参数为serial_port::flow_control::type,enum类型,可以是none software hardware
  • serial_port::stop_bits    停止位,构造参数为serial_port::stop_bits::type,enum类型,可以是one onepointfive two
  • serial_port::character_size    字符大小,构造参数为unsigned int

演示代码

  1. #include 
  2. #include 
  3. #include 
  4.  
  5. using namespace std;
  6. using namespace boost::asio;
  7.  
  8. int main(int argc, char* argv[])
  9. {
  10.     io_service iosev;
  11.     // 串口COM1, Linux下为“ /dev/ttyS0”
  12.     serial_port sp(iosev, "COM1");
  13.     // 设置参数
  14.     sp.set_option(serial_port::baud_rate(19200));
  15.     sp.set_option(serial_port::flow_control(serial_port::flow_control::none));
  16.     sp.set_option(serial_port::parity(serial_port::parity::none));
  17.     sp.set_option(serial_port::stop_bits(serial_port::stop_bits::one));
  18.     sp.set_option(serial_port::character_size(8));
  19.     // 向串口写数据
  20.     write(sp, buffer("Hello world", 12));
  21.  
  22.     // 向串口读数据
  23.     char buf[100];
  24.     read(sp, buffer(buf));
  25.     
  26.     iosev.run();
  27.     return 0;

上面这段代码有个问题,read(sp, buffer(buf))非 得读满100个字符才会返回,串口通信有时我们确实能知道对方发过来的字符长度,有时候是不能的。

如果知道对方发过来的数据里有分隔符的话(比如空格作为分隔),可以使用read_until来读,比如:

  1. boost::asio::streambuf buf;
  2. // 一直读到遇到空格为止
  3. read_until(sp, buf, ' ');
  4. copy(
  5.     istream_iterator<char>(istream(&buf)>>noskipws),
  6.     istream_iterator<char>(),
  7.     ostream_iterator<char>(cout)); 

另外一个方法是使用前面说过的异步读写+超时的方式,代码如下:

  1. #include 
  2. #include 
  3. #include 
  4.  
  5. using namespace std;
  6. using namespace boost::asio;
  7. void handle_read(char *buf,boost::system::error_code ec,
  8.     std::size_t bytes_transferred)
  9. {
  10.     cout.write(buf, bytes_transferred);
  11. }
  12.  
  13. int main(int argc, char* argv[])
  14. {
  15.     io_service iosev;
  16.     serial_port sp(iosev, "COM1");
  17.     sp.set_option(serial_port::baud_rate(19200));
  18.     sp.set_option(serial_port::flow_control());
  19.     sp.set_option(serial_port::parity());
  20.     sp.set_option(serial_port::stop_bits());
  21.     sp.set_option(serial_port::character_size(8));
  22.     
  23.     write(sp, buffer("Hello world", 12));
  24.  
  25.     // 异步读
  26.     char buf[100];
  27.     async_read(sp, buffer(buf), boost::bind(handle_read, buf, _1, _2));
  28.     // 100ms后超时
  29.     deadline_timer timer(iosev);
  30.     timer.expires_from_now(boost::posix_time::millisec(100));
  31.     // 超时后调用sp的cancel()方 法放弃读取更多字符
  32.     timer.async_wait(boost::bind(&serial_port::cancel, boost::ref(sp)));
  33.  
  34.     iosev.run();
  35.     return 0;

<完>

阅读(2289) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~