iOS 单片机外设对接基础知识

高字节和低字节

一. 计算机的数值应视为连续若干个二进制位的集合;

二. 所谓高、低字节就是此集合中位地址高/低的二进制位集合;

三. (小端模式,人类正常读写存放顺序0x00,0x00,0x00,0x01)例如定义一个unsigned short型变量在0x1234 5678(数据寻址地址),那么这个变量的地址就是0x1234 5678,占用0x1234 5678(低位地址,数据寻址时,用的是低位字节的地址)与0x1234 5679(高位地址)两字节存储空间,其中0x1234 5678是低字节、0x1234 5679是高字节。


四、 一个16进制数有两个字节组成,例如:A9。

高字节就是指16进制数的前8位(权重高的8位),如上例中的A。

低字节就是指16进制数的后8位(权重低的8位),如上例中的9。
--------------------- --------------------- --------------------- ---------------------
小端和大端

字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有小端、大端两种字节顺序。

小端字节序指低字节数据存放在内存低地址处,高字节数据存放在内存高地址处;

大端字节序是高字节数据存放在低地址处,低字节数据存放在高地址处。

为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于 8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。

 整数类型内部:低地址存储低位,高地址存储高位。 
 局部变量:先定义的高地址,后定义的低地址。 
 类,结构体,数组:先定义的低地址,后定义的高地址。 
 数组实际占用的空间,要比元素大,感觉上像是给数组名本身一个“指针类型”的空间,即4个字节。

任何数据类型的数组都需要 20 个字节的内存空间,加上每一数组维数占 4 个字节,再加上数据本身所占用的空间。数据所占用的内存空间可以用数据元数目乘上每个元素的大小加以计算。例如,以 4 个 2字节之 Integer 数据元所组成的一维数组中的数据,占 8 个字节。这 8 个字节加上额外的 24 个字节,使得这个数组所需总内存空间为 32 个字节。
---------------------
intel处理器  小端模式
TCP/IP       大端模式
苹果的好像是大端
--------------------- --------------------- --------------------- ---------------------
字符与字节

ASCII码:一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。一个二进制数字序列,在计算机中作为一个数字单元,一般为8位二进制数,换算为十进制。最小值-128,最大值127。如一个ASCII码就是一个字节。
UTF-8编码:一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。中文标点占三个字节,英文标点占一个字节
Unicode编码:一个英文等于两个字节,一个中文(含繁体)等于两个字节。中文标点占两个字节,英文标点占两个字节

——————————————————————————————————————————————————————————————————————————————————————————

补码 编辑
计算机中的符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

特性编辑
1、一个负整数(或原码)与其补数(或补码)相加,和为模。
2、对一个整数的补码再求补码,等于该整数自身。
3、补码的正零与负零表示方法相同。
--------------------- --------------------- --------------------- ---------------------
模的概念可以帮助理解补数和补码。
“模”是指一个计量系统的计数范围。如时钟等。计算机也可以看成一个计量机器,它也有一个计量范围,即都存在一个“模”。例如:
时钟的计量范围是0~11,模=12。表示n位的计算机计量范围是0~2^(n)-1,模=2^(n)。
“模”实质上是计量器产生“溢出”的量,它的值在计量器上表示不出来,计量器上只能表示出模的余数。任何有模的计量器,均可化减法为加法运算。
例如:假设当前时针指向10点,而准确时间是6点,调整时间可有以下两种拨法:一种是倒拨4小时,即:10-4=6;另一种是顺拨8小时:10+8=12+6=6
在以12模的系统中,加8和减4效果是一样的,因此凡是减4运算,都可以用加8来代替。对“模”而言,8和4互为补数。实际上以12模的系统中,11和1,10和2,9和3,7和5,6和6都有这个特性。共同的特点是两者相加等于模。
对于计算机,其概念和方法完全一样。n位计算机,设n=8, 所能表示的最大数是11111111,若再加1成为100000000(9位),但因只有8位,最高位1自然丢失。又回了00000000,所以8位二进制系统的模为2^8。在这样的系统中减法问题也可以化成加法问题,只需把减数用相应的补数表示就可以了。把补数用到计算机对数的处理上,就是补码。
--------------------- --------------------- --------------------- ---------------------
正数
正整数的补码是其二进制表示,与原码相同 。
【例1】+9的补码是00001001。(备注:这个+9的补码是用8位2进制来表示的,补码表示方式很多,还有16位二进制补码表示形式,以及32位二进制补码表示形式,64位进制补码表示形式等。每一种补码表示形式都只能表示有限的数字。)
负数
求负整数的补码,将其对应正数二进制表示所有位取反(包括符号位,0变1,1变0)后加1 [2]  。
同一个数字在不同的补码表示形式中是不同的。比如-15的补码,在8位二进制中是11110001,然而在16位二进制补码表示中,就是1111111111110001。以下都使用8位2进制来表示。

数0的补码表示是唯一的。
[+0]补=[+0]反=[+0]原=00000000
[ -0]补=11111111+1=00000000

转化为原码
已知一个数的补码,求原码的操作其实就是对该补码再求补码:
⑴如果补码的符号位为“0”,表示是一个正数,其原码就是补码。
⑵如果补码的符号位为“1”,表示是一个负数,那么求给定的这个补码的补码就是要求的原码。
【例4】已知一个补码为11111001,则原码是10000111(-7)。
因为符号位为“1”,表示是一个负数,所以该位不变,仍为“1”。
其余七位1111001取反后为0000110;
再加1,所以是10000111。

若要得到一个负二进制补码的数值,只要对补码全部取反并加1,就可得到其数值。
如:二进制值:10111111(-65的补码)
各位取反:01000000
加1:01000001(+65)

