boost 串口编程

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

你可能感兴趣的:(timer,linux,service,System,buffer,character)