android串口通信接受自定义协议数据并解析问题

1.一般自定义的串口协议

 串口传输接口底层是按位(bit)发送的,上层是按byte发送和接收的,但协议为了方便描述,每个byte用十六进制数(0x00~0xFF)表示,范相当于十进制的0~255,而byte为八位且是有符号类型,相当于十进制的-128~127,明显0x8F~0xFF(128~255)是不能准确转换为byte的,咋办?

byte b = 0xFF;

编译器会提示出错,因为0xFF被当作255整数处理,255超过了byte(-128~127)的范围,不能直接赋值,那咋办?强转啊!

 byte b = (byte) 0xFF;

这样就没问题了,但此时你会不会觉得这样写就和协议想发送0xFF的想法不匹配了呢,我明明想发个255来着,那我告诉你,你一个一个字节的发,每个字节就只能是-128~127,不能在其他范围,所以强转的目的是你可以发送这个0xFF的前提,发送的值肯定不是255,具体是啥:

public class Main {

    public static void main(String[] args) {
        byte c1 = (byte) 0xFF;
        int c2 = c1 & 0xFF;
        System.out.println(""+c1);
        System.out.println(""+c2);
    }
}
-1
255

Process finished with exit code 0

可见,实际上是一个-1,但接受端为了表达这是个发送端发送给我的是0xFF(255)而不是-1,你可以通过取到该字节值后 “ 该值 & 0xFF”转为无符号值即255.

通常自定义协议的格式:

一.接收到数据是不固定的长度,协议是起始是AA AA    结束是DE D0
接收到的数据有可能是AA AA 08 56 82 44 DE DO

二.接受到数据是不固定的长度,协议的起始A0 55  第三个字节为协议长度,结束字节是发送数据的异或校验值,

列如:A0 55 04 51 00 00    55 A0 55 04 53 00 01 56

结束字节是前面各个字节异或后的值:

 /**
     * 异或校验和
     * @param data
     * @return
     */
    public static byte getXor(byte[] data){
        byte temp=data[0];
        for (int i = 1; i <data.length; i++) {
            temp ^=data[i];
        }
        return temp;
    }

2.分段接收数据不好解析

在读取串口数据时,通常在线程中读取输入流中的数据,这时接受的字节数是不固定的,一条指令被分成若干段,接受到的散乱字节不好处理,看到网上有做延时接受处理,也就是输入流可用的时候就延时一会儿,等接受完了再一次性读出来,效果不错:

/**
     * 4.接收串口数据的线程
     */
    private class ReceiveThread extends Thread {
        @Override
        public void run() {
            //条件判断,只要条件为true,则一直执行这个线程
            while (isStart) {
                if (inputStream == null) {
                    return;
                }
                byte[] readData = new byte[1024*4];
                try {
                    String receiveCmd = "";
                    String HEAD = "A055";
                    StringBuilder sb = new StringBuilder();
                    // 为了一次性读完,做了延迟读取
                    if (inputStream.available() > 0 ) {
                        SystemClock.sleep(200);
                        int size = inputStream.read(readData);
                        if (size > 0) {
                            String readString = DataUtils.ByteArrToHex(readData, 0, size);
                            LogUtils.d(readString);
                            if(!TextUtils.isEmpty(readString)){
                                String[] split = readString.split(HEAD);
                                for (int i = 1; i < split.length; i++) {
                                    receiveCmd = HEAD+split[i];
                                    sb.append(receiveCmd+"\n");
                                    LogUtils.e(receiveCmd);
                                }
                            }
                            EventBus.getDefault().post(sb.toString());
                            sb.setLength(0);
                        }
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }

 

 

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
stm32串口通信自定义协议是指在stm32微控制器中使用串口进行通信时,为了满足特定需求所设计的一种协议。相比于常见的通信协议,如UART、SPI或I2C等,自定义协议可以根据实际需求进行灵活的定制,以实现更高效、稳定的数据传输。 首先,自定义协议需要设计合适的数据格式。可以选择使用不同的帧结构,如起始字符、帧长度、命令字、数据域和校验等。起始字符用于标识消息的开始,帧长度用于表示数据域的长度,命令字用于确定接收方的操作,数据域用于传输实际数据,校验用于验证数据的完整性。 其次,自定义协议需要确定合适的数据传输方式。可以选择使用同步传输或异步传输方式,同步传输通常使用时钟来同步发送和接收数据,而异步传输则在数据中添加起始位和停止位来标识数据边界。 接着,自定义协议还需要考虑数据的传输速率和可靠性。可以根据实际需求选择合适的波特率(Baud rate),以确保数据能够在一定的时间内传输完毕。同时,可以采用CRC校验或其他纠错技术,来减少数据传输过程中发生错误的可能性。 最后,为了实现自定义协议,需要在stm32的程序中编写相应的发送和接收函数,并根据协议规定进行数据的拆包和组包。发送函数负责将数据按照协议格式封装成帧,并通过串口发送出去。接收函数则负责解析接收到的数据帧,并根据协议提取出有用的信息。 总之,stm32串口通信自定义协议可以根据实际需求,灵活定制数据格式、传输方式和校验机制等,以实现更高效、灵活和可靠的数据传输。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值