objective-c和硬件协议通信

本文详细介绍了在iOS应用中使用Objective-C与硬件设备进行通信的过程,包括发送协议消息的步骤(如数据转换、CRC校验、转义处理等)以及接收应答消息的解析验证方法。此外,还涵盖了通用的16进制数据转换操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、简介
iOS与硬件设备模块(C语言)通信,iOS发送消息指令给硬件,硬件收到消息后,进行逻辑处理,再将应答消息返回iOS解析,界面展示结果

C语言采用unsigned char接收二进制数据,iOS需要将16进制数据转换成Byte数组,以NSData类型向设备发送协议
unsigned char(等于Byte) 1个字节  值域范围:0~255

*_t类型为:

序号类型字节长度
1uint8_t1字节
2uint16_t2字节
3uint32_t4字节
4uint64_t8字节

二、发送协议消息
1.将拼接的16进制消息内容转换为Data数据

NSData *verificationData = [self convertHexStrToData:msgContent];

2.调用CRC16方法,将消息内容生成4位校验码,返回(消息内容+CRC校验码)

NSData *converData = [self calCRCWithData:verificationData];

3.将消息体内容进行转义处理,比如:AA <————> BB后紧跟一个 01

NSString *strMsg =[self convertDataToHexStr:finalDataM];

4.在转义内容前后增加标识位

NSString *flagBit = @"FF";
strMsg = [flagBit stringByAppendingString:strMsg];
strMsg = [strMsg stringByAppendingString:flagBit];

5.拆分NSString字符,每2位转换为unsigned char,放入数组中

NSData *trandata2 = [self convertHexStrToData:strMsg];

6.通过TCP将NSData数据发送给设备

三、接收应答消息
1.解析设备返回的应答数据,转换为16进制字符串

NSData *dataMsg = [NSData dataWithBytes:bytes length:sizeof(bytes)];

2.判断应答字符串前后缀是否为“FF“

NSString *headeMsg = [strMsg substringWithRange:range];
range.location = [strMsg length]-2;
NSString *footMsg = [strMsg substringWithRange:range];
BOOL result1 = [@"FF" caseInsensitiveCompare:headeMsg] == NSOrderedSame;
BOOL result2 = [@"FF" caseInsensitiveCompare:footMsg] == NSOrderedSame;
if(result1 == YES && result2){
   NSLog(@"标示位错误!");
}else{
   NSLog(@"标示位错误!");
}

3.将应答字符串反转义

NSData *finalUnescapesData=  [self UnescapesData:verificationData];
        NSString *unescapesStr =[self convertDataToHexStr:finalUnescapesData];

4.调用CRC16方法,将消息体生成4位校验码

NSData *crcData = [self calCRCValidCodeWithData:[self convertHexStrToData:msg1]];
NSString *crcStr =[self convertDataToHexStr:crcData];

5.判断生成的校验码和应答字符串的校验码是否一致

BOOL valideResult = [validCodeMsg caseInsensitiveCompare:crcStr] == NSOrderedSame;
if(valideResult){
     NSLog(@"解析成功!");
}else{
     NSLog(@"解析失败!");
}

四、通用转换方法
1.将16进制字符串转换成NSData

+ (NSMutableData *)convertHexStrToData:(NSString *)str {
    if (!str || [str length] == 0) {
        return nil;
    }

    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
    NSRange range;
    if ([str length] %2 == 0) {
        range = NSMakeRange(0,2);
    } else {
        range = NSMakeRange(0,1);
    }
    for (NSInteger i = range.location; i < [str length]; i += 2) {
        unsigned int anInt;
        NSString *hexCharStr = [str substringWithRange:range];
        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];

        [scanner scanHexInt:&anInt];
        NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
        NSLog(@"转换数据--%ld:%@", (long)i,entity);

        [hexData appendData:entity];

        range.location += range.length;
        range.length = 2;
    }

    return hexData;
}

