在做的项目本身只是需要用到蓝牙从机就行,从机项目开发已基本要收尾了。考虑到要配合产线系统做自动化测试,因此需要一个配合从机的主机dongle供自动化测试系统使用。

蓝牙主机的使用只要按主机和从机的通信流程来走的话各家的蓝牙软件流程基本差不多,都是围绕主机扫描----主机连接-----(主从交换mtu等phy参数)-------主机遍历从机的service------主机遍历所需要service下的char记录下需要char的handle值以及同时找出支持notify的char handler-----对支持notify/indicate的char进行使能-----------对所需要的char进行read write

代码上的大体流程主要如下

1、主机角色初始化,扫描连接及启动遍历service

GAPRole_CentralInit();
// Initialize GATT Client
GATT_InitClient();
//注册相关回调
GAPRole_CentralStartDevice(centralTaskId, &centralBondCB, &centralRoleCB);回调定义
// GAP Role Callbacks
static gapCentralRoleCB_t centralRoleCB = {centralRssiCB,        // RSSI callbackcentralEventCB,       // Event callbackcentralHciMTUChangeCB // MTU change callback
};和蓝牙通信连接相关的主要回调,扫描 连接等状态的切换主要都在该回调里
static void centralEventCB(gapRoleEvent_t *pEvent)
{switch(pEvent->gap.opcode){case GAP_DEVICE_INIT_DONE_EVENT:{PRINT("Discovering...\n");GAPRole_CentralStartDiscovery(DEFAULT_DISCOVERY_MODE,DEFAULT_DISCOVERY_ACTIVE_SCAN,DEFAULT_DISCOVERY_WHITE_LIST);}break;case GAP_DEVICE_INFO_EVENT:{// Add device to listPRINT("Add device to list...\n");centralAddDeviceInfo(pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType);}break;case GAP_DEVICE_DISCOVERY_EVENT:{uint8_t i;PRINT("centralScanRes:%d...\r\n",centralScanRes);// See if peer device has been discoveredfor(i = 0; i < centralScanRes; i++){if(tmos_memcmp(PeerAddrDef, centralDevList[i].addr, B_ADDR_LEN))break;}// Peer device not foundif(i == centralScanRes){PRINT("Device not found...\n");centralScanRes = 0;GAPRole_CentralStartDiscovery(DEFAULT_DISCOVERY_MODE,DEFAULT_DISCOVERY_ACTIVE_SCAN,DEFAULT_DISCOVERY_WHITE_LIST);PRINT("Discovering...\n");}// Peer device foundelse{PRINT("Device found...\n");GAPRole_CentralEstablishLink(DEFAULT_LINK_HIGH_DUTY_CYCLE,DEFAULT_LINK_WHITE_LIST,centralDevList[i].addrType,centralDevList[i].addr);// Start establish link timeout eventtmos_start_task(centralTaskId, ESTABLISH_LINK_TIMEOUT_EVT, ESTABLISH_LINK_TIMEOUT);PRINT("Connecting...\n");}}break;case GAP_LINK_ESTABLISHED_EVENT:{PRINT("GAP_LINK_ESTABLISHED_EVENT...\n");tmos_stop_task(centralTaskId, ESTABLISH_LINK_TIMEOUT_EVT);if(pEvent->gap.hdr.status == SUCCESS){centralState = BLE_STATE_CONNECTED;centralConnHandle = pEvent->linkCmpl.connectionHandle;centralProcedureInProgress = TRUE;central_gattdiscover_start();//连接上后开始遍历serveice和char// Initiate service discoverytmos_start_task(centralTaskId, START_SVC_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY);// See if initiate connect parameter updateif(centralParamUpdate){tmos_start_task(centralTaskId, START_PARAM_UPDATE_EVT, DEFAULT_PARAM_UPDATE_DELAY);}// See if initiate connect parameter updateif(centralPhyUpdate){tmos_start_task(centralTaskId, START_PHY_UPDATE_EVT, DEFAULT_PHY_UPDATE_DELAY);}// See if start RSSI pollingif(centralRssi){tmos_start_task(centralTaskId, START_READ_RSSI_EVT, DEFAULT_RSSI_PERIOD);}PRINT("Connected...\n");}else{PRINT("Connect Failed...Reason:%X\n", pEvent->gap.hdr.status);PRINT("Discovering...\n");centralScanRes = 0;GAPRole_CentralStartDiscovery(DEFAULT_DISCOVERY_MODE,DEFAULT_DISCOVERY_ACTIVE_SCAN,DEFAULT_DISCOVERY_WHITE_LIST);}}break;case GAP_LINK_TERMINATED_EVENT:{centralState = BLE_STATE_IDLE;centralConnHandle = GAP_CONNHANDLE_INIT;centralDiscState = BLE_DISC_STATE_IDLE;centralCharHdl = 0;centralScanRes = 0;centralProcedureInProgress = FALSE;tmos_stop_task(centralTaskId, START_READ_RSSI_EVT);PRINT("Disconnected...Reason:%x\n", pEvent->linkTerminate.reason);PRINT("Discovering...\n");GAPRole_CentralStartDiscovery(DEFAULT_DISCOVERY_MODE,DEFAULT_DISCOVERY_ACTIVE_SCAN,DEFAULT_DISCOVERY_WHITE_LIST);}break;case GAP_LINK_PARAM_UPDATE_EVENT:{PRINT("Param Update...\n");}break;case GAP_PHY_UPDATE_EVENT:{PRINT("PHY Update...\n");}break;case GAP_EXT_ADV_DEVICE_INFO_EVENT:{// Display device addrPRINT("AddrType:%d Recv ext adv - Addr %x %x %x %x %x %x \n", pEvent->deviceExtAdvInfo.addrType,pEvent->deviceExtAdvInfo.addr[0],pEvent->deviceExtAdvInfo.addr[1], pEvent->deviceExtAdvInfo.addr[2],pEvent->deviceExtAdvInfo.addr[3], pEvent->deviceExtAdvInfo.addr[4],pEvent->deviceExtAdvInfo.addr[5]);}break;case GAP_DIRECT_DEVICE_INFO_EVENT:{// Display device addrPRINT("AddrType:%d Recv direct adv - Addr %x %x %x %x %x %x \n", pEvent->deviceExtAdvInfo.addrType, pEvent->deviceExtAdvInfo.addr[0],pEvent->deviceExtAdvInfo.addr[1], pEvent->deviceExtAdvInfo.addr[2],pEvent->deviceExtAdvInfo.addr[3], pEvent->deviceExtAdvInfo.addr[4],pEvent->deviceExtAdvInfo.addr[5]);}break;default:break;}
}

2、遍历service和char

//遍历所有service
GATT_DiscAllPrimaryServices(centralConnHandle,centralTaskId );遍历完成会通过centralProcessGATTMsg传递系统消息SYS_EVENT_MSG给用户层进行解析//如下从系统消息里解析出来遍历到需要的service hander值
if( ( pMsg->method ==  ATT_READ_BY_GRP_TYPE_RSP) && ( pMsg->msg.readByGrpTypeRsp.numGrps > 0 ) ){for(unsigned char i = 0 ; i < pMsg->msg.readByGrpTypeRsp.numGrps;i++){uint8_t *p_uuid = &(pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i + 4]);uint8_t uuid_length = pMsg->msg.readByGrpTypeRsp.len - 4;if(uuid_length == sizeof(TheFind_ServiceUUID)){if(tmos_memcmp(TheFind_ServiceUUID,p_uuid,uuid_length)) {centralSvcStartHdl = BUILD_UINT16( pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i], \pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i + 1]);centralSvcEndHdl = BUILD_UINT16( pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i+2], \pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i + 3]);}}}}

