@implementation AppDelegate
-(instancetype)init
{
self=[superinit];
if(self)
{
My_Com = [[SeriportSettingalloc]init];
}
returnself;
}
以上是我初始化的代码,这段代码重写了父类的init,但是这里的类型我用的是instancetype,这个类型相比于ID类型来说是一种优化写法,能让编译器迅速的知道我们的类属于什么类型的。具体的话可以百度一下,有许多博客和大神讲解的比我更加的清楚。那么在这里我们把我们所写的串口类进行了实例化。
-(IBAction)SetStopbits:(id)sender
{
NSInteger stopbits = [Stopbits intValue];
My_Com->stopbits = stopbits;
}
-(IBAction)Setdatabit:(id)sender
{
NSInteger databits = [Databits intValue];
My_Com->databits=databits;
}
-(IBAction)SetBuratte:(id)sender
{
NSInteger burrate = [Burrate intValue];
My_Com->speed =burrate ;
}
上段代码我实现了三个触发事件,分别是设置停止位,数据位和波特率,这三个控件我是用的Combox控件来实现的,那么在这些简单控件上,只要[(控件实例) 数据类型],以这种方式我们就可以获得Combox 乃至许多简单控件上的数据,所以当事件触发的时候,就把值赋予我们所定义的串口类的实例里的成员变量就好了。
-(IBAction)Open:(id)sender
{
My_Com->DevName=[Device stringValue];
if([My_Com->DevName length]==0)
{
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:[NSString stringWithUTF8String:"Please Input your Seriport Name"]];
[alert setInformativeText:[NSString stringWithFormat:@"name is nil"]];
[alert setAlertStyle:NSAlertStyleWarning];
[alert runModal];
return;
}
My_Com->SerialPort_fd=OpenDev([My_Com->DevName UTF8String]);
if(My_Com->SerialPort_fd==-1)
{
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:[NSString stringWithUTF8String:"Open Serial error"]];
[alert setInformativeText:[NSString stringWithFormat:@"Unkown error"]];
[alert setAlertStyle:NSAlertStyleWarning];
[alert runModal];
return;
}
My_Com->parity='o';
set_speed(My_Com->SerialPort_fd, My_Com->speed);
set_Parity(My_Com->SerialPort_fd,My_Com->databits,My_Com->stopbits,My_Com->parity);
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadDemo) object:nil];
[thread start];
}
-(IBAction)add:(id)sender
{
if([sender state])
{
addstate=1;
}
}
上面这段代码的控件是一个勾选框,勾选框无非两种状态,一种是选中了,另一种是没有选中,那么在Cocoa框架里,参数sender里的state方法就可以判断勾选框是否勾选上了,当勾选框选上的时候,我们把addstate这个全局变量赋值为1,这里读者看了可能有些懵,这段代码是为了发送时的某一功能设定的,其实可以写的更优雅一些,但是本代码目的就是为了教会初学者,所以采用得是标志位的方式实现。下面来看发送函数的代码。
-(IBAction)Send:(id)sender
{
NSString *str=[Sendbuffer stringValue];
if([str length]==0)
{
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:[NSString stringWithUTF8String:"Please Input "]];
[alert setInformativeText:[NSString stringWithFormat:@"Unkown error"]];
[alert setAlertStyle:NSAlertStyleWarning];
[alert runModal];
return;
}
if(addstate==1)
{
if([[AddComBox stringValue] isEqualToString:@"\\n"])
{
NSString *str1=[str stringByAppendingString:@"\n"];
NSData* data = [str1 dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger dataLen = [data length];
const char *dataBytes = (const char*)[data bytes];
write(My_Com->SerialPort_fd, dataBytes, dataLen);
}
else if ([[AddComBox stringValue] isEqualToString:@"\\r\\n"])
{
NSString *str1=[str stringByAppendingString:@"\r\n"];
NSData* data = [str1 dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger dataLen = [data length];
const char *dataBytes = (const char*)[data bytes];
write(My_Com->SerialPort_fd, dataBytes, dataLen);
}
else if ([[AddComBox stringValue] isEqualToString:@"\\r"])
{
NSString *str1=[str stringByAppendingString:@"\r"];
NSData* data = [str1 dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger dataLen = [data length];
const char *dataBytes = (const char*)[data bytes];
write(My_Com->SerialPort_fd, dataBytes, dataLen);
}
else{
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger dataLen = [data length];
const char *dataBytes = (const char*)[data bytes];
write(My_Com->SerialPort_fd, dataBytes, dataLen);
}
}
}
上面这段代码就是发送函数,这个功能就是以textfeild和一个按钮控件,加上Combox,ComBox的作用是为了在发送的时候我们可以选择add不add一个/r/n,这样我们就可以选择我们发送过去的数据到底换行还是不换行。这也就是我们勾选框的目的。
当发送区的textfield被写上数据时,我们先判断他是否是空字符串,如果是空字符串,那么我们一样要弹出警告框。接下来就是判断全局的addstate是否为1,如果为1,我们判断Combox里的值是否为/r/n或者/r或者/n,如果都不是那么我们就直接发送,如果是那么就在字符串的后面加上,这里面是有坑的,读者看我的/r/n不是正常的。至于为什么自己思考一下。NSdata是比特流的意思。也就是串口接收的元数据流,这里其实也可以直接发送,但是这么写更加的安全一些。
-(void)threadDemo
{
ssize_t nread;
char buffer[1024];
BOOL notstop=true;
while (notstop)
{
memset(buffer, 0, sizeof(buffer));
nread = read(My_Com->SerialPort_fd, buffer, 1024);
if (nread>0)
{
NSString * str = [NSString stringWithUTF8String:buffer];
[self performSelectorOnMainThread: @selector(view:) withObject:str waitUntilDone:NO];
}
[NSThread sleepForTimeInterval:0.01];
}
}
-(void)view:(NSString*)str
{
NSUInteger length = 0;
NSAttributedString *theString;
NSRange theRange;
theString = [[NSAttributedString alloc] initWithString:str];
[[My_textView textStorage] appendAttributedString: theString];
length = [[My_textView textStorage] length];
theRange = NSMakeRange(length, 0);
[My_textView scrollRangeToVisible:theRange];
}
上述就是我串口助手源码重要部分的讲解,博主也实现了自动遍历当前可用串口功能,只是这部分的功能是基于第三方库实现的。所以这部分就不写上了,如果调试过程之中发现有乱码,大部分是设置数据错误,可能是参数没对,主要也可能是波特率的问题。希望大家看了我的博客,能自己写出自己的串口助手!