ESP32的BLE_SPP

最近在捣鼓这个ESP32的BLE的SPP功能,把自己的心得体会写下来,如果有什么不对的地方欢迎大家来留言讨论。
首先是乐鑫官方的源码地址:
https://github.com/espressif/espidf/tree/30372f5a4ff2c0dfdaad95f544dc36bcdda30b75/examples/bluetooth/bluedroid/ble/ble_spp_server
这个模式的蓝牙是低功耗蓝牙串口传输,它的工作流程是:
1、初始化蓝牙控制器
ret = esp_bt_controller_init(&bt_cfg);
然后使能蓝牙控制器
ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
这个ESP_BTMODE_BLE是使能的模式选择,可以是BLE也可以是BT还可以是两者的共存。
2、初始化蓝牙堆栈
ret = esp_bluedroid_init();
并使能堆栈
ret = esp_bluedroid_enable();
经过以上两个步骤,蓝牙就已经初始化完成了,是不是很简单。
接下来就是一些回调函数了,
这个是GATT的注册回调函数
esp_ble_gatts_register_callback(gatts_event_handler);
这个是GAP的注册回调函数
esp_ble_gap_register_callback(gap_event_handler);
注册应用APP
esp_ble_gatts_app_register(ESP_SPP_APP_ID);
这个函数执行以后蓝牙堆栈会给用户分配一个gatts_if 这个就是我们与蓝牙堆栈的操作端口,这个函数执行以后就会触发esp_ble_gatts_register_callback的ESP_GATTS_REG_EVT事件
static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
{
ESP_LOGI(GATTS_TABLE_TAG, “EVT %d, gatts if %d\n”, event, gatts_if);

//分配一个gatts_if用于和堆栈进行连接
if (event == ESP_GATTS_REG_EVT) {
if (param->reg.status == ESP_GATT_OK) {
spp_profile_tab[SPP_PROFILE_APP_IDX].gatts_if = gatts_if;
} else {
ESP_LOGI(GATTS_TABLE_TAG, “Reg app failed, app_id %04x, status %d\n”,param->reg.app_id, param->reg.status);
return;
}
}

do {
    int idx;
    for (idx = 0; idx < SPP_PROFILE_NUM; idx++) {
    //已经成功的分配一个gatts_if进入到回调函数里面进行操作
        if (gatts_if == ESP_GATT_IF_NONE || 
                gatts_if == spp_profile_tab[idx].gatts_if) {
            if (spp_profile_tab[idx].gatts_cb) {
                spp_profile_tab[idx].gatts_cb(event, gatts_if, param);
            }
        }
    }
} while (0);

}
case ESP_GATTS_REG_EVT:
ESP_LOGI(GATTS_TABLE_TAG, “%s %d\n”, func, LINE);
//设置服务器的名字
esp_ble_gap_set_device_name(SAMPLE_DEVICE_NAME);

    	ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__);
    	广播原始数据
    	esp_ble_gap_config_adv_data_raw((uint8_t *)spp_adv_data, sizeof(spp_adv_data));

    	ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__);
    	创建属性表
    	esp_ble_gatts_create_attr_tab(spp_gatt_db, gatts_if, SPP_IDX_NB, SPP_SVC_INST_ID);
当执行完这个广播原始数据以后会触发gap的回调函数:
case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
//gap开始广播
    esp_ble_gap_start_advertising(&spp_adv_params);
    break;