找到service后开始遍历char

//遍历所有char找到自己要用的char handler值
GATT_DiscAllChars(centralConnHandle,centralSvcStartHdl,centralSvcEndHdl,centralTaskId);//同样也是通过系统消息传递遍历后的结果if ( pMsg->method == ATT_READ_BY_TYPE_RSP ){if(pMsg->msg.readByTypeRsp.numPairs > 0 ){for(unsigned char i = 0; i < pMsg->msg.readByTypeRsp.numPairs ; i++){uint16_t char_value_handle = BUILD_UINT16(pMsg->msg.readByTypeRsp.pDataList[pMsg->msg.readByTypeRsp.len * i+3], \pMsg->msg.readByTypeRsp.pDataList[pMsg->msg.readByTypeRsp.len * i + 4]);//characteristic uuid lengthuint8_t char_uuid_length = pMsg->msg.readByGrpTypeRsp.len - 5;//uuiduint8_t *chat_uuid = &(pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i + 5]);                          if(sizeof(TheFind_CharUUID) == char_uuid_length){if(tmos_memcmp(TheFind_CharUUID,chat_uuid,char_uuid_length)){TheFind_CharUUID = char_value_handle;}}}}
}

3、遍历支持notify的char handler

            req.startHandle = centralSvcStartHdl;req.endHandle = centralSvcEndHdl;req.type.len = ATT_BT_UUID_SIZE;req.type.uuid[0] = LO_UINT16(GATT_CLIENT_CHAR_CFG_UUID);req.type.uuid[1] = HI_UINT16(GATT_CLIENT_CHAR_CFG_UUID);GATT_ReadUsingCharUUID( centralConnHandle, &req, centralTaskId );

