输出字符1所对应的数字
○ char zifu1=‘1’;
System.out.println(zifu1+0);
0-65536 2^16 1111 1111 1111 1111
-32768-32767
32767 0111 1111 1111 1111
-32768-0 最高位为负
• 以0开头的都是八进制数
• 十进制数不能以0开头。
• 以0x和0X开头的都是十六进制。
十六进制逢15进1,四个比特描述一个十六进制数
cyclic redundancy chech 循环冗余校验。对数据进行计算,得到结果附在后面,接收设备同样如此,以保证数据传输之完整。
校验宽度 (WIDTH)即最后生成的数据长度,可以为任意长度,一般使用16bit或32bit。
如0xFFFF是16bit的校验和
如0xFFFFFFFF是32bit的校验和
多项式的每项的系数为0或1,最高系数是和宽度相等,因为有0次幂存在,因此总多项式为宽度+1
例如,16bit的CRC16-MODBUS的生成多项式为
要求最高幂(这里是x的16次方)系数为1,最低次幂(永远是x的0次方)系数为1
因为使用程序进行CRC计算时使用一个宽度 (WIDTH)为长度的寄存器进行,我们需要给这个寄存器写入初始值,写入的初始值即为这个值
计算完成后输出之前需要于此值进行异或操作
一般为全0或全1,长度和宽度 (WIDTH)相等
CRC计算时是以字节(Byte)为单位输入寄存器中的,这个参数是说明输入数据的顺序。
反转的例子
输出数据反转和输入反转类似,只不过是以宽度 (WIDTH)为基准反转而已
u16 CRC16(u8 * Dat, int Len)
{
u16 Poly = 0x8005;
u16 CRC = 0xffff;
u8 Zj = 0;
for (int i = 0; i < Len; i++)
{
//在这里加输入反转
Zj = (Dat[i]);
CRC ^= (Zj<< 8);
for (int j = 0; j < 8; j++)
{
if (CRC & 0x8000)
{
CRC <<= 1;
CRC ^= Poly;
}
else
{
CRC <<= 1;
}
}
}
//在这里加输出反转
return ((CRC)^0x0000);
}
反转:
u16 CRC_Reverse_16(u16 Dat)
{
u16 Res = 0;
u16 zj = Dat;
for (int i = 0; i < 16; i++)
{
if (zj & 0x8000)
Res += 1<<i;
zj <<= 1;
}
return Res;
}
u8 CRC_Reverse_8(u8 Dat)
{
u8 Res = 0;
u8 zj = Dat;
for (int i = 0; i < 8; i++)
{
if (zj & 0x80)
Res += 1 << i;
zj <<= 1;
}
return Res;
}
上述计算过程运算量相等较大,因为每移动一位均需要计算一次异或操作,适合上位机使用
下位机还是建议使用查表法,如果将1Byte的数据做成表,只需要之前的1/8的计算量
,输入0-0xFF的1Byte数据进行CRC,输出值为表:也就是都遍历
u16 CRC16_ModBus1(u8 Dat)
{
u16 Poly = CRC_Reverse_16(0x8005);
u16 CRC = 0xffff;
u8 Zj = 0;
for (int i = 0; i < Len; i++)
{
CRC ^= Dat[i];
for (int j = 0; j < 8; j++)
{
if (CRC & 0x0001)
{
CRC >>= 1;
CRC ^= Poly;
}
else
{
CRC >>= 1;
}
}
}
return (CRC ^ 0x0000);
}
int main()
{
u8 i=0;
for(i=0;i<=0xFF;i++)
{
printf("%X",CRC16_ModBus1(i));
}
}
生成:const u16 T[256] =
{
0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,0xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440,0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40,0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40,0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41,0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040,0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441,0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840,0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40,0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640,0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441,0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840,0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640,0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041,0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440,0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841,0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41,0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040
};
查表的代码和直接计算类似,只需要注意两点
u16 CRC16_ModBus2(u8 *Dat, int Len)
{
u16 CRC = 0xffff;//初始值
u8 Zj;
for (int i = 0; i < Len ; i++)
{
Zj = (CRC & 0xFF)^ Dat[i];//生成标号,一次将低8位数据消除
CRC >>= 8;
CRC ^= T[Zj];
}
return (CRC);
}
CRC计算在线
二进制补码:正数的补码是自己,负数的补码取反加一。
-1在内存中的存储就是10000001 反11111110加1,11111111.全高电平
二进制反码:通过反转位组合中的每一位形成一个负数。
八进制:三位表示一个数,001 110 010 即162八进制
英文 binary digit的缩写 二进制数系统中,每个0或1就是一个位(bit)
位是数据存储(计算机中信息)的最小单位
计算机中的CPU位数指的是CPU一次能处理的最大位数。例如32位计算机的CPU一次最多能处理32位数据
8bit就称为一个字节(Byte), 1Byte=8bit
记为Byte或B,是计算机中信息的基本单位,每个字节有一个门牌号。
32位系统最多有2的32个状态,也就是说门牌号从0~2^32都可以有。所以最大的地址占四个字节,因此默认建立指针变量的时候是四个字节。
• 8位ASCII编码的ASCII字符是8位(1字节),但它可以容纳7位.
• ISO-8859-1编码中的ISO-8895-1字符是8位(1字节).
Unicode码表,万国码,包括中文,非常大
Unicode定义了国际化字符集。是迄今为止人类语言的所有字符集。
万国码,UTF-8采用变字长的方式。
UTF-8编码中的Unicode字符介于8位(1字节)和32位(4字节)之间.
使用非常广泛。
一个英文字符1个字节,一个中文字符3个字节。
UTF-8:Unicode TransformationFormat-8bit,是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。
UTF-8编码的文字可以在各国支持UTF8字符集的浏览器上显示。
utf通常指UTF-8,支持简体中文字、繁体中文字、英文、日文、韩文等语言(支持文字更广)
UTF-16编码中的Unicode字符介于16(2字节)和32位(4字节)之间,但大多数常用字符占16位.这是Windows内部使用的编码.
• UTF-32编码中的Unicode字符始终为32位(4字节).
• UTF-8中的ASCII字符是8位(1字节),UTF-16中的ASCII字符是16位.
ISO-8895-1(0xA0-0xFF)中的附加(非ASCII)字符将采用UTF-8和UTF-16中的16位.
使用两个字节表示一位中文字符。有两万多个字符。
GBK是国家标准GB2312基础上扩容后兼容GB2312的标准
用8bit足够描述键盘中所有的键位。2的8次方 256
基于拉丁字母的电脑编码系统 128个字符。95 个可显示字符,32—126。33个控制字符,0-31,127,128.
0 NULL
1 \0 空字符
使用一字节表示128个英文字符。
据在物理上的存储方式是二进制的,即由0/1字符串构成。而我们解读这些的方式有两种:基于字符编码,和基于值编码。
常见的基于字符的编码有:ASCII码,Unicode编码。
基于值编码,可以理解为自定义的编码。
如果某文件的数据使用基于值的编码,那么该文件即为“二进制文件”。不同的应用程序对二进制文件中的每个值会有不同的解读,就像不同的编码对文本文件中的每一/多个字节有不同的解读。
常见的二进制文件有可执行程序、图形、图像、声音等等。
1B(byte,字节)= 8 bit
1KB=1024B;2的10次方
1MB=1024KB=1024×1024B。 2的20次方
1KB(Kilobyte,千字节)=2的10次方B;
1MB(Megabyte,兆字节,百万字节,简称“兆”)=2的20次方 B;
1GB(Gigabyte,吉字节,十亿字节,又称“千兆”)=2的30次方B; 30是盒子的个数
1TB(Terabyte,万亿字节,太字节)=2的40次方 B;
1PB(Petabyte,千万亿字节,拍字节)=2的50次方 B;
在通信中带宽是指信号的频带宽度。即最高频率与最低频率之差。Hz
电磁波中:带宽就是频带宽度。
模拟信号系统,带宽表示频率宽度。带宽就是带通滤波器高低频率之差。带宽大可以通过更多频率的信号。
数字信号:带宽表示1S之内可以传输的最大数据量。单位bps,就是比特率。也称为网络带宽。
较宽的带宽。
九十年代带宽都被限制在56K,高于56Kbps的带宽都称为宽带,反之为窄带。
2010年重新定义,56K变成了4M。
一个码元就是一个脉冲信号,一个脉冲信号有可能携带1bit数据,也有可能携带2bit数据、4bit数据。
举个例子:把振幅分成四种,低(00)、中(01)、高(10)、很高(11),这样我发一个脉冲信号,它的振幅是低,那就说明发送的是00(也就是2bit),它的振幅是中(01),发送的就是01(也就是2bit)……也就实现了一个脉冲信号,携带2bit的功能。
比特流(Bitstream)是飞利浦八八年提出的技术,构造很简单。首先二进制的数码信号进入一个有参考电压的模组中,输入信号比参考电压高输出就是1,反之则为0;第二个信号再与第一个信号比较,更高的就输出1,较低输出0…以此类推。
所谓比特流就是一串二进制信息,数据的传输现在大部分都是用的数字信号,也有模拟信号的。
单位时间内传输的比特。单位如下:
bps 或 b/s 即 bit per second
kb/s
Mb/s
Gb/s
在网络中带宽数字信道能传输的最高数据率(比特率)。单位bps
波特率指的就是1秒能发送多少个码元,也就是1秒能发送多少个脉冲信号。
数字信号是离散的,它的任何一个值都是规定的最小单位的整数。
当我们使用的码元数量有限的时候,是数字信号。
通俗说代表消息的参数的取值是离散的。
用户家中的计算机到调制解调器之间就是数字信号。
当使用的码元就是某个实数区间的时候,就是离散/模拟信号。
通俗说模拟代表消息的参数的取值是连续的。
调制解调器到电话端局之间的用户线上传送的就是模拟信号。
ADC芯片
并联比较型AD转换器,转换速度最快
将8V电压均分成8份,每份对应一个3位二进制数
将8V加上8个等值电阻,就将其分为了1V到8V
当我们要测量2.1V,从下到上输出11000000。同理
通过优先编码器将8种结果转成3位二进制。
这个AD的精度很低。
将这个电压分成多少份,几乎就需要等同数量的比较器和触发器。
显示分辨率就是屏幕上显示的像素个数,分辨率160×128的意思是水平方向含有像素数为160个,垂直方向像素数128个。屏幕尺寸一样的情况下,分辨率越高,显示效果就越精细和细腻。
指在由一个数字序列表示的图像中的一个最小单位,称为像素。
串行就是一根线,一次只传输一个数据位的数据
并行就是多根线,一次可以传输多个数据位的数据
单工:只能一个方向传输,收音机
半双工:两个方向都可以,但不能同时传,对讲机
全双工:同时两个方向,电话
有时钟线控制的就是同步
没有就是异步
A调用B的同一个过程,对调用者A来说就是阻塞和非阻塞,对被调用者B来说就是同步和异步。
A调用B,这个时候A只有等待B有结果才会返回。
小明去2号窗口办业务,业务员说你在这等着,弄完给你。
A调用B,B立即返回,不用等待。等B处理完之后会通过通知或者回调函数来通知A结果。
小明去2号窗口办业务,业务员说你先走吧,办完叫你。
简言之,同步与异步的区别在于B是不是立即返回,B完成业务之后会不会主动通知A。所以,同步的话,A需要等待或定时查询B是否完成业务,异步则不需要。
A调用B,A会被挂起,等待B的返回结果,什么事都不可以做。
小明去2号窗口办业务,一直等着中间啥也没干。
A调用B,A会被挂起,等待B的结果,但是可以去做别的事情。
小明去2号窗口办业务,中间还上了趟厕所。
简言之,阻塞与非阻塞的区别在于A是不是先去干别的事。
当A调用B的时候,A需要一直在等待,直到B返回结果,期间A不可以做任何事情。
当A调用B的时候,A需要等待B返回结果,但是期间可以去做别的事情,但是A需要时不时的确认B是否返回结果。
当A调用B的时候,B立即返回结果,A不需要等待,到结果返回时B会通知A,但是期间A不可以做别的事情。
当A调用B的时候,B立即返回结果,A不需要等待,到结果返回时B会通知A,而且期间A还可以做别的事情。
总之,异步非阻塞对大家都有好处,也最人性化。