这样你的手机就可以搜索到这个设备了。
剩下的就是一些读和写事件了
ESP_GATTS_WRITE_EVT
ESP_GATTS_READ_EVT
这些都没什么好说的就是一些读写操作,它的读写数据都存在一个共用体里面,蓝牙堆栈为每一个事件都定义了一个共用体,到时间需要哪个数据直接操作esp_ble_gatts_cb_param_t这个共用体里面的数据就行了。
这一步的重要的是创建这个属性表,官方的文档是这样解释的:
https://github.com/espressif/esp-idf/blob/30372f5a4/examples/bluetooth/bluedroid/ble/gatt_server_service_table/tutorial/Gatt_Server_Service_Table_Example_Walkthrough.md
这个属性表就是一个结构体数组,定义:
esp_attr_control_t attr_control; //这个变量定义的意思为是你的程序回应还是有蓝牙堆栈自动回应
esp_attr_desc_t att_desc; 这个结构体如下:
//表示 UUID 的⻓长度,分 16-bit、 32-bit、 128-bit 三种。这是由于属性UUID 是通过指针进⾏行行传递的,因此需要说明⻓长度。
uint16_t uuid_length;
//表示当前属性的 UUID 的指针,⽤用户根据上⾯面的 UUID ⻓长度,从指针⾥里里⾯面读取指定⻓长度的 UUID 值。
uint8_t *uuid_p;
//表示当前属性的读写许可。该变量量为按位操作,每个⽐比特表示⼀一个特定的读写属性,对不不同⽐比特做或操作,可以表示多种读写属性。例例如PERM_READ | PERM_WRITE 表示这个属性既可读⼜又可写。
uint16_t perm;
//表示当前属性值的最⼤长度,协议栈主要根据这个变量量为该属性分配内存。如果对方写入的属性值超过这里定义的最⼤长度,即回复写错误,错误原因是写⻓度超出数据最⼤长度
uint16_t max_length;
//表示当前属性的当前实际⻓长度。
uint16_t length;
//表示当前属性的属性值初始化值。由于这个参数为指针格式,因此需要从上⾯面的 Length 获取该值的实际⻓长度,从而从指针⾥获得正确的值。
uint8_t *value;
经过以上的步骤基本上蓝牙的一些功能就已经实现了,如果想要收到蓝牙的数据要开启通知。
只要把这个属性表弄明白了,其他也就没什么难度了。以上是我对这个的理解,如有不对的地方,欢迎指教。。。。

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
`esp_ble_gap_periodic_adv_set_params` 是一个 ESP32 蓝牙库中的函数,用于设置周期性广播参数。周期性广播是一种特殊的广播方式,可以在设定的时间间隔内定期发送广播包。 该函数的原型如下: ```c esp_err_t esp_ble_gap_periodic_adv_set_params(esp_ble_gap_periodic_adv_params_t *adv_params); ``` `adv_params` 是一个结构体,包含了周期性广播的参数信息。具体的结构体定义如下: ```c typedef struct { uint16_t interval_min; /*!< Minimum advertising interval */ uint16_t interval_max; /*!< Maximum advertising interval */ uint8_t adv_type; /*!< Advertising type */ uint8_t own_addr_type; /*!< Own address type */ esp_ble_addr_type_t peer_addr_type; /*!< Peer address type */ uint8_t peer_addr[BLE_BD_ADDR_LEN]; /*!< Peer Bluetooth device address */ uint8_t filter_policy; /*!< Advertising filter policy */ } esp_ble_gap_periodic_adv_params_t; ``` 其中,各个参数的含义如下: - `interval_min` 和 `interval_max`:指定周期性广播的最小和最大间隔(单位为 0.625ms)。 - `adv_type`:指定广播类型,可以是 `ESP_BLE_GAP_ADV_TYPE_ADV_IND`(可发现的非直连广播)或 `ESP_BLE_GAP_ADV_TYPE_ADV_DIRECT_IND_HIGH`(高功率直连广播)等。 - `own_addr_type`:指定本机蓝牙地址类型。 - `peer_addr_type`:指定对方蓝牙地址类型。 - `peer_addr`:对方蓝牙设备的地址。 - `filter_policy`:指定广播包过滤策略,可以是 `ESP_BLE_ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY`(允许任意扫描和任意连接)或 `ESP_BLE_ADV_FILTER_ALLOW_SCAN_WLST_CON_ANY`(允许白名单扫描和任意连接)等。 需要注意的是,该函数只能在 BLE 模式下调用,并且应在初始化蓝牙堆栈之后调用。 希望这个回答能解决你的问题,如果还有其他问题,请随时提问!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值