2.将NSData转换成16进制的字符串

+ (NSString *)convertDataToHexStr:(NSData *)data {
    if (!data || [data length] == 0) {
        return @"";
    }
    NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];

    [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange,BOOL *stop) {
        unsigned char *dataBytes = (unsigned char*)bytes;
        for (NSInteger i =0; i < byteRange.length; i++) {
            NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) &0xff];
            if ([hexStr length] == 2) {
                [string appendString:hexStr];
            } else {
                [string appendFormat:@"0%@", hexStr];
            }
        }
    }];

    return string;
}

3.将16进制字符串转成NSData+CRC数据

+ (NSData *)calCRCWithData:(NSData *)visibleData
{
    //将16进制字符串转成NSData数据
    NSMutableData *visibleDataM = [visibleData mutableCopy];

    //NSData做crc验证得到short返回值
    Byte *byte = (Byte *)[visibleDataM bytes];
    unsigned short crcShort = u16CRC_Calc162(byte, (int)visibleDataM.length);
    //将short返回值转成byte类型添加到可变数组末尾
    Byte bytes[2];
    bytes[0] = (Byte) (crcShort >> 8);
    bytes[1] = (Byte) (crcShort);

    [visibleDataM appendBytes:bytes length:sizeof(bytes)];

    return visibleDataM;
}

4、获取CRC校验码

+ (NSData *)calCRCValidCodeWithData:(NSData *)visibleData
{
    //NSData做crc验证得到short返回值
    Byte *byte = (Byte *)[visibleData bytes];
    unsigned short crcShort = u16CRC_Calc162(byte, (int)visibleData.length);
    //将short返回值转成byte类型添加到可变数组末尾
    Byte bytes[2];
    bytes[0] = (Byte) (crcShort >> 8);
    bytes[1] = (Byte) (crcShort);
    return [[NSData alloc] initWithBytes:bytes length:sizeof(bytes)];
}

5、对Data+CRC数据进行转义

+ (NSData *)EscapedData:(NSData *)converData
{
    /**
     对Data+CRC数据进行转义
     */
    Byte *myBytes = (Byte *)[converData bytes];
    NSMutableData *finalDataM = [NSMutableData data];
    for (int i = 0; i < converData.length; i++) {
        if (myBytes[i] == 0xAA) {
            Byte temByte[2];
            temByte[0] = 0xBB;
            temByte[1] = 0x01;
            [finalDataM appendBytes:temByte length:sizeof(temByte)];

        }
        else if (myBytes[i] == 0xCC) {
            Byte temByte[2];
            temByte[0] = 0xDD;
            temByte[1] = 0x02;
            [finalDataM appendBytes:temByte length:sizeof(temByte)];

        }
        else{
            Byte temByte[1];
            temByte[0] = myBytes[i];
            [finalDataM appendBytes:temByte length:sizeof(temByte)];

        }
    }
    return finalDataM;
}

6、对Data+CRC数据进行反转义

+ (NSData *)UnescapesData:(NSData *)converData
{
    /**
     对Data+CRC数据进行反转义
     */
    Byte *myBytes = (Byte *)[converData bytes];
    NSMutableData *finalDataM = [NSMutableData data];
    for (int i = 0; i < converData.length; i++) {

        if (myBytes[i] == 0xBB && myBytes[i+1] == 01) {
            Byte temByte[1];
            temByte[0] = 0xAA;
            [finalDataM appendBytes:temByte length:sizeof(temByte)];
            i++;
        }
        else if (myBytes[i] == 0xDD && myBytes[i+1] == 02) {
            Byte temByte[1];
            temByte[0] = 0xCC;
            [finalDataM appendBytes:temByte length:sizeof(temByte)];
            i++;
        }
        else{
            Byte temByte[1];
            temByte[0] = myBytes[i];
            [finalDataM appendBytes:temByte length:sizeof(temByte)];
        }
    }

    return finalDataM;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值