news 2026/5/1 11:40:14

蓝牙连接例程/蓝牙收发信号引出

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
蓝牙连接例程/蓝牙收发信号引出

文章目录

  • 一、简介
  • 二、蓝牙连接收发例程
    • 1、蓝牙控制指令
    • 2、定义
    • 3、类似例程
    • 4、其他例程
  • 三、指令说明
    • diss
    • diss conn_idx
    • diss scan
    • diss show_dev
    • diss up_conn
    • 其他指令
  • 四、IO映射输出蓝牙收发状态
    • 1、映射引脚选择
    • 2、寄存器配置
    • 3、现象展示

一、简介

这篇文章主要说明内容:
1、蓝牙例程中的连接和控制指令
2、如何将蓝牙收发状态通过IO引脚引出

二、蓝牙连接收发例程

使用例程:example/ble/multi_connection
这个例程集合了蓝牙广播和蓝牙连接等功能,可以实现两块开发板烧录同一个程序并相互连接。

1、蓝牙控制指令

staticvoidble_app_display_command(void){LOG_I("Command list:");LOG_I("diss conn_idx. Connected with advertising index device. Details see: diss conn_idx help.");LOG_I("diss reconn. Reconnected last initial connected device.");LOG_I("diss scan. Scan advertising device. Details see: diss scan help.");LOG_I("diss search_svc [dev_idx] [len] [uuid]. Search GATT service with speicifed uuid for peer device.");LOG_I("diss up_conn [dev_idx] [interval max in ms] [interval min in ms] [latency] [supervision timeout in ms]. Update connection parameter.");LOG_I("diss up_phy [dev_idx] [phy, 0:1M, 1:2M, 2:coded]. Update physical.");LOG_I("diss up_len [dev_idx] [tx_octets] [tx_time]. Update data length.");LOG_I("diss exch_mtu [dev_idx]. Trigger exchange MTU.");LOG_I("diss show_dev. Show all connected device with device index.");LOG_I("diss bond [dev_idx]. Bonded peer device.");LOG_I("diss delete all_bond. Delete all bonded devices.");LOG_I("diss show_rmt_service [dev_idx]. Show last searched service.");LOG_I("diss read_val [dev_idx] [handle]. Read data via dedicated gatt handle.");LOG_I("diss write_val [dev_idx] [handle] [data_len] [data]. Write data via dedicated gatt handle.");LOG_I("diss adv_update. Updata advertising content.");}

下载好程序后输入diss即可查看指令说明,后面也会详细说明关键指令的使用方式

2、定义

代码前端定义了服务/特征两个由16个HEX值组成的uuid

3、类似例程

BLE centeral and peripheral:与multi_connection非常类似,区别在于多连接。

4、其他例程

1)、BLE iBeacon:蓝牙广播例程,只有蓝牙广播功能,可通过finsh命令修改广播内容和停止或开启广播。没有蓝牙蓝牙接收的功能,且不能被连接。

2)、蓝牙周期广播:与蓝牙广播功能类似,可以通过设置周期性的自动更新广播内容。

三、指令说明

代码支持finsh来实时控制连接等功能,连接上串口并通过串口发送指令即可。

diss

输入后显示说有指令简介。

diss conn_idx

输入后也会提升具体的连接指令说明,这里使用地址连接的方式简单说明
diss conn_idx 0 03fe0070adf3
输入后即可连接到指定地址的设备,每个设备的地址都不相同,可以通过蓝牙搜索软件发现蓝牙设备查看到地址。

diss scan

diss scan start 1 300 1000 500 -50
输入命令后设备会根据设置的扫描间隔、窗口和rssi等参数自动搜索附近的设备

diss show_dev

显示连接的设备信息

diss up_conn

修改可以根据参数修改连接设备的connection interval
可以通过show_dev 查看到修改后的值
diss up_conn 0 150 100 4 4000
设备号:0 最大值:150 最小值:100 尝试次数:4 超时时间:4000

其他指令

其他指令还包括写cccd。读取指定handle值,更新广播信息绑定与解除绑定设备等等。也可以根据需要在下面的代码中添加需求的指令代码。

