用ASIO读写串行口

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

 

演示代码

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

using  namespace std;
using  namespace boost::asio;

int main( int argc,  char* argv[])
{
        io_service iosev;
         //  串口COM1, Linux下为“/dev/ttyS0”
        serial_port sp(iosev,  " COM1 ");
         //  设置参数
        sp.set_option(serial_port::baud_rate( 19200));
        sp.set_option(serial_port::flow_control(serial_port::flow_control::none));
        sp.set_option(serial_port::parity(serial_port::parity::none));
        sp.set_option(serial_port::stop_bits(serial_port::stop_bits::one));
        sp.set_option(serial_port::character_size( 8));
         //  向串口写数据
        write(sp, buffer( " Hello world "12));

         //  向串口读数据
         char buf[ 100];
        read(sp, buffer(buf));

        iosev.run();
         return  0;


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

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

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

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

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

using  namespace std;
using  namespace boost::asio;
void handle_read( char *buf,boost::system::error_code ec,
std::size_t bytes_transferred)
{
        cout.write(buf, bytes_transferred);
}

int main( int argc,  char* argv[])
{
        io_service iosev;
        serial_port sp(iosev,  " COM1 ");
        sp.set_option(serial_port::baud_rate( 19200));
        sp.set_option(serial_port::flow_control());
        sp.set_option(serial_port::parity());
        sp.set_option(serial_port::stop_bits());
        sp.set_option(serial_port::character_size( 8));

        write(sp, buffer( " Hello world "12));

         //  异步读
         char buf[ 100];
        async_read(sp, buffer(buf), boost::bind(handle_read, buf, _1, _2));
         //  100ms后超时
        deadline_timer timer(iosev);
        timer.expires_from_now(boost::posix_time::millisec( 100));
         //  超时后调用sp的cancel()方法放弃读取更多字符
        timer.async_wait(boost::bind(&serial_port::cancel, boost:: ref(sp)));

        iosev.run();
         return  0;

 


转载于:https://www.cnblogs.com/toosuo/archive/2011/12/08/2281008.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值