小数补码求法编辑
一种简单的方式,符号位保持1不变,数值位从右边数第一个1及其右边的0保持不变,左边按位取反。

——————————————————————————————————————————————————————————————————————————————————————————

C语言中位运算符之间,按优先级顺序排列为
1
~
2
<<、>>
3
&
4
^
5
|
6
&=、^=、|=、<<=、>>=
--------------------- --------------------- --------------------- ---------------------
16进制的位运算:比如0x123 (0001 0010 0011)前面没有的补0
就是把ABXDF0123456789 16进制的元素 合并在一起 

取得0x5 可以用 0xD5 & 0x0f
取得0xd 可以用 (0xD5 &0xf0)>>4
将 0xD和0x5合并, (0xd << 4 | 0x5)

0x0f (0000 1111),当从一个有多位的16进制数字中获取某一部分数据,就&上f(1111),其余的&上0(0000),再移除掉右边为0的个数位
比如从0x123中获取0x1(0x123&0xf00>>8)  0x2(0x123&0x0f0>>4)  0x3(0x123&0x00f)

--------------------- --------------------- --------------------- --------------------- 
//10进制转16进制,循环除以16每次把余数写在前面,比如,第一次/16余3,第二次余A,第三次余1 则是0x1A3

+(NSString *)ToHex:(longlong int)tmpid

{

    NSString *nLetterValue;

    NSString *str =@"";

    long longint ttmpig;

    for (int i =0; i<9; i++) {

        ttmpig=tmpid%16;

        tmpid=tmpid/16;

        switch (ttmpig)

        {

            case 10:

                nLetterValue =@"A";break;

            case 11:

                nLetterValue =@"B";break;

            case 12:

                nLetterValue =@"C";break;

            case 13:

                nLetterValue =@"D";break;

            case 14:

                nLetterValue =@"E";break;

            case 15:

                nLetterValue =@"F";break;

            default:nLetterValue=[[NSStringalloc]initWithFormat:@"%lli",ttmpig];

                

        }

        str = [nLetterValue stringByAppendingString:str];

        if (tmpid == 0) {

            break;

        }

        

    }

    return str;

}
--------------------- --------------------- --------------------- --------------------- 
16进制字符 转成10进制 

NSString *str = @"0xff055008";
//先以16为参数告诉strtoul字符串参数表示16进制数字,然后使用0x%X转为数字类型
unsigned long red = strtoul([str UTF8String],0,16); //这里获取到的是16进制(下面是第二种方法)
NSLog(@"转换完的数字为:%lx",red);//这里是10进制

--------------------- --------------------- --------------------- ---------------------
16进制字符,转16进制
NSString * hexCharStr = [hexString substringWithRange:NSMakeRange(i, 2)];//一般就是2位
NSScanner * scanner = [[NSScanner alloc] initWithString:hexCharStr] ;
unsigned int anInt;
[scanner scanHexInt:&anInt];
--------------------- --------------------- --------------------- ---------------------
在上面的基础上,16进制字符,转换成NSData 
 For循环获取每个16进制
 NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];//就是把
 [hexData appendData:entity];//每一个16进制数都添加进入到hexData里面
--------------------- --------------------- --------------------- ---------------------
NSData ,转16进制字符
[data enumerateByteRangesUsingBlock:^(constvoid *bytes, NSRange byteRange,BOOL *stop) {

        unsigned char *dataBytes = (unsignedchar*)bytes;//先转成char

        for (NSInteger i =0; i < byteRange.length; i++) {

            NSString *hexStr = [NSStringstringWithFormat:@"%x", (dataBytes[i]) &0xff];

            if ([hexStr length] == 2) {

                [string appendString:hexStr];

            } else {

                [string appendFormat:@"0%@", hexStr];

            }

        }

    }];
--------------------- --------------------- --------------------- ---------------------
普通字符串转换为十六进制字符串
     
    + (NSString *)hexStringFromString:(NSString *)string{ 
    NSData *myD = [string dataUsingEncoding:NSUTF8StringEncoding]; 
    Byte *bytes = (Byte *)[myD bytes];  //先转换成byte字节,data里面的数据是以byte为单位的
    //下面是Byte 转换为16进制。 
    NSString *hexStr=@""; 
    for(int i=0;i<[myD length];i++) 
    { 
    NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];//16进制数 
     
    if([newHexStr length]==1) 
     
    hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr]; 
     
    else 
     
    hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr]; 
    } 
    return hexStr; 
    }
--------------------- --------------------- --------------------- ---------------------
 十六进制字符串转换为普通字符串的。 
    + (NSString *)stringFromHexString:(NSString *)hexString { // 
     
    char *myBuffer = (char *)malloc((int)[hexString length] / 2 + 1); 
    bzero(myBuffer, [hexString length] / 2 + 1); 
    for (int i = 0; i < [hexString length] - 1; i += 2) { 
    unsigned int anInt; 
    NSString * hexCharStr = [hexString substringWithRange:NSMakeRange(i, 2)]; 
    NSScanner * scanner = [[[NSScanner alloc] initWithString:hexCharStr] autorelease]; 
    [scanner scanHexInt:&anInt]; //16进制
    myBuffer[i / 2] = (char)anInt; //把16进制转换成char类型,一部分16进制中的一个1进制数对应着一个char
//char定义为一个Unsigned Byte类型。也就是无符号的一个字节。它将一个字节的8位全占用了。可以表示的数据范围是0到255之间。
    } 
    NSString *unicodeString = [NSString stringWithCString:myBuffer encoding:4]; //char类型转字符串
    NSLog(@"------字符串=======%@",unicodeString); 
    return unicodeString; 
     
     
    } 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值