4、读写char

 void WriteCharHandler(uint8_t* data,uint8_t datalen,uint16_t Handler){attWriteReq_t req;req.cmd = FALSE;req.sig = FALSE;req.handle = Handler;req.len = datalen;req.pValue = GATT_bm_alloc(centralConnHandle, ATT_WRITE_REQ, req.len, NULL, 0);if(req.pValue != NULL){tmos_memcpy(req.pValue,data,datalen);if(GATT_WriteCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS){centralDoWrite = FALSE;}else{GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ);}}}void ReadCharHandler(uint16_t handle){attReadReq_t req;req.handle = handle;GATT_ReadCharValue(centralConnHandle, &req, centralTaskId);}

5、接收notify以及read响应

//接收读写回应以及notify indicate都是通过系统消息进来给用户static void centralProcessGATTMsg(gattMsgEvent_t *pMsg){if(centralState != BLE_STATE_CONNECTED){// In case a GATT message came after a connection has dropped,// ignore the messageGATT_bm_free(&pMsg->msg, pMsg->method);return;}if((pMsg->method == ATT_EXCHANGE_MTU_RSP) ||((pMsg->method == ATT_ERROR_RSP) &&(pMsg->msg.errorRsp.reqOpcode == ATT_EXCHANGE_MTU_REQ))){if(pMsg->method == ATT_ERROR_RSP){uint8_t status = pMsg->msg.errorRsp.errCode;PRINT("Exchange MTU Error: %x\n", status);}centralProcedureInProgress = FALSE;}if(pMsg->method == ATT_MTU_UPDATED_EVENT){PRINT("MTU: %x\n", pMsg->msg.mtuEvt.MTU);}if((pMsg->method == ATT_READ_RSP) ||((pMsg->method == ATT_ERROR_RSP) &&(pMsg->msg.errorRsp.reqOpcode == ATT_READ_REQ))){if(pMsg->method == ATT_ERROR_RSP){uint8_t status = pMsg->msg.errorRsp.errCode;PRINT("Read Error: %x\n", status);}else{// After a successful read, display the read valuePRINT("Read rsp: %x\n", *pMsg->msg.readRsp.pValue);}centralProcedureInProgress = FALSE;}else if((pMsg->method == ATT_WRITE_RSP) ||((pMsg->method == ATT_ERROR_RSP) &&(pMsg->msg.errorRsp.reqOpcode == ATT_WRITE_REQ))){if(pMsg->method == ATT_ERROR_RSP){uint8_t status = pMsg->msg.errorRsp.errCode;PRINT("Write Error: %x\n", status);}else{// Write successPRINT("Write success \n");}centralProcedureInProgress = FALSE;}else if(pMsg->method == ATT_HANDLE_VALUE_NOTI){PRINT("Receive noti: %x\n", *pMsg->msg.handleValueNoti.pValue);}else if(centralDiscState != BLE_DISC_STATE_IDLE){//centralGATTDiscoveryEvent(pMsg);}GATT_bm_free(&pMsg->msg, pMsg->method);}

对蓝牙主从连接以及服务特性发现流程稍微了解下后再来按着流程来理解软件上的流程基本都能很快用起来。

