• Mac下的串口通信-ORSSerialPort


    ================================2015/11/05=======================================

    最近在工作中遇到有关Mac下串口通信的问题,一开始直接用以前同事写的framework,基本通信没问题,通过一个NSThread对象开启一个线程,在线程中用while循环不断读取数据,如果读到数据,则进行处理。但是一打开串口,CPU的占用率就直接飙到100%,而且读信息的时候很难判断“ ”换行符,于是打算自己重写串口类。

    到网上搜索资料,“Mac+串口”,无果,大部分都转往Linux串口方向。虽然很多人都说mac系统跟linux差不多,但是对于小白,概念还是比较模糊的,无从下手。

    无意间找到一篇文章:mac下串口通讯工具的编写

    看了一下注释,觉着作者写的类不错,于是乎跑到Github,幸运地找到了同名的项目:https://github.com/armadsen/ORSSerialPort

    (感谢上面转载的那位博主,没有中文标题,估计跑到GitHub不知得翻到什么时候……)

    自己先研究一下,后续再补充。

    ================================2015/11/06=======================================

    经过一天的磨合,终于把自己的小程序搞定。ORSSerialPort这个工程的使用体验很好,用法非常简单,串口通信的应用程序工作状态中CPU的占用率也只有2%~5%左右,程序很顺畅,不会卡死,至于里面的进程机制,抱歉我还没有完全弄清楚,留待以后慢慢看。

    今天做个简单总结:

    1、ORSSerialPort是什么?

    ORSSerialPort是一个使用方便的Objective-C串口库,用于OS X系统下的串口通信。目前有Objective-C和Swift两种版本,可供程序开发者选择。

    Source源码是用Objective-C写的。在Swift下使用的话,添加一个Bridge头文件即可。

    这里是作者Andrew Madsen的博客,可以围观一下:http://blog.andrewmadsen.com/

    2、为什么要用ORSSerialPort?

    (1)开源

    ORSSerialPort基于MIT软件协议,使用者可以根据自己的需求进行修改和使用。

    (2)可以监听数据的接收/响应以及串口的断开/接入等事件。

    (3)Key Value Observing

    ORSSerialPort的很多属性使用了Key-Value Observing机制,当指定属性被修改后,对象就会收到通知。

    3、如何使用ORSSerialPort?

    (1)安装

    原作者提供了几种将ORSSerialPort加入工程的方法,https://github.com/armadsen/ORSSerialPort/wiki/Installing-ORSSerialPort

    总的来说,可将ORSSerialPort编译成framework,然后加入工程中。也可以直接将ORSSerialPort的源码(ORSSerialPort/Source)copy到工程里。推荐使用后者,可以对代码进行修改和调试,也可以清晰地了解串口通信程序编写的过程。

    (2)读取一行数据

    ORSSerialPort的原代码是不支持一行一行读取数据的。

    我的处理方法是:用一个全局的NSMutableString字符串RxString来暂存接收到的数据,每次接收的时候,判断RxString是否包含结束符(' '),如果包含,则将RxString送入处理函数,然后,将RxString进行清空。

     1 NSMutableString *RxString;
     2 -(void)serialPort:(ORSSerialPort *)serialPort didReceiveData:(NSData *)data{
     3     
     4     NSString *str=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
     5     
     6     if(str.length == 0)
     7         return;
     8 
     9     [RxString appendString:str];
    10     
    11     //接收到一行数据
    12     if([RxString containsString:@"
    "]){
    13         if(flagShow){
    14             //处理数据
    15             [self handleReceiveString:RxString];
    16         }
    17         
    18         //重置RxString
    19         RxString=[NSMutableString stringWithString:@""];
    20         
    21     }
    22 }

    当然,也有其他的解决方案,比如,在ORSSerialPort的源码中进行修改:Mac上一个不错的读串口的库ORSSerialPort

    (3)配置串口

    在ORSSerialPort源码中,作者将数据位数写成了8位,如果需要进行配置,可以添加一个DataBits属性。

    首先,在ORSSerialPort.h中添加属性的声明:

     1 /** ---------------------------------------------------------------------------------------
     2  * @name Configuring the Serial Port
     3  *  ---------------------------------------------------------------------------------------
     4  */
     5 
     6 //--------------------------------change------------------------------
     7 /**
     8  *  The number of data bits. Possible values are: 5, 6, 7, or 8.
     9  */
    10 @property (nonatomic) NSUInteger numberOfDataBits;
    11 
    12 //------------------------------end change----------------------------

    然后,在ORSSerialPort.m中进行修改- (void)setPortOptions方法:

     1 // Set data bits
     2     options.c_cflag &= ~CSIZE;
     3     
     4 //    -----------------change------------------
     5 //    options.c_cflag |= CS8;
     6     switch (self.numberOfDataBits) {
     7         case 5:
     8             options.c_cflag |= CS5;
     9             break;
    10         case 6:
    11             options.c_cflag |= CS6;
    12             break;
    13         case 7:
    14             options.c_cflag |= CS7;
    15             break;
    16         case 8:
    17             options.c_cflag |= CS8;
    18             break;
    19         default:
    20             break;
    21     }
    22 //    -------------end change------------------
    23     

    添加DataBits属性的setter:

    1 //-----------------change-------------------------------
    2 -(void)setNumberOfDataBits:(NSUInteger)numberOfDataBits{
    3     if(numberOfDataBits != _numberOfDataBits){
    4         _numberOfDataBits = numberOfDataBits;
    5         
    6         [self setPortOptions];
    7     }
    8 }
    9 //-----------------end change---------------------------

    修改- (instancetype)initWithDevice:(io_object_t)device:

     1         self.requestsQueue = [NSMutableArray array];
     2 //        ---------------change-----------------
     3         self.numberOfDataBits = 8;
     4 //        ----------------end change -----------
     5         self.baudRate = @B19200;
     6         self.allowsNonStandardBaudRates = NO;
     7         self.numberOfStopBits = 1;
     8         self.parity = ORSSerialPortParityNone;
     9         self.shouldEchoReceivedData = NO;
    10         self.usesRTSCTSFlowControl = NO;
    11         self.usesDTRDSRFlowControl = NO;
    12         self.usesDCDOutputFlowControl = NO;
    13         self.RTS = NO;
    14         self.DTR = NO;

    Done!

     ================================2015/11/09=======================================

  • 相关阅读:
    Expectation Maximization Algorithm
    Cramer-Rao Bounds (CRB)
    宽带DOA估计方法
    Statistical Methods for Machine Learning
    Bootstrap Method
    算法学习————猫树
    扩展KMP详解
    网络流的模型和应用
    [CQOI2011]动态逆序对
    CF1278F Cards
  • 原文地址:https://www.cnblogs.com/tt2015-sz/p/4939028.html
Copyright © 2020-2023  润新知