intcmd_diss(intargc,char*argv[]){app_env_t*env=ble_app_get_env();if(argc>1){if(strcmp(argv[1],"conn_idx")==0){if(strcmp(argv[2],"start")==0){uint8_tidx=atoi(argv[3]);if(idx>env->adv_count||idx==0){LOG_E("Wrongly idx(%d), Shall not equal 0 or exceed maximum idx(%d)",idx,env->adv_count);return0;}uint8_town_addr_type=atoi(argv[4]);uint16_ttimeout=atoi(argv[5])/10;uint16_tconn_itv=atoi(argv[6])*4/5;uint16_tscan_itv=atoi(argv[7])*8/5;uint8_tscan_wd=atoi(argv[8])*8/5;uint8_tret=ble_app_create_connection(&env->adv_addr[idx-1],own_addr_type,timeout,conn_itv,scan_itv,scan_wd);if(ret!=HL_ERR_NO_ERROR)LOG_E("Create connection failed %d",ret);}elseif(strcmp(argv[2],"cancel")==0){ble_gap_cancel_create_connection();}elseif(strcmp(argv[2],"addr")==0){inti;ble_gap_connection_create_param_tconn_param;conn_param.own_addr_type=GAPM_STATIC_ADDR;conn_param.conn_to=500;conn_param.type=GAPM_INIT_TYPE_DIRECT_CONN_EST;conn_param.conn_param_1m.scan_intv=0x30;conn_param.conn_param_1m.scan_wd=0x30;conn_param.conn_param_1m.conn_intv_max=0x80;conn_param.conn_param_1m.conn_intv_min=0x60;conn_param.conn_param_1m.conn_latency=0;conn_param.conn_param_1m.supervision_to=500;conn_param.conn_param_1m.ce_len_max=100;conn_param.conn_param_1m.ce_len_min=60;conn_param.peer_addr.addr_type=atoi(argv[3]);hex2data(argv[4],conn_param.peer_addr.addr.addr,BD_ADDR_LEN);ble_gap_create_connection(&conn_param);}else{LOG_I("Create connection: diss conn_idx start [idx, select from adv idx] [own_addr_type, 0(public/randam)/1(resolve)]");LOG_I("[super_timeout(ms)] [conn_itv(ms)] [scan_itv(ms)] [scan_wd(ms)]");LOG_I("Create connection via addres: diss conn_idx addr [own_addr_type] [peer_addr, aabbccddeeff]");LOG_I("Cancel connection: diss conn_idx cancel");}}elseif(strcmp(argv[1],"reconn")==0){uint8_tret=ble_app_reconnect();if(ret!=HL_ERR_NO_ERROR)LOG_E("Reconnection failed %d",ret);}elseif(strcmp(argv[1],"scan")==0){if(strcmp(argv[2],"start")==0){ble_gap_scan_start_tscan_param;scan_param.own_addr_type=GAPM_STATIC_ADDR;scan_param.type=GAPM_SCAN_TYPE_OBSERVER;scan_param.dup_filt_pol=atoi(argv[3]);scan_param.scan_param_1m.scan_intv=atoi(argv[4])*8/5;scan_param.scan_param_1m.scan_wd=atoi(argv[5])*8/5;scan_param.duration=atoi(argv[6])/10;scan_param.period=0;env->scan_rssi=atoi(argv[7]);ble_gap_scan_start(&scan_param);}elseif(strcmp(argv[2],"stop")==0){ble_gap_scan_stop();}else{LOG_I("Scan start: diss scan start [dup, 0/1] [interval, ms] [window, ms] [duration, ms] [received_rssi]");LOG_I("Scan stop: diss scan stop");}}elseif(strcmp(argv[1],"search_svc")==0){inti,len;uint8_tuuid[128]={0};uint8_tidx=(uint16_t)atoi(argv[2]);if(idx>BLE_APP_MAX_CONN_COUNT)LOG_E("Wrongly device index(%d)",idx);len=atoi(argv[3]);hex2data(argv[4],uuid,len);//sibles_attm_convert_to128(uuid, uuid, len);sibles_search_service(env->conn[idx].conn_idx,len,uuid);}elseif(strcmp(argv[1],"up_conn")==0){ble_gap_update_conn_param_tconn_para;uint8_tidx=(uint16_t)atoi(argv[2]);if(idx>BLE_APP_MAX_CONN_COUNT)LOG_E("Wrongly device index(%d)",idx);conn_para.conn_idx=env->conn[idx].conn_idx;conn_para.intv_max=(uint16_t)atoi(argv[3])*4/5;conn_para.intv_min=(uint16_t)atoi(argv[4])*4/5;// value = argv * 1.25conn_para.ce_len_max=0x100;conn_para.ce_len_min=0x1;conn_para.latency=(uint16_t)atoi(argv[5]);conn_para.time_out=(uint16_t)atoi(argv[6])/10;ble_gap_update_conn_param(&conn_para);}elseif(strcmp(argv[1],"up_phy")==0){ble_gap_update_phy_tphy;uint8_tidx=(uint16_t)atoi(argv[2]);if(idx>BLE_APP_MAX_CONN_COUNT)LOG_E("Wrongly device index(%d)",idx);phy.conn_idx=env->conn[idx].conn_idx;phy.rx_phy=1<<atoi(argv[3]);phy.tx_phy=1<<atoi(argv[3]);phy.phy_opt=0;ble_gap_update_phy(&phy);}elseif(strcmp(argv[1],"up_len")==0){ble_gap_update_data_len_tdata_len;uint8_tidx=(uint16_t)atoi(argv[2]);if(idx>BLE_APP_MAX_CONN_COUNT)LOG_E("Wrongly device index(%d)",idx);data_len.conn_idx=env->conn[idx].conn_idx;data_len.tx_octets=(uint16_t)atoi(argv[3]);data_len.tx_time=(uint16_t)atoi(argv[4]);ble_gap_update_data_len(&data_len);}elseif(strcmp(argv[1],"exch_mtu")==0){uint8_tidx=(uint16_t)atoi(argv[2]);if(idx>BLE_APP_MAX_CONN_COUNT)LOG_E("Wrongly device index(%d)",idx);sibles_exchange_mtu(env->conn[idx].conn_idx);}elseif(strcmp(argv[1],"show_dev")==0){ble_app_display_connected_device(env);}elseif(strcmp(argv[1],"show_rmt_service")==0){uint8_tidx=(uint16_t)atoi(argv[2]);if(idx>BLE_APP_MAX_CONN_COUNT)LOG_E("Wrongly device index(%d)",idx);ble_app_display_service(&env->conn[idx].svc);}elseif(strcmp(argv[1],"delete")==0){if(strcmp(argv[2],"all_bond")==0){connection_manager_delete_all_bond();}}elseif(strcmp(argv[1],"read_val")==0){uint8_tidx=(uint16_t)atoi(argv[2]);if(idx>BLE_APP_MAX_CONN_COUNT)LOG_E("Wrongly device index(%d)",idx);sibles_read_remote_value_req_tvalue;value.read_type=SIBLES_READ;value.handle=(uint16_t)atoi(argv[3]);value.length=0;value.offset=0;int8_tret=sibles_read_remote_value(env->conn[idx].rmt_svc_hdl,env->conn[idx].conn_idx,&value);if(ret!=0)LOG_E("Read remote value ");}elseif(strcmp(argv[1],"write_val")==0){uint8_tidx=(uint16_t)atoi(argv[2]);if(idx>BLE_APP_MAX_CONN_COUNT)LOG_E("Wrongly device index(%d)",idx);sibles_write_remote_value_tvalue;value.handle=(uint16_t)atoi(argv[3]);value.write_type=SIBLES_WRITE;value.len=(uint16_t)atoi(argv[4]);uint8_t*w_data=malloc(value.len);RT_ASSERT(w_data);hex2data(argv[5],w_data,value.len);LOG_HEX("write context",16,w_data,value.len);value.value=(uint8_t*)w_data;int8_tret=sibles_write_remote_value(env->conn[idx].rmt_svc_hdl,env->conn[idx].conn_idx,&value);if(ret!=0)LOG_E("Write remote value ");free(w_data);}elseif(strcmp(argv[1],"write_test")==0){uint8_tidx=(uint16_t)atoi(argv[2]);uint16_thandle=(uint16_t)atoi(argv[3]);uint32_tdata_count=(uint16_t)atoi(argv[4]);uint32_tdata_length=(uint16_t)atoi(argv[5]);LOG_I("test start %d %d %d %d",idx,handle,data_count,data_length);ble_write_to_remote_master(idx,handle,data_count,data_length);LOG_I("test end");}elseif(strcmp(argv[1],"bond")==0){uint8_tidx=(uint16_t)atoi(argv[2]);if(idx>BLE_APP_MAX_CONN_COUNT)LOG_E("Wrongly device index(%d)",idx);connection_manager_create_bond(env->conn[idx].conn_idx);}elseif(strcmp(argv[1],"write_cccd")==0){uint8_tconn_idx=(uint8_t)atoi(argv[2]);uint16_twrite_handle=(uint16_t)atoi(argv[3]);write_cccd(conn_idx,write_handle);}elseif(strcmp(argv[1],"adv_update")==0){update_adv_content();}else{ble_app_display_command();}}return0;}FINSH_FUNCTION_EXPORT_ALIAS(cmd_diss,__cmd_diss,My device information service.);

四、IO映射输出蓝牙收发状态

也许会有人需求将蓝牙收发的状态信息,这在用户手册的16.2/16.3小节中有提及。
蓝牙收发状态的信息可以由TX_ACTIVE(蓝牙发送时信号位高电平) RX_ACTIVE(蓝牙接收时信号为高电平)表示,且可以通过IO映射用于控制外部控制模块

1、映射引脚选择

我们需要选择手册中指定的IO口,且TX、RX信号应当配对选择,这里以PA40和PA39为例。
接下来只需根据表格配置对应寄存器的值为指定值即可。

2、寄存器配置

配置寄存器前需要先将芯片的小核保持唤醒状态,这使用到强制唤醒的代码。保证配置的小核的寄存器不会被重新覆盖。
唤醒代码:HAL_HPAON_WakeCore(CORE_ID_LCPU);
配置完成烧录后即可通过引脚查看收发状态。

HAL_HPAON_WakeCore(CORE_ID_LCPU);/* PAD_40 TX_ATIVE */hwp_pinmux1->PAD_PA40&=~0xf;hwp_pinmux1->PAD_PA40|=0x9;hwp_lpsys_cfg->DBGR&=~0xff0f;hwp_lpsys_cfg->DBGR|=0xff07;hwp_lpsys_cfg->SYSCR&=~0x6;hwp_lpsys_cfg->SYSCR|=0x4;hwp_hpsys_cfg->DBGR&=~0x8000ff0f;hwp_hpsys_cfg->DBGR|=~0x8000ff09;/* PAD_39 RX_ACTIVE */hwp_pinmux1->PAD_PA39&=~0xf;hwp_pinmux1->PAD_PA39|=0x9;hwp_lpsys_cfg->DBGR&=~0xff0f;hwp_lpsys_cfg->DBGR|=0xff07;hwp_lpsys_cfg->SYSCR&=~0x6;hwp_lpsys_cfg->SYSCR|=0x4;hwp_hpsys_cfg->DBGR&=~0x8000ff0f;hwp_hpsys_cfg->DBGR|=~0x8000ff09;

3、现象展示

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 6:00:07

C++基础:Stanford CS106L学习笔记 9 类模板(Class Templates)

目录 9.1 类模板声明9.2 实现类模板9.3 类模板的"怪癖"9.3.1 **typename**​**vs.**​**class**9.3.2 默认参数9.3.3 无类型参数 9.4 const 正确性9.4.1 const方法9.4.2 const接口9.4.3 const重载9.4.4 const\_cast9.4.5 mutable 编写一个int_vector: class int_vect…

作者头像 李华
网站建设 2026/5/1 7:21:27

基于SSM的高校大学生就业平台的设计与实现(开题报告)

毕业论文(设计)开题报告 题目 基于SSM的高校大学生就业平台的设计与实现 题目类别 毕业设计 姓名 专业 计算机科学与技术 班级 计科 学号 一、选题背景及依据(简述国内外研究状况和相关领域中已有的研究成果(文献综述),选题目的、意义,列出主要参考文献) (一)选题背…

作者头像 李华
网站建设 2026/4/21 13:40:00

树的初阶相关知识(上)

一.树概念及结构1.1 树的概念树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。有一个特殊的结点&#xff0…

作者头像 李华
网站建设 2026/5/1 6:29:55

将NeMo模型转换为Triton兼容格式

把微调后的NeMo模型&#xff08;尤其是LoRA微调的Llama 3.1 8B Instruct&#xff09;转换成Triton推理服务器能直接使用的格式。 把这个过程拆解为环境准备、模型转换&#xff08;NeMo→TRT-LLM&#xff09;、Triton模型仓库构建三个核心步骤&#xff0c;给出逐行可执行的操作和…

作者头像 李华
网站建设 2026/5/1 6:28:19

混沌这玩意儿在优化算法里真是万金油。今天咱们拿灰狼算法开刀,手把手给它装10种不同的混沌引擎。先上硬货——代码仓库里直接塞个混沌生成器

10种混沌映射优化灰狼算法&#xff0c;可一键切换&#xff0c;可用于优化所有群智能算法&#xff0c;以灰狼算法为例。 10种混沌映射算法包括&#xff1a;Tent映射、Logistic映射、Cubic映射、chebyshev映射、Piecewise映射、sinusoidal映射、Sine映射&#xff0c;ICMIC映射, C…

作者头像 李华