沁恒蓝牙芯片CH58X蓝牙主机的使用相关推荐

  1. 沁恒蓝牙芯片CH58X蓝牙从机的使用

    CH583 是集成 BLE 无线通讯的 32 位 RISC 微控制器.片上集成 2Mbps 低功耗蓝牙 BLE 通讯模块.2 个全速 USB 主机和设备控制器及收发器.2 个 SPI.4 个串口.AD ...

  2. 沁恒微BLE蓝牙主机寻找从机服务及特征值的记录

    1.今天,22年10月10号,两年多的嵌软工作生涯,突然想记录一下工作中软件开发的事. 2.嗯~,先说一下开发需求吧.刚入公司转正不久,导师告诉我要做一个蓝牙主机,能够根据用户输入的设备名称寻找指定的 ...

  3. 沁恒蓝牙芯片CH57x系列学习与应用

    沁恒蓝牙芯片CH57x系列学习与应用 沁恒的蓝牙芯片例程已经将各个函数集合的很高,不同主从机例程的主函数中,往往只有一至两个的函数调用的区别,但是在这一到两个函数中,差别却是很大的. 以沁恒的外设从机 ...

  4. 沁恒触摸蓝牙模块方案测试体验(CH582)

    前段时间看到网上有一个触摸方案的键盘,看起来比较新颖,仔细了解发现是沁恒微电子的芯片和方案,与原厂的工程师联系了一下,原厂也比较大方,直接寄过来一份触摸蓝牙方案demo,听说是一个触摸蓝牙门锁的方案, ...

  5. 沁恒微 蓝牙分析仪 BLE analyzer入门

    资源链接 WCH_BLEAnalyzer.zip - 南京沁恒微电子股份有限公司 默认: 启动抓包 过滤,严格按照添加->筛选来操作 启动筛选: 暂停,双击任意一帧即可获取包详细内容

  6. 第十七届全国大学生智能汽车竞赛 沁恒微电子芯片推荐

    简 介: 南京沁恒为电子公司继续赞助第十七届全国大学生智能车.今年他们不仅提供性能更加优越的RISV-V MCU芯片,同时也推荐使用公司具有特色的无线蓝牙芯片,用于运动智能车作品的调试与跟踪. 关键词 ...

  7. 沁恒CH573开发板上手

    概述 CH573是集成BLE无线通讯的32位RISC-V内核微控制器.片上集成低功耗蓝牙BLE通讯模块.全速USB主机和设备控制器及收发器.SPI.4个串口.ADC.触摸按键检测模块.RTC等丰富的外 ...

  8. 南京沁恒推出的国产 M3 架构芯片与意法半导体 M3 芯片对比

    南京沁恒推出的 Cortex-M3 架构 MCU 包括: CH32F103xx 系列.CH32F203xx 系列.CH32F205xx 系列. CH32F207xx 系列.CH32F208xx 系列. ...

  9. 沁恒CH582M开发板--点亮LED

    硬件准备 1.源地CH582M核心板开发板 RISC-V沁恒WCH蓝牙BLE5.3双路USB 2.双向usb接口/usb-typec数据线 软件准备 1.IDE:mouneriver: http:// ...

最新文章

  1. JAVA——Map基础知识
  2. modbus 台达a2_驱控智造未来 台达重磅发布多款工业自动化新品
  3. C++中的IPv6网络程序设计
  4. c语言的报告一,C语言实验报告(一).doc
  5. php判断post是否xss,PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】...
  6. idea java 远程调试_如何使用 Idea 远程调试 Java 代码
  7. 2021年塔城某施工项目招标公告
  8. Python使用MINIMAX实现自动吃豆人
  9. web调用钉钉待办审批
  10. 拼多多分享好友砍价Java实现_拼多多砍价怎么发到qq?怎么帮好友砍价?
  11. Qt:Label插入图片
  12. Axure幻灯片案例
  13. 最新php面试题及答案
  14. apktool反编译及后续打包
  15. 如何将RTOS系统启动时间做到“毫秒级”?AliOS Things是这样做的
  16. 「Vue自我检验」Vue 组件进阶知识,你了解多少?
  17. python 按照顺序读取文件夹中的图片名称
  18. Java 线程池 8 大拒绝策略,面试必问!
  19. android pdfview,android pdfview运行报错,求大神过来解答。跪谢
  20. Golang 实现Windows服务

热门文章

  1. 如何实现PHP上传视频的功能?(图文+视频)
  2. python笔记二:函数
  3. openharmony中控屏开发6:H3.95超级面板的电路设计1
  4. 虚拟机网络模式(Bridge,Nat)简介
  5. 2009年中国大学计算机专业权威排名
  6. PDF转PPT?只需这两种方法,轻松完成转换
  7. HTML5期末大作业:生活类购物商城网站设计——生活类购物商城模板(2页)
  8. oracle存储过程之数据增删查改及调用
  9. php网站开题报告该怎么答辩,建置Web的管理介面for php,毕业论文设计,答辩ppt,开题报告,外文翻译,硕士研究生...
  10. 【深度学习】ubuntu多环境多版本cuda与cudnn共存切换