Mac下的串口通信-ORSSerialPort


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

最近在工作中遇到有關Mac下串口通信的問題,一開始直接用以前同事寫的framework,基本通信沒問題,通過一個NSThread對象開啟一個線程,在線程中用while循環不斷讀取數據,如果讀到數據,則進行處理。但是一打開串口,CPU的占用率就直接飆到100%,而且讀信息的時候很難判斷“\r”換行符,於是打算自己重寫串口類。

到網上搜索資料,“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是否包含結束符('\r'),如果包含,則將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:@"\r"]){
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=======================================

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM