基础知识
说到串口,那就有点嵌入式了,说点概念。
上位机:
上位机是指可以直接发出操控命令的设备
下位机:
下位机一般是指被操控的设备(例如单片机)
波特率
波特率串行每秒传输数据的速率,例如,波特率是9600那么它传输一位0或1的时间就是1/9600秒,也就是每秒能传9600bit。波特率越高,代表传输信号频率越高。相同的电缆,信号频率越高时,感抗越大,信号在传输线上的损耗也就越大。因此,波特率越高,传输距离越短。
比特和字节(bit&byte)
计算机就是各种电路的开关,每个开关自然就只有两种状态,开和关,在计算机中1表示的是开,0表示是关。而计算机最小的存储单位是字节,每个字节等于8比特(至于为啥自己查),那8比特用二进制表示当然就是0000 0000-1111 1111,那是不表达为十进制就是0-255呢?(ps 255 是由2的7次方减1来的 公式你懂的),当然不是,负数给狗吃了么☻。
原码、反码、补码
定律:
原码就是二进制本身 例如十进制的1等于0000 0001
对于正数来说 :
原码 = 反码 = 补码
对于负数来说 :
原码就是正数的符号位取1
反码 = 原码的非符号位取反(取反就是把1变成0 把0变成1)
补码 = 反码+1
一些小知识 两个16进制代表一个字节
异或:两者相等为0,不等为1
如a=a^b=1011^1001=0010
对于计算机来说,一个二进制的它的最高位是它的符号位,0代表正数,1代表负数,所以一个字节8比特范围区间应该是 1111 1111 - 0111 1111 也就是-127到127,你以为这就是对的么,其实也不是(我真的不是特意耍你)答案是-128到127,为什么呢,这就涉及到了计算机二进制的运算了。
对于计算机来说,假如要识别符号位来做加还是减,很麻烦,所以计算机只能做加法,例如1-1=1+(-1)。
计算机内部是用补码来存储一个数的,为什么呢,因为二进制的计算就是补码的加法,至于为啥用补码,举个例子1-1它的原码直接相加会等于 1000 0010 等于-2,肯定不科学,那反码呢,反码的1-1等于 1111 1111 转为原码 1000 0000 也就是 -0也不科学,补码就不一样了 补码的 1-1 等于1 0000 0000 超过8位的会被截掉,那结果就是0000 0000 转回原码还是0000 0000 那就正确了。而127加1二进制就会表示 1000 0000 负数么显然不科学,于是中央就决定1000 0000 就是-128了。所以128转字节会变成-128,也就是溢出了。
安卓的串口通讯
串口通讯顾名思义就是给串口发送或者接收数据,而串口的数据格式一般来说有
包头+数据+校验+包尾
或者
包头+数据长度+数据+校验值
等不同的格式,不同的设备有可能不同,当然安卓的串口通讯涉及了jni,也就是java调用c/c++的操作,不过不用担心,谷歌n年前已经帮我们封装好了,https://github.com/cepr/android-serialport-api ,至于怎么导入,自己搜素。当然,如果你像我一样那么懒,直接用别人弄好的arr包吧。
导入
|
|
具体使用
我这里就提个大概吧,首先给谷歌提供的串口工具类提供串口地址,波特率。
是不是很简单哈哈,更详细参考这个开源项目吧 https://github.com/licheedev/Android-SerialPort-Tool
当然串口通讯也是有坑的(编程怎么可能没坑)
会有分包 粘包的坑,至于分包 粘包是啥,下面的图画的很清楚。
具体可看https://blog.csdn.net/qq513036862/article/details/53640317
对于串口分包,我的思路就是根据头和数据长度来拼接,具体思路为,开两个StringBuffer若出现数据长度不足,有以下情况:
1.有包头且在数据起始位的
2.有包头且不在数据起始位的
3.没包头的
StringBuffer1就负责把 1,(2的包头前部分或者3拼接起来,因为2 3在一条完整数据不可能同时存在,所以用或)
StringBuffer2 就负责把 2的包头后部分(含包头存起来)
当StringBuffer1长度够后,检验数据,正确后取出,然后StringBuffer1清空,把StringBuffer2 的数据导入StringBuffer1,StringBuffer2数据清空即可。
讲完啦~