精华内容
下载资源
问答
  • 首先我用的是第三方bluetoothkit 进行连接的。 不知道的小伙伴可以去github先了解一下。https://github.com/dingjikerbo/Android-BluetoothKit 其实连接什么的我就不做介绍了。 利用这个Xmodem协议升级的时候我...

    最近公司安排了一个BLE升级固件的任务,要用Xmodem协议,搞的我赶紧去补这块的知识。

    首先我用的是第三方bluetoothkit 进行连接的。

    不知道的小伙伴可以去github先了解一下。https://github.com/dingjikerbo/Android-BluetoothKit

    其实连接什么的我就不做介绍了。

    利用这个Xmodem协议升级的时候我发现有些坑。

     

    1.安卓为了适配多个版本,机型,强制要求,BLE每次只能收发20个字节,超过就收不到了,发到好说,收数据的需要跟嵌入式同学沟通。(网上也有说修改MTU值达到发送更多的,我试过,但没成功。可能是我的方法有误,有兴趣的可以去试一下)

    2.BLE发送时间间隔其实是有要求的,底层队列是串行的,不注意的话很容易阻塞。下次再发的时候就会出现命令货不对版的情况。(建议是每发20字节,隔80--100毫秒在发下一个20字节。)

    首先先贴出Xmodem代码

    package com.mituo.pda_ble;
    
    
    import android.util.Log;
    import android.view.View;
    import android.widget.Toast;
    
    import com.inuker.bluetooth.library.BluetoothClient;
    import com.inuker.bluetooth.library.Constants;
    import com.inuker.bluetooth.library.connect.response.BleNotifyResponse;
    import com.inuker.bluetooth.library.connect.response.BleReadResponse;
    import com.inuker.bluetooth.library.connect.response.BleWriteResponse;
    
    import org.greenrobot.eventbus.EventBus;
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.util.UUID;
    
    /**
     * Created by Administrator on 2019-08-06.
     */
    public class Xmodem {
    
        // 开始
        private final byte SOH = 0x01;
        // 结束
        private final byte EOT = 0x04;
        // 应答
        private final byte ACK = 0x06;
        // 重传
        private final byte NAK = 0x15;
        // 无条件结束
        private final byte CAN = 0x18;
    
        // 以128字节块的形式传输数据
        private final int SECTOR_SIZE = 128;
        // 最大错误(无应答)包数
        private final int MAX_ERRORS = 10;
    
        // 输入流,用于读取串口数据
        private InputStream inputStream;
        // 输出流,用于发送串口数据
        private OutputStream outputStream;
    
        public Xmodem(InputStream inputStream, OutputStream outputStream) {
            this.inputStream = inputStream;
            this.outputStream = outputStream;
        }
    
        //scanRecords的格式转换
        static final char[] hexArray = "0123456789ABCDEF".toCharArray();
    
        private static String bytesToHex(byte[] bytes) {
            char[] hexChars = new char[bytes.length * 2];
            for (int j = 0; j < bytes.length; j++) {
                int v = bytes[j] & 0xFF;
                hexChars[j * 2] = hexArray[v >>> 4];
                hexChars[j * 2 + 1] = hexArray[v & 0x0F];
            }
            return new String(hexChars);
        }
    
        private BluetoothClient Client;
        String MAC;
        String serviceUUID;
        String w_UUID;
    
        public Xmodem(BluetoothClient mClient, String MAC, String serviceUUID, String w_UUID) {
            Client = mClient;
            this.MAC = MAC;
            this.serviceUUID = serviceUUID;
            this.w_UUID = w_UUID;
        }
    
        /**
         * 发送数据
         *
         * @param filePath 文件路径
         */
        public void send(final String filePath) {
            new Thread() {
                public void run() {
                    try {
                        long num=0;
                        // 错误包数
                        int errorCount;
                        // 包序号
                        byte blockNumber = 0x01;
                        // 校验和
                        byte checkSum;
                        // 读取到缓冲区的字节数量
                        int nbytes;
                        // 初始化数据缓冲区
                        byte[] sector = new byte[SECTOR_SIZE];
                        // 读取文件初始化
                        FileInputStream  fis = new FileInputStream(filePath);
                        Log.e("aris","文件"+"的大小是:"+fis.available()+"\n");
                        EventBus.getDefault().post("文件大小:"+fis.available());
                        DataInputStream inputStream = new DataInputStream(
                                fis);
                        while ((nbytes = inputStream.read(sector)) > 0) {
                            // 如果最后一包数据小于128个字节,以0xff补齐
                            if (nbytes < SECTOR_SIZE) {
                                for (int i = nbytes; i < SECTOR_SIZE; i++) {
                                    sector[i] = (byte) 0xff;
                                }
                            }
                            num+=nbytes;
                            // 同一包数据最多发送10次
                            Log.e("aris", "000000000");
                            errorCount = 0;
                            while (errorCount < MAX_ERRORS) {
                                Bleutils.getInstance().setNotify("");
                                // 组包
                                // 控制字符 + 包序号 + 包序号的反码 + 数据 + 校验和
                                checkSum = (byte) (calc(sector) & 0x00ffff);
                                putChar(SOH, blockNumber, ~blockNumber, sector, checkSum);
    
                                Thread.sleep(150);
                                // 获取应答数据
    //                            Log.e("aris", "Notify  :  " + Bleutils.getInstance().getNotify());
                                // 如果收到应答数据则跳出循环,发送下一包数据
                                // 未收到应答,错误包数+1,继续重发
                                if (Bleutils.getInstance().getNotify().equals("06")) {
                                    Log.e("aris", "发送下一包数据");
                                    EventBus.getDefault().post("进度:"+num);
                                    break;
                                } else {
                                    Thread.sleep(1000);
                                    if (Bleutils.getInstance().getNotify().equals("06")) {
                                        Log.e("aris", "444444444444");
                                        break;
                                    }
                                    ++errorCount;
    //                                if (errorCount == 9) {
                                    EventBus.getDefault().post("升级错误");
                                    Client.clearRequest(MAC, 0);//clearType表示要清除的请求类型,如果要清除多种请求,可以将多种类型取或,如果要清除所有请求,则传入0。
                                    Log.e("aris", "升级错误,终止升级");
                                    Client.refreshCache(MAC);
                                    Thread.sleep(500);
                                    Client.disconnect(MAC);
                                    return;
    //                                }
                                }
    
                            }
                            // 包序号自增
                            blockNumber = (byte) ((++blockNumber) % 256);
                        }
    
                        // 所有数据发送完成后,发送结束标识
                        boolean isAck = false;
                        while (!isAck) {
                            Bleutils.getInstance().setNotify("");
                            putData(EOT, "发送结束标识");
                            Thread.sleep(500);
                            isAck = Bleutils.getInstance().getNotify().equals("06");
                        }
    
                        Thread.sleep(100);
                        Bleutils.getInstance().setNotify("软件更新指令");
                        update();
                        Thread.sleep(500);
                        Client.clearRequest(MAC, 0);//clearType表示要清除的请求类型,如果要清除多种请求,可以将多种类型取或,如果要清除所有请求,则传入0。
                        Client.refreshCache(MAC);
                        Thread.sleep(500);
                        Client.disconnect(MAC);
                        EventBus.getDefault().post("软件更新指令OK");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
    
                ;
            }.start();
    
        }
    
    
    
        /**
         * 发送数据
         *
         * @param data 数据
         * @throws IOException 异常
         */
    
        private void putData(int data, final String s) throws IOException {
            Client.write(MAC, UUID.fromString(serviceUUID), UUID.fromString(w_UUID), new byte[]{(byte) data}, new BleWriteResponse() {
                @Override
                public void onResponse(int code) {
                    if (code == Constants.REQUEST_SUCCESS) {
                        Log.e("aris", "putData  write  请求成功 " + s);
                    } else if (code == Constants.REQUEST_FAILED) {
                        Log.e("aris", "putData  write  请求失败 " + s);
                        EventBus.getDefault().post("升级错误");
                    }
                }
            });
        }
    
        public static byte hexToByte(String inHex) {
            return (byte) Integer.parseInt(inHex, 16);
        }
    
        void update() {
    
            //软件更新指令
            //发送:55  01  31  EE
            byte bt2[] = new byte[4];
            bt2[0] = hexToByte("55");
            bt2[1] = hexToByte("01");
            bt2[2] = hexToByte("31");
            bt2[3] = hexToByte("EE");//EE
            Client.write(MAC, UUID.fromString(serviceUUID), UUID.fromString(w_UUID), bt2, new BleWriteResponse() {
                @Override
                public void onResponse(int code) {
                    if (code == Constants.REQUEST_SUCCESS) {
                        Log.e("aris", "update  请求成功 " + code);
                    } else if (code == Constants.REQUEST_FAILED) {
                        Log.e("aris", "update  请求失败 " + code);
                    }
                }
            });
            Log.e("aris", "软件更新指令");
        }
    
        /**
         * 发送数据
         *
         * @param SOH
         * @param blockNumber
         * @param i
         * @param data        数据
         * @param checkSum    校验和   @throws IOException 异常
         */
        private void putChar(byte SOH, byte blockNumber, int i, byte[] data, byte checkSum) throws IOException, InterruptedException {
            ByteBuffer bb = ByteBuffer.allocate(data.length + 4).order(
                    ByteOrder.BIG_ENDIAN);
            bb.put(SOH);
            bb.put(blockNumber);
            bb.put((byte) i);
            bb.put(data);
            bb.put(checkSum);
            byte data1[] = new byte[20];
            byte data2[] = new byte[20];
            byte data3[] = new byte[20];
            byte data4[] = new byte[20];
            byte data5[] = new byte[20];
            byte data6[] = new byte[20];
            byte data7[] = new byte[12];
            for (int j = 0; j < bb.array().length; j++) {
                if (j < 20) {
                    data1[j] = bb.array()[j];
                } else if (j >= 20 && j < 40) {
                    data2[j - 20] = bb.array()[j];
                } else if (j >= 40 && j < 60) {
                    data3[j - 40] = bb.array()[j];
                } else if (j >= 60 && j < 80) {
                    data4[j - 60] = bb.array()[j];
                } else if (j >= 80 && j < 100) {
                    data5[j - 80] = bb.array()[j];
                } else if (j >= 100 && j < 120) {
                    data6[j - 100] = bb.array()[j];
                } else if (j >= 120 && j < 132) {
                    data7[j - 120] = bb.array()[j];
                }
            }
            ByteBuffer bb2 = ByteBuffer.allocate(data.length + 4).order(
                    ByteOrder.BIG_ENDIAN);
            bb2.put(data1);
            bb2.put(data2);
            bb2.put(data3);
            bb2.put(data4);
            bb2.put(data5);
            bb2.put(data6);
            bb2.put(data7);
    //        Log.e("aris", " <   > bb2.array()" + bb2.array().length + " [] " + bytesToHex(bb2.array()));
            for (int j = 0; j < 7; j++) {
                switch (j) {
                    case 0:
                        writedata(data1);
                        break;
                    case 1:
                        writedata(data2);
                        break;
                    case 2:
                        writedata(data3);
                        break;
                    case 3:
                        writedata(data4);
                        break;
                    case 4:
                        writedata(data5);
                        break;
                    case 5:
                        writedata(data6);
                        break;
                    case 6:
                        writedata(data7);
                        break;
                }
                Thread.sleep(90);
    
            }
    
    
        }
    
        void writedata(byte[] data) {
            Client.write(MAC, UUID.fromString(serviceUUID), UUID.fromString(w_UUID), data, new BleWriteResponse() {
                @Override
                public void onResponse(int code) {
                    if (code == Constants.REQUEST_SUCCESS) {
                        Log.e("aris", "putChar  write  请求成功 " + code);
                    } else if (code == Constants.REQUEST_FAILED) {
                        Log.e("aris", "putChar  write  请求失败 " + code);
                    }
                }
            });
        }
    
    
        private static final char crctable[] = {0x0000, 0x1021, 0x2042, 0x3063,
                0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b,
                0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252,
                0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a,
                0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401,
                0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509,
                0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630,
                0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738,
                0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7,
                0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af,
                0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96,
                0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e,
                0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5,
                0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd,
                0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4,
                0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc,
                0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb,
                0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3,
                0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da,
                0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2,
                0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589,
                0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481,
                0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
                0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0,
                0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f,
                0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827,
                0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e,
                0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16,
                0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d,
                0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45,
                0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c,
                0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
                0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
    
        public static byte calc(byte[] bytes) {
    //        char crc = 0x0000;
            byte crc = 0;
            for (byte b : bytes) {
    //            crc = (char) ((crc << 8) ^ crctable[((crc >> 8) ^ b) & 0x00ff]);
                crc = (byte) (crc + b);
            }
            return crc;
        }
    
    }
    

    其实就是简单的分包,然后在发送。只要注意一下间隔。

    当然还有一个就是校验方式要和嵌入式同学商量好。

    升级是做好了,不过由于速度实在是太慢了,有点鸡肋。一个68KB的升级 .bin,可能需要5-7分钟才能发完。

    这个与BLE每次只能发20字节有直接关系。

    所有固件升级,还是建议利用BLE 的 OTA升级通道。

    展开全文
  • 随着蓝牙版本及编解码技术突破,蓝牙耳机在我们日常生活中已经是十分常见了,听音乐、打电话、玩游戏时都得上蓝牙耳机。虽说大家对耳机需求侧重点有所偏差,但音质作为耳机基础,大家入手耳机时还是会首先...

    随着蓝牙版本及编解码的技术突破,蓝牙耳机在我们日常生活中已经是十分常见了,听音乐、打电话、玩游戏时都用得上蓝牙耳机。虽说大家对耳机的需求侧重点有所偏差,但音质作为耳机的基础,大家入手耳机时还是会首先考虑音质的,所以接下来就分享几款音质不错的蓝牙耳机。

    Xisem西圣Ares

    085c6c264a58f16f9054be7d24d94dc6.png

    Xisem西圣Ares的硬件方面上十分强大,内置了高通QCC3020芯片,其稳定性,传输速率,功耗都具有很大的优势。还支持APTX音频编码技术,再加上实实在在的HIFI金属喇叭6mm全频动圈单元,三频表现更清晰均衡,混重低音,历经两年反复调整校准,紧闭音腔设计,声音立体感更强。

    自身的50mAh充电电池单次续航基本能达到6小时左右,再配合充电仓可续充双耳机3-4次,总续航超过24小时,充电仓+双耳机的续航设计确实在耳机使用粘性上下足了功夫。

    飞利浦(PHILIPS)SHB2505

    967a3679d68f1a6f72d8ca46e491fea0.png

    飞利浦SHB2505采用高性能蓝牙5.0芯片,传输更快、功耗更低、抗干扰性更强、不掉线低延迟。内置高性能的6mm驱动单元,小巧机身也能带来如此澎湃音效,封闭式结构隔绝噪音,更享纯真好音质。斜角45°入耳,人体工程学设计,加上鳍状耳翼,做到了运动不脱落,佩戴更舒适。

    索尼(SONY)WI-H700

    dd51479fa50206674d7a379c504822c7.png

    索尼WI-H700配备了9mm的高灵敏度驱动单元,支持高解析度音频,装载了数字声音增强引擎,可表现出高频信号和音频压缩中丢失的尾音,带来具有空间感的自然音效。弹性硅胶材质的颈挂部分,提供了佩带时颈部的舒适,而且有效防滑,贴心磁扣能方便线缆收纳整理,减少耳机线的缠结。

    AKG N200 WIRELESS

    5afac6d7b634ab51b250f5c5dd8d27eb.png

    AKG N200 WIRELESS采用了高性能的8.6mm动圈驱动单元,通过AKG标志性调音,可带来三频适中、解析细腻、动态声场出色和增强型的低音响应,适用于聆听各类高解析度清新风格歌曲。支持aptx、AAC蓝牙音频编解码协议,可通过高性能、无损压缩算法,确保能通过蓝牙音频设备获得CD级音质。

    展开全文
  • 哪位大神有--蓝牙用PBAP协议获取电话簿demo,小弟在网上实在是找不到,大神们帮帮忙!也可以发我邮箱381534138@qq.com 非常感谢!!![img=...
  • 蓝牙蓝牙协议

    2019-09-06 13:46:33
    最后,它定义了如何不同类型地址来实现隐私性和可解析性。 ATT协议(属性协议):定义了客户端与服务器如何相互发送符合标准消息; GATT(通用属性协议):定义了如何发现和使用服务。特性和描述符标准方法。 ....

    gap协议(通用属性规范):定义了设备如何彼此发现、建立连接以及如何实现绑定,同同时描述了设备如何成为广播者和观察者,并且实现无需连接的数据传输。最后,它定义了如何用不同类型的地址来实现隐私性和可解析性。 

    ATT协议(属性协议):定义了客户端与服务器如何相互发送符合标准的消息;

    GATT(通用属性协议):定义了如何发现和使用服务。特性和描述符的标准方法。

    展开全文
  • 刚接触蓝牙,现在想做个蓝牙血压计app,有蓝牙血压计传输协议,怎么用蓝牙血压计里面口令进行app与血压计交互呢,求大神们指点迷津!
  • 主要介绍下Linux ubuntu虚拟机外接我们的蓝牙扩展版跑蓝牙协议初始化以及搜索演示 一. 声明 本专栏文章我们会以连载方式持续更新,本专栏计划更新内容如下: 第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些...

    零. 概述

    主要介绍下用Linux ubuntu虚拟机外接我们的蓝牙扩展版跑蓝牙协议栈的初始化以及搜索演示

    一. 声明

    本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下:

    第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。

    第二篇:Transport层介绍,主要介绍蓝牙协议栈跟蓝牙芯片之前的硬件传输协议,比如基于UART的H4,H5,BCSP,基于USB的H2等

    第三篇:传统蓝牙controller介绍,主要介绍传统蓝牙芯片的介绍,包括射频层(RF),基带层(baseband),链路管理层(LMP)等

    第四篇:传统蓝牙host介绍,主要介绍传统蓝牙的协议栈,比如HCI,L2CAP,SDP,RFCOMM,HFP,SPP,HID,AVDTP,AVCTP,A2DP,AVRCP,OBEX,PBAP,MAP等等一系列的协议吧。

    第五篇:低功耗蓝牙controller介绍,主要介绍低功耗蓝牙芯片,包括物理层(PHY),链路层(LL)

    第六篇:低功耗蓝牙host介绍,低功耗蓝牙协议栈的介绍,包括HCI,L2CAP,ATT,GATT,SM等

    第七篇:蓝牙芯片介绍,主要介绍一些蓝牙芯片的初始化流程,基于HCI vendor command的扩展

    第八篇:附录,主要介绍以上常用名词的介绍以及一些特殊流程的介绍等。

    另外,开发板如下所示,对于想学习蓝牙协议栈的最好人手一套。以便更好的学习蓝牙协议栈,相信我,学完这一套视频你将拥有修改任何协议栈的能力(比如Linux下的bluez,Android下的bluedroid)。

    -------------------------------------------------------------------------------------------------------------------------

    CSDN学院链接(进入选择你想要学习的课程):https://edu.csdn.net/lecturer/5352?spm=1002.2001.3001.4144

    蓝牙交流扣扣群:970324688

    Github代码:https://github.com/sj15712795029/bluetooth_stack

    入手开发板:https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22329603896.18.5aeb41f973iStr&id=622836061708

    蓝牙学习目录https://blog.csdn.net/XiaoXiaoPengBo/article/details/107727900

    --------------------------------------------------------------------------------------------------------------------------

    演示视频点击我(!!!!!!!!!!!!!!!!)

    二. ubuntu虚拟机 蓝牙协议栈封装使用AT command实现搜索

    使用步骤操作如下:(Linux ubuntu虚拟机外接蓝牙扩展点击链接)!!!!!!!!!!!!!!!!!!!!

    步骤 1)准备好代码,从github下载下来最新的代码(在上面有):

    步骤 2)连接好硬件

    需要找一个带流控的串口板来接线,接线是:

    VCC 5V供电,GND接到GND,TX接到TX,RX接到RX,CTS接到CTS,RTS接到RTS

    可能你会问为啥TX是接TX,RX接RX,CTS接CTS,RTS接RTS,而不是TX接RX,RX接TX,CTS接RTS,RTS接CTS

    步骤 3)把代码放到ubuntu主机主机上,打开Linux工程

    1-BLUETOOTH\project\ubuntu_csr8x11_bt,然后直接make编译,他会编译出来一个bt_demo

    步骤 4)把硬件插入到ubuntu,改下ttyUSB0的权限(sudo chmod 777 /dev/ttyUSB0)(否则不能通信)

    步骤 5)执行./bt_demo等初始化通过后,然后敲BT_INQUIRY来搜索就行了

    三. 实现原理

    步骤1)实现串口监测

    void stdin_process_init()
    {
    
        pthread_t thread_stdin_id;
        pthread_create(&thread_stdin_id, NULL, stdin_process_thread, NULL);
    }
    void *stdin_process_thread(void *data)
    {
    
        while(1)
        {
            fd_set read_fd;
            int result = 0;
    
            /* monitor uart rx */
            FD_ZERO (&read_fd);
            FD_SET (0, &read_fd);
    
            if ((result = select (1, &read_fd, NULL, NULL, NULL)) == -1)
            {
                printf("ERROR:file[%s],function[%s],line[%d] select fail\n",__FILE__,__FUNCTION__,__LINE__);
            }
    
            if(result > 0 && FD_ISSET ( 0, &read_fd))
            {
    
                memset(stdin_buf,0,STDIN_BUF_SIZE);
                int read_result = read(0,stdin_buf,STDIN_BUF_SIZE);
                stdin_recv_len = read_result;
                //printf("--------1---------len %d\n",read_result);
                //bt_hex_dump(stdin_buf,read_result);
                //printf("--------2----------\n");
    
            }
        }
    }

    大概原理就是先创建一个thread,然后一直监听stdin,也就是fd 0,监听到有输入,然后就把他放在stdin_buf

    步骤 2)stdin buffer的解析

    void stdin_process_run()
    {
        if(stdin_recv_len != 0)
        {
            shell_parse(stdin_buf);
            stdin_recv_len = 0;
        }
    }
    uint8_t shell_parse(uint8_t *shell_string)
    {
    
        ....
    
        if(strncmp(BT_INQUIRY_CMD,(const char*)shell_string,strlen(BT_INQUIRY_CMD)) == 0)
        {
            printf("SHELL:operate bt inquiry\n");
            bt_start_inquiry(0x30,HCI_INQUIRY_MAX_DEV);
            return 0;
        }
    }

    然后这样就实现了AT跟协议栈的对接

    展开全文
  • 蓝牙4.0BLE协议

    2016-11-01 14:57:38
    蓝牙4.0BLE协议与协议栈的关系 ...蓝牙4.0BLE协议栈就是将各个层定义的协议都集合在一起,以函数的形式实现,并提供一些应用层API,供用户调用。 注意:虽然协议是统一的,但是协议的具体实现形式是变化
  • 完整的蓝牙应用协议。。包括各种版本的应用协议, 如a2dp的1.0、1.1和1.2版本等。 所需的就是有用的,希望给大家上~!我们的祖国是花园~! 蓝牙应用在4.0之前为标准蓝牙,...我这个包里面完整的包含里面的协议。。
  • 前言:大创项目结题在即却没怎么动手,现在才开始学习,大家不要学我这样...1.什么是蓝牙4.0ble协议栈   协议定义是一些列通信标准,通信双方需要共同按照这一标准进行正常数据收发:协议栈是协议的具体实
  • 蓝牙协议

    2014-01-07 10:02:12
    什么是蓝牙 ...行业组织人员,在经过一夜关于欧洲历史和未来无限技术发展讨论后,有些人认为Blatand国王名字命名再合适不过了。Blatand国王将现在挪威,瑞典和丹麦统一起来;就如同这项即将面世
  • 下发蓝牙链接 ...mac=10.00.00.63.42.42&stationId=10002095&type=test2 参数说明: ...哪个网关进行连接 type 连接类型名,就是刚刚保存test2 下发连接后,基站会反馈此次下发蓝牙
  • 蓝牙协议栈初识

    千次阅读 2018-12-03 10:30:02
    但是信息交互方式在无线连接出现之前只能使用有线连接,比如计算机接入键盘,鼠标,主机,扫描仪,打印机,摄像头等等,如果都是有线连接那就会让你工作台充满电缆,而且既然是有线那么...
  • 先描述一下我这个应用,一根蓝牙笔点击特制杂志上印刷电影名称,比如:点击片名为《金龙鱼葵花籽油5L》视频,蓝牙笔读取到视频名称背后杂志码比如是234567,因为蓝牙笔只能读到指令不可能直接读取到...
  • 蓝牙通讯协议

    千次阅读 2014-08-13 13:39:20
    A2DP(Advanced Audio Distribution Profile)通过蓝牙传递高品质音乐一种协议。 HSP(HeadSet Profile),和A2DP类似,但是HSP是同步传送,A2DP是异步传送,所以A2DP音质会更高一些。HSP一般在手机无线耳机...
  • 它已经逐渐取代有线耳机成为我们标配手机配件了,不管在家还是外出,只要是有听歌、看剧需求,就得上它。国庆也近在眼前,我们闲暇时光就更多了,蓝牙耳机也可以助力我们假期舒适体验,所以今天就给大家推荐几...
  • 国名技术出,供参考蓝牙干货,蓝牙核心协议,学习必备。
  • 生成蓝牙协议的UUID

    2015-05-03 23:30:16
    iOS使用ble时协议中需要定义三个UUID;可以一下方法生成: 打开终端,输入uuidgen即可。
  • 蓝牙4.0BLE协议栈以及分层概述

    千次阅读 2018-05-23 20:29:04
    一、蓝牙4.0协议概念 ...BLE协议栈将各个层定义的协议都集合在一起,以函数库的形式实现,并给用户提供一些应用层 API,供用户调用。 二、BLE协议栈 在 Bluetooth-LE 低功耗蓝牙中有四种设备类型:Central主机、P...
  • 蓝牙协议基础

    2019-09-09 09:24:30
    两个角色:主设备(master) 从设备(slave) 1台主设备最多可同时与7台从设备进行通信,并可以和多达256个从设备保持同步但不通信... 蓝牙设备在某个频点发送数据之后,再跳到另一个频点发送,而频点排列顺序则是伪随...
  • 任务:android编程实现手机通过蓝牙SPP协议同时连接2个蓝牙设备A、B并同时读取A、B数据。 我实现方法:2个蓝牙设备A、B都是SPP server,手机是SPP client。 结果:可以把手机只配对连接A或B,读取数据。如果把...
  • 模式实现,软件实现了基于HID协议的HCI、逻辑链路控制适配协议和服务发现协 议。然后在HID应用规范基础上给出了以串口方式实现键盘和鼠标数据采集硬件和 软件设计,整个系统设计结合蓝牙开发工具BBDK,给出...
  • 不同的蓝牙架构可以在不同场景中。从而协议架构方案也会不同。 转载自:https://www.cnblogs.com/schips/p/12293141.html 《三种蓝牙架构实现方案(蓝牙协议栈方案)》 蓝牙架构实现方案有哪几种?我们...
  • 蓝牙协议源代码(C语言写

    热门讨论 2010-01-08 13:26:52
    蓝牙协议的C源代码,做无线通信也许得着,分享了 !
  • 蓝牙作为一种小范围无线连接技术,能在设备间实现方便快捷、灵活安全、低成本、低...那么,我们经常用的蓝牙,有哪些版本呢?蓝牙版本变化蓝牙1.1版本,传输率约为748~810kpbs,会受到同频率产品的通讯干扰。蓝牙...
  • 本驱动是本人在hisi3521d上交叉编译的蓝牙协议栈驱动移植,已成功在hi3516上的蓝牙开发.希望能帮忙有需要开发同仁.
  • 和平精英职业玩家都什么耳机?好用和平精英蓝牙耳机安利随着各种自媒体...下面小编推荐几款低延迟的蓝牙耳机推荐给大家~推荐一、Nank南卡lite Pro蓝牙耳机售价:399元蓝牙协议:Aptx,AAC,SBC防水等级:IP55级...
  • 所以感觉看着脑袋都大了,所以我萌发了一种,轻快简单文风刨析蓝牙协议架构想法,可能写会很糟糕,但是我觉得就算只有自己看着开心也是足够; 什么是BLE 记得我还是小白时候BT、BLE傻傻稳步清楚,有...
  • 蓝牙技术及其协议蓝牙 (Bluetooth) ...遵循蓝牙协议的各类数据及语音设备将能够微波取代传统网络中错综复杂电缆,非常方便地实现快速、灵活、安全、低代价、低功耗数据和语音通信。由于蓝...
  • 先描述一下我这个应用,一根蓝牙笔点击特制杂志上印刷电影名称,比如:点击片名为《金龙鱼葵花籽油5L》视频,蓝牙笔读取到视频名称背后杂志码比如是234567,因为蓝牙笔只能读到指令不可能直接读取到...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 517
精华内容 206
关键字:

蓝牙用的协议