还在为如何快速开发蓝牙功能发愁?本文手把手教你用Keil和N32WB452官方SDK,30分钟搭建支持自定义服务、双向数据传输的蓝牙通信框架。包含资源占用避坑指南、事件回调实战解析,以及蓝牙调试工具实测效果演示。

1.  新建Keil工程 + SDK移植

1.1 下载Keil环境N32WB452系列PACK包:

https://www.nationstech.com/uploads/Microcontrollers/N32WB452xx_V3.4.0/6-Software_Development_Kit/Nations.N32WB452_DFP.1.1.1.pack

1.2 下载N32WB452系列软件开发包:

https://www.nationstech.com/uploads/Microcontrollers/N32WB452xx_V3.4.0/6-Software_Development_Kit/Nations.N32WB452_Library.2.5.0.zip

1.3  添加keil项目中N32WB452固件库文件

1.3.1  使用蓝牙功能只需拷贝Nations.N32WB452_Library.2.5.0目录以下文件到keil项目

1.3.2 keil项目Lib目录下移植文件

1.3.3  keil项目固件库头文件包含

  1. 如需使用蓝牙功能,需包含基础组件和蓝牙组件
  2. 若不使用蓝牙功能,仅需包含基础组件即可

1.3.4  keil项目固件库.c文件添加

Lib目录结构中,使用ble_前缀区分内核文件与蓝牙核心文件

1.3.5  keil项目全局宏定义

N32WB452,USE_STDPERIPH_DRIVER,N32WB452_BT_API,N32WB452_BT_API0,BLE_OTA_WRITE_CHAR_EN


 

2.  项目开发

2.1  芯片蓝牙应用简介

        N32WB452芯片采用双核架构,M0内核跑蓝牙协议栈,M4内核跑用户逻辑,用户逻辑开发在M4内核。

        在完成上面新建Keil项目 + 蓝牙SDK文件移植编译成功后,就可以进行芯片蓝牙功能开发了。

        以下为N32WB452芯片应用架构 + 蓝牙事件回调机制:

2.2  芯片蓝牙应用资源占用

        蓝牙应用会占用M4内核的 定时器3 + 外部中断EXTI14 + 外部中断EXTI16(可选),用户逻辑不可使用这些资源。     

2.3  芯片蓝牙应用代码开发

        2.3.1  蓝牙基础通信框架

        通过以下配置 + 初始化,你可以实现一个自定义蓝牙名称 + 自定义服务 + 2个特征(接收 + 发送)的基础通信框架,满足大部分的蓝牙通信业务场景需求。

// 添加BLE头文件
#include "n32wb452_ble_api.h"

// 直接使用EXTI14中断函数即可,不用配置
void EXTI15_10_IRQHandler(void)  
{
    if (EXTI_GetStatusFlag(EXTI_LINE14) != RESET) {
        EXTI_ClrITPendBit(EXTI_LINE14);        
        bt_handler();
    }
}

//蓝牙事件回调函数
void bt_envent_callback_func(bt_event_enum event, const uint8_t * data, uint32_t size, uint32_t character_uuid)
{
    switch(event) {
        case BT_EVENT_VERSION:
            break;

        case BT_EVENT_CONNECTED:
            break;

        case BT_EVENT_DISCONNECTD:
            break;

        case BT_EVENT_RCV_DATA:
            break;

        default:
            break;
    }
}

//蓝牙用户服务参数配置
static bt_attr_param bt_init = {
    .ctrl_param = {
        .multi_mode = 0,                                                   
        .reserved = 0,                                                                                                    
    },
    .device_name = "N32WB452_BLE",                                         
    .scan_rsp_data = {13, 9, 'N', '3', '2', 'W', 'B', '4', '5', '2', '_', 'B', 'L', 'E'},    
    .scan_rsp_data_len = 14,                                                
    .device_addr = "11:22:33:44:55:66",
#if 1                               
    .service[0] = { 
        .svc_uuid = 0xfee7,   
        .character[0] = {
            .uuid = 0xfec1,                                               
            .permission = BT_WRITE_PERM | BT_WRITE_REQ_PERM,  
        },
        .character[1] = {
            .uuid = 0xfec2,                                                
            .permission = BT_NTF_PERM,
        }
    },
#else
    .service[0] = {0},
#endif
};


// 调用蓝牙初始化函数,配置蓝牙复位参数 + 注册蓝牙事件回调函数
void Bt_Process_Init(void)
{
    int32_t ret = bt_ware_init(&bt_init, bt_envent_callback_func);
    if (ret != BT_RET_SUCCESS) {
        log_info("bt init error\r\n"); 
    }
    
    //
}

void Bt_Process(void)
{
    // 蓝牙主线性(必须调用)
    bt_run_thread();
}

int main(void)
{
    Bt_Process_Init();
    while(1) {
        Bt_Process();
    }
}

     

2.3.2  蓝牙事件回调函数使用介绍

1.获取蓝牙连接成功状态

2.获取蓝牙断开连接事件

3.接收蓝牙客户端发送的数据

4.发送数据给蓝牙客户端

// 定义蓝牙数据结构体
typedef struct {
    uint16_t rev_length;    // 接收数据长度
    uint8_t rev_buf[128];   // 接收数据缓存
    uint16_t send_length;   // 发送数据长度
    uint8_t send_buf[128];  // 发送数据缓存
    // ...
} ble_para_t;

ble_para_t ble_para;

//蓝牙事件回调函数
void bt_envent_callback_func(bt_event_enum event, const uint8_t * data, uint32_t size, uint32_t character_uuid)
{
    switch(event) {
        case BT_EVENT_VERSION:
            break;

        case BT_EVENT_CONNECTED:
            // 蓝牙连接事件,用户可在此事件中获取连接成功状态
            break;

        case BT_EVENT_DISCONNECTD:
            // 蓝牙连接事件,用户可在此事件中获取断开连接状态
            break;

        case BT_EVENT_RCV_DATA:
            // 接收数据事件,接收客户端发送的数据
            if (USER_IDX_WRITE_NOTIFY_VAL == character_uuid) {
                ble_para.length = bt_rcv_data(bt_para.rev_buf, size, character_uuid);  

                // 发送数据给客户端(可以在接收成功后发送,则可以其它场景下发送)
                bt_snd_data(bt_para.send_buf, bt_para.send_length, USER_IDX_READ_NOTIFY_VAL);
            }
            break;

        default:
            break;
    }
}

3.  BLE通信调试

3.1  BLE调试工具分享:https://www.wch.cn/download/file?id=528

3.2  蓝牙调试软件搜索到的BLE设备端

3.2  蓝牙客户端接收到设备端返回的数据

4.  总结

        通过以上代码,你可以使用N32WB452芯片配置一个具备接收与发送功能的蓝牙设备端项目。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