CH340与Android串口通信
为何要将CH340的ATD+Eclipse上的安卓工程移植到AndroidStudio
为了在这个工程基础上进行改动,验证串口的数据和配置串口的参数,我首先在Eclipse上配置了安卓开发环境,注意在配置环境是需要下载一些支持包,SDK等需要科学上网,配置好环境后无法生成APK文件,找不到问题的解决方案,所以遂决定将这个工程移植到AS中。
首先在博客中找到了一些将Eclipse工程移植到AS上的方法,尝试后没有成功,可能是基础较差,出现了一些新的问题不知道怎么解决,所以我打算按照自己的方法尝试移植。
移植的具体步骤
- 首先我们必须明确在原ADT工程下哪些文件是必须并独特的,哪些文件是系统自动生成的,不需要复制的。
重点文件与目录: src libs res androidManifest.xml
需要复制的文件:
1:src目录 MainActivity.java MyApp.java
2:res目录 drawable/icon.png layout/main.xml my_spinner_textview.xml values/strings.xml xml/device_filter.xml
3:libs目录 CH34xUARTDriver.jar - 新建一个空白工程,布局文件使用 layout/main.xml my_spinner_textview.xml 注意将res中上述提到的文件也要复制到AS中res目录中,重复的选择覆盖。
- 将CH34xUARTDriver.jar粘贴到AS的libs中,选中点击右键,选择Add as libar…,完成后可以看见build.gradle中会添加
添加JAR包.jpg - 将java文件粘贴到AS中的Java目录下。
tips: 注意在AS中使用jar包时要导入,否则用不了包中所提供的类,即在上述的JAVA文件中需要加入,在Eclipse中不需要如此操作(import cn…CH34xUARTDriver)
在布局文件中可能有些rEC中某些res中的文件没有复制到AS中的目录下,可以根据系统报的错误或提示再去复制。
通过上述的步骤,这个工程即可在AS上修改编译打包。
CH340串口通信驱动函数
驱动函数有一个详细的PDF文档说明其中的各个函数与参数设置,这里不加赘述。
通信过程中重难点
项目中真个通信都是单向的,所以在这里主要讨论接收数据,并不涉及到发送数据。
驱动中接收函数是
Tips:
JAVA是对类的操作,所以[] date输入没有数据,经过处理以后它就会存储缓冲区串口发送的数据。
在安卓工程中它开了一个线程,在线程中它的代码如下
private class readThread extends Thread {
public void run() {
byte[] buffer = new byte[128];
while (true) {
Message msg = Message.obtain();
if (!isOpen) {
break;
}
int length = MyApp.driver.ReadData(buffer, 128);
if (length > 0) {
String recv = toHexString(buffer, length);
// String recv = new String(buffer, 0, length);
totalrecv += length;
// String recv = String.valueOf(totalrecv);
msg.obj = totalrecv;
handler.sendMessage(msg);
}
}
}
}
串口读取的原理:
串口中一级缓存是程序中写的,也就是上述代码中的buffer,与驱动程序无关,驱动程序是负责来一个字节,就把这个字节填入你开的一级缓存buffer中。
byte[] buffer = new byte[a]中的a与ReadData(buffer, b)中b辨析:
a:代表你开的字节的大小,b读取的字节数,即读取缓存去buffer中的字节数。
a、b取值的可能三种情况:
- a>b,buffer中[b+1,…]中的数据没有意义,不是从串口写入的数据。
- a=b,buffer中的数据全部都是串口发送的数据。
- a<b,要接收的数据字节数超过缓冲数组的上界,一般不这么写。
实验中遇到的情况:
- 我把a=b,而且把它设置为128及以下时,传输会出现问题,同时APP会卡死,到256或更大时就会消除这个问题。
- a>b,a=256,b= 10,数据不会连续,buffer中[b+1,…]中的数据没有意义,下次再去读串口是继续从buffer[b+1,…]中的添加数据,还是从buffer[0]开始存,仍有问题,下次通过实验验证下。
还存在的问题
还是串口读取的问题,串口如何读取,保证数据的实时性,比如说,通过串口给你发个4个字节的数据标志,要你读到这个数据就做出举动(要保证实时性),但是如果a=b的话(目前只有这种方式能保证数据的正确性),每次都只能读定义的整个缓冲区的大小的话,当其实你缓冲区已经接收到了这4个特定的字节时,但是由于a=b,它只能等整个缓存区填满了才能读所有的数据在进行判断,这样的话对整个实时性造成了很大的影响,改如何解决?问题所在。
询问有关经验开发人员了解。
- android不断接收数据放入缓冲区,满了就会覆盖。所以要及时把数据提取出来,然后再对这些数据进行提取。
- 由于每次都得读取整个缓冲区的数据,每个缓冲区内的数据不一定是连续的,所有需要将提取后的数据进行拼接处理,这样才能够还原每一帧的信息。
所以说安卓端没读一次串口数据必定是将整个缓冲区里面的数据全部拿出来,不存在说有缓冲区存了一半等中断信息标志,不过在这里我们可以自己设定缓存区的大小(太小发现不行),这样的话基本来说也可以实现某些特定的操作。