编前记
今天在刷博客(郭老师)的时候评论区看见有人在聊单片机的串口通信,刚好之前做过一个项目通过NFC读取IC门禁卡片的项目所以拿出来分享(复习)一下,先讲了解一下什么是串口通信:串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节的通信方式。以上来自百度百科的介绍。
详细介绍猛戳链接:https://baike.baidu.com/item/%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1/3775296?fr=aladdin
在Android系统上是如何进行串口通信的呢?需要先了解以下几个概念
这是一个衡量符号传输速率的参数。指的是信号被调制以后在单位时间内的变化,即单位时间内载波参数变化的次数,如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位,1个停止位,8个数据位),这时的波特率为240Bd,比特率为10位*240个/秒=2400bps。一般调制速率大于波特率,比如曼彻斯特编码)。
这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据往往不会是8位的,标准的值是6、7和8位。如何设置取决于你想传送的信息。比如,标准的ASCII码是0~127(7位)。扩展的ASCII码是0~255(8位)。如果数据使用简单的文本(标准 ASCII码),那么每个数据包使用7位数据。每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。
用于表示单个包的最后一位。典型的值为1,1.5和2位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。
在串口通信中一种简单的检错方式。有四种检错方式:偶、奇、高和低。当然没有校验位也是可以的。对于偶和奇校验的情况,串口会设置校验位(数据位后面的一位),用一个值确保传输的数据有偶个或者奇个逻辑高位。例如,如果数据是011,那么对于偶校验,校验位为0,保证逻辑高的位数是偶数个。如果是奇校验,校验位为1,这样就有3个逻辑高位。高位和低位不真正的检查数据,简单置位逻辑高或者逻辑低校验。这样使得接收设备能够知道一个位的状态,有机会判断是否有噪声干扰了通信或者是否传输和接收数据是否不同步。
以下是基于NFC感应(非接触式)卡片的实战
"NFC卡模拟"能添加和模拟4字节、7字节和10字节的卡id,目前市面上主流4字节和7字节10字节暂时还未面世,一个字节用两位十六进制数表示。
工欲善其事,必先利其器,既然要进行通信那就得读写操作,下面提供一个封装好的库:https://pan.baidu.com/s/1JAdtghGxFh-wO5Ga1_4gQA 提取码:exks
// 创建一个SerialPort对象
// 第一个参数File传入要读取的串口路径例如:/dev/ttyS0 具体看开发版定义
// 第二个参数波特率例如:115200 具体看开发版定义
// 第三个参数flags 传入0即可
SerialPort mSerialPort = new SerialPort(new File(serialPath), baudrate, 0);
// 创建完对象就直接获取输入输出流开启读取数据线程
mOutputStream = mSerialPort.getOutputStream();
mInputStream = mSerialPort.getInputStream();
mReadThread = new ReadThread();
mReadThread.start();
private class ReadThread extends Thread {
@Override
public void run() {
super.run();
while (!isInterrupted()) {
int size;
try {
if (mInputStream == null)
return;
byte[] buffer = new byte[512];
size = mInputStream.read(buffer);
if (size > 0) {
// 把读取到的字节数组转换成字符串
String str = byteArrToHex(buffer, 0, size);
// 这里转换后str就是读取到的数据,根据NFC卡片类型自行进行数据的效验,
// 比如有效位与无效位
// do something
}
Thread.sleep(10); // 休眠一下优化效率
} catch (Exception e) {
e.printStackTrace();
return;
}
}
}
}
public static String byteArrToHex(byte[] inBytArr, int offset, int byteCount) {
StringBuilder strBuilder = new StringBuilder();
for(int i = offset; i < byteCount; ++i) {
strBuilder.append(byte2Hex(inBytArr[i]));
}
return strBuilder.toString();
}
public static String byte2Hex(Byte inByte) {
return String.format("%02x", inByte).toUpperCase();
}
核心代码就只有这么几行,具体业务逻辑自行封装即可,这里只完成读取设备传递过来的数据。
下面提供一个串口测试工具:https://pan.baidu.com/s/1SJjWl8JLnoEFvKrGcUU2zQ 提取码:8f1z
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)