c++ boost serial port communication

文章转自:http://blog.csdn.net/zhaodan19861107/article/details/7766338


用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 ;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值