bigbat 发表于 2024-10-29 12:13

【NUCLEO-WB09KE】BLE应用架构与分析

<p><strong>1、测试介绍</strong></p>

<p>(1)测试前说明</p>

<p>为了了解ST BLE设备的编程架构,开始对ST提供的应用进行测试。最开始时使用&ldquo;BLE_Peripheral_Lite&rdquo;应用进行研究,结果该应用出现了配对失败的问题,随即放弃了该应用转而使用BLE_p2pServer应用进行测试。所以下面的测试为该应用的分析和测试。</p>

<p>&nbsp; (2)测试需要的硬件</p>

<p>PC主机:系统为windows 10版本</p>

<p>USB蓝牙适配器:版本为5.4,建议使用勉驱的产品,需要驱动的产品又可能出现兼容问题。</p>

<p>NUCLEO-WB09KE开发板:主要芯片为STM32WB09KE芯片,为低功耗产品ARM m0+内核</p>

<p>(3)测试需要的软件</p>

<p>Bluetooth LE Eplorer:该软件为微软提供的测试产品,虽然功能一般但是较为实用。可以从微软的应用商店免费获得。</p>

<p>BLE_p2pServer:&nbsp;STM32WB0 的演示程序。使用STM32CubeMX复制</p>

<p>ComAssistant串口助手:可以从EE下载,软件为本人编写</p>

<p><strong>2、测试过程</strong></p>

<p>(1)下载安装Bluetooth LE Eplorer软件</p>

<p>&nbsp; 软件比较简洁,只要启动就可以使用了</p>

<p>(2)烧写BLE_p2pServer到开发板</p>

<p>注意:需要将开发板的跳线设置到Boot Loader状态。</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>打开keil软件编译程序,如果可以连接开发板则进行烧写</p>

<p> &nbsp;</p>

<p>烧写到开发板后,重新上电,上电后</p>

<p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>

<p>打开串口连接测试串口波特率:115200,N,8,1</p>

<p>按压B3停止系统指示灯不停闪烁,按压B1开始系统连接状态</p>

<p> &nbsp;</p>

<p>(3)连接配对</p>

<p>将开发板的跳线设置到USER FLASH状态</p>

<p>&nbsp; 进行配对,可以发现设备的PIN码一致,如果:多次配对需要在windows设备管理中删除设备。</p>

<p>&nbsp; 配对成功后</p>

<p>&nbsp; 进行操作,向设备写入0101打开LED1 ,写入0100关闭LED1</p>

<p>&nbsp; 写入命令</p>

<p> &nbsp;</p>

<p><strong>3、程序结构分析</strong></p>

<p>设备功能参数,设备包含三组&ldquo;Service&rdquo;</p>

<p>&nbsp; 服务号:UUID</p>

<p>SERVICE1<br />
&nbsp; UUID:00001801-0000-1000-8000-00805f9b34fb<br />
SERVICE2<br />
&nbsp; UUID:00001800-0000-1000-8000-00805f9b34fb<br />
SERVICE3<br />
&nbsp; UUID:0000fe40-cc7a-482a-984a-7f2ed5b3e58f</p>

<pre>
<code class="language-cpp">#define P2P_SERVER_UUID                        0x8f,0xe5,0xb3,0xd5,0x2e,0x7f,0x4a,0x98,0x2a,0x48,0x7a,0xcc,0x40,0xfe,0x00,0x00
#define LED_C_UUID                        0x19,0xed,0x82,0xae,0xed,0x21,0x4c,0x9d,0x41,0x45,0x22,0x8e,0x41,0xfe,0x00,0x00
#define SWITCH_C_UUID                        0x19,0xed,0x82,0xae,0xed,0x21,0x4c,0x9d,0x41,0x45,0x22,0x8e,0x42,0xfe,0x00,0x00</code></pre>

<p>这个与程序定义的一致。</p>

<pre>
<code class="language-cpp">/* USER CODE BEGIN Header */
/**
******************************************************************************
* @File p2p_server_app.c
* @author MCD Application Team
* @brief p2p_server_app application definition.
******************************************************************************
* @attention *
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "app_common.h"
#include "app_ble.h"
#include "ble.h"
#include "p2p_server_app.h"
#include "p2p_server.h"
#include "stm32_seq.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/

/* USER CODE BEGIN PTD */
typedef struct{
    uint8_t             Device_Led_Selection;
    uint8_t             Led1;
}P2P_LedCharValue_t;

typedef struct{
    uint8_t             Device_Button_Selection;
    uint8_t             ButtonStatus;
}P2P_ButtonCharValue_t;
/* USER CODE END PTD */

typedef enum
{
Switch_c_NOTIFICATION_OFF,
Switch_c_NOTIFICATION_ON,
/* USER CODE BEGIN Service1_APP_SendInformation_t */

/* USER CODE END Service1_APP_SendInformation_t */
P2P_SERVER_APP_SENDINFORMATION_LAST
} P2P_SERVER_APP_SendInformation_t;

typedef struct
{
P2P_SERVER_APP_SendInformation_t   Switch_c_Notification_Status;
/* USER CODE BEGIN Service1_APP_Context_t */
P2P_LedCharValue_t            LedControl;
P2P_ButtonCharValue_t         ButtonControl;
/* USER CODE END Service1_APP_Context_t */
uint16_t            ConnectionHandle;
} P2P_SERVER_APP_Context_t;

/* Private defines -----------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* External variables --------------------------------------------------------*/
/* USER CODE BEGIN EV */

/* USER CODE END EV */

/* Private macros ------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
static P2P_SERVER_APP_Context_t P2P_SERVER_APP_Context;

uint8_t a_P2P_SERVER_UpdateCharData;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
static void P2P_SERVER_Switch_c_SendNotification(void);

/* USER CODE BEGIN PFP */
static void P2P_SERVER_APP_LED_BUTTON_context_Init(void);
/* USER CODE END PFP */

/* Functions Definition ------------------------------------------------------*/
void P2P_SERVER_Notification(P2P_SERVER_NotificationEvt_t *p_Notification)
{
/* USER CODE BEGIN Service1_Notification_1 */

/* USER CODE END Service1_Notification_1 */
switch(p_Notification-&gt;EvtOpcode)
{
    /* USER CODE BEGIN Service1_Notification_Service1_EvtOpcode */

    /* USER CODE END Service1_Notification_Service1_EvtOpcode */

    case P2P_SERVER_LED_C_READ_EVT:
      /* USER CODE BEGIN Service1Char1_READ_EVT */

      /* USER CODE END Service1Char1_READ_EVT */
      break;

    case P2P_SERVER_LED_C_WRITE_NO_RESP_EVT:
      /* USER CODE BEGIN Service1Char1_WRITE_NO_RESP_EVT */
      if(p_Notification-&gt;DataTransfered.p_Payload == 0x01)
      {
      BSP_LED_On(LED_BLUE);
      APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 ON\n");
      P2P_SERVER_APP_Context.LedControl.Led1 = 0x01; /* LED1 ON */
      }
      if(p_Notification-&gt;DataTransfered.p_Payload == 0x00)
      {
      BSP_LED_Off(LED_BLUE);
      APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 OFF\n");
      P2P_SERVER_APP_Context.LedControl.Led1 = 0x00; /* LED1 OFF */
      }
      /* USER CODE END Service1Char1_WRITE_NO_RESP_EVT */
      break;

    case P2P_SERVER_SWITCH_C_NOTIFY_ENABLED_EVT:
      /* USER CODE BEGIN Service1Char2_NOTIFY_ENABLED_EVT */
      P2P_SERVER_APP_Context.Switch_c_Notification_Status = Switch_c_NOTIFICATION_ON;
      APP_DBG_MSG("-- P2P APPLICATION SERVER : NOTIFICATION ENABLED\n");
      APP_DBG_MSG(" \n\r");
      /* USER CODE END Service1Char2_NOTIFY_ENABLED_EVT */
      break;

    case P2P_SERVER_SWITCH_C_NOTIFY_DISABLED_EVT:
      /* USER CODE BEGIN Service1Char2_NOTIFY_DISABLED_EVT */
      P2P_SERVER_APP_Context.Switch_c_Notification_Status = Switch_c_NOTIFICATION_OFF;
      APP_DBG_MSG("-- P2P APPLICATION SERVER : NOTIFICATION DISABLED\n");
      APP_DBG_MSG(" \n\r");
      /* USER CODE END Service1Char2_NOTIFY_DISABLED_EVT */
      break;

    default:
      /* USER CODE BEGIN Service1_Notification_default */

      /* USER CODE END Service1_Notification_default */
      break;
}
/* USER CODE BEGIN Service1_Notification_2 */

/* USER CODE END Service1_Notification_2 */
return;
}

void P2P_SERVER_APP_EvtRx(P2P_SERVER_APP_ConnHandleNotEvt_t *p_Notification)
{
/* USER CODE BEGIN Service1_APP_EvtRx_1 */

/* USER CODE END Service1_APP_EvtRx_1 */

switch(p_Notification-&gt;EvtOpcode)
{
    /* USER CODE BEGIN Service1_APP_EvtRx_Service1_EvtOpcode */

    /* USER CODE END Service1_APP_EvtRx_Service1_EvtOpcode */
    case P2P_SERVER_CONN_HANDLE_EVT :
      P2P_SERVER_APP_Context.ConnectionHandle = p_Notification-&gt;ConnectionHandle;
      /* USER CODE BEGIN Service1_APP_CENTR_CONN_HANDLE_EVT */

      /* USER CODE END Service1_APP_CENTR_CONN_HANDLE_EVT */
      break;
    case P2P_SERVER_DISCON_HANDLE_EVT :
      P2P_SERVER_APP_Context.ConnectionHandle = 0xFFFF;
      /* USER CODE BEGIN Service1_APP_DISCON_HANDLE_EVT */
      P2P_SERVER_APP_LED_BUTTON_context_Init();
      /* USER CODE END Service1_APP_DISCON_HANDLE_EVT */
      break;

    default:
      /* USER CODE BEGIN Service1_APP_EvtRx_default */

      /* USER CODE END Service1_APP_EvtRx_default */
      break;
}

/* USER CODE BEGIN Service1_APP_EvtRx_2 */

/* USER CODE END Service1_APP_EvtRx_2 */

return;
}

void P2P_SERVER_APP_Init(void)
{
P2P_SERVER_APP_Context.ConnectionHandle = 0xFFFF;
P2P_SERVER_Init();

/* USER CODE BEGIN Service1_APP_Init */
UTIL_SEQ_RegTask( 1U &lt;&lt; CFG_TASK_SEND_NOTIF_ID, UTIL_SEQ_RFU, P2P_SERVER_Switch_c_SendNotification);

/**
   * Initialize LedButton Service
   */
P2P_SERVER_APP_Context.Switch_c_Notification_Status= Switch_c_NOTIFICATION_OFF;
P2P_SERVER_APP_LED_BUTTON_context_Init();
/* USER CODE END Service1_APP_Init */
return;
}

/* USER CODE BEGIN FD */
void P2P_SERVER_APP_LED_BUTTON_context_Init(void)
{
BSP_LED_Off(LED_BLUE);
P2P_SERVER_APP_Context.LedControl.Device_Led_Selection=0x01; /* Device1 */
P2P_SERVER_APP_Context.LedControl.Led1=0x00; /* led OFF */
P2P_SERVER_APP_Context.ButtonControl.Device_Button_Selection=0x01;/* Device1 */
P2P_SERVER_APP_Context.ButtonControl.ButtonStatus=0x00;

return;
}
/* USER CODE END FD */

/*************************************************************
*
* LOCAL FUNCTIONS
*
*************************************************************/
__USED void P2P_SERVER_Switch_c_SendNotification(void) /* Property Notification */
{
P2P_SERVER_APP_SendInformation_t notification_on_off = Switch_c_NOTIFICATION_OFF;
P2P_SERVER_Data_t p2p_server_notification_data;

p2p_server_notification_data.p_Payload = (uint8_t*)a_P2P_SERVER_UpdateCharData;
p2p_server_notification_data.Length = 0;

/* USER CODE BEGIN Service1Char2_NS_1*/

if(P2P_SERVER_APP_Context.ButtonControl.ButtonStatus == 0x00)
{
    P2P_SERVER_APP_Context.ButtonControl.ButtonStatus = 0x01;
}
else
{
    P2P_SERVER_APP_Context.ButtonControl.ButtonStatus = 0x00;
}
a_P2P_SERVER_UpdateCharData = 0x01; /* Device Led selection */
a_P2P_SERVER_UpdateCharData = P2P_SERVER_APP_Context.ButtonControl.ButtonStatus;
/* Update notification data length */
p2p_server_notification_data.Length = (p2p_server_notification_data.Length) + 2;

if(P2P_SERVER_APP_Context.Switch_c_Notification_Status == Switch_c_NOTIFICATION_ON)
{
    APP_DBG_MSG("-- P2P APPLICATION SERVER : INFORM CLIENT BUTTON 1 PUSHED\n");
    notification_on_off = Switch_c_NOTIFICATION_ON;
}
else
{
    APP_DBG_MSG("-- P2P APPLICATION SERVER : CAN'T INFORM CLIENT - NOTIFICATION DISABLED\n");
}
/* USER CODE END Service1Char2_NS_1*/

if (notification_on_off != Switch_c_NOTIFICATION_OFF &amp;&amp; P2P_SERVER_APP_Context.ConnectionHandle != 0xFFFF)
{
    P2P_SERVER_NotifyValue(P2P_SERVER_SWITCH_C, &amp;p2p_server_notification_data, P2P_SERVER_APP_Context.ConnectionHandle);
}

/* USER CODE BEGIN Service1Char2_NS_Last*/

/* USER CODE END Service1Char2_NS_Last*/

return;
}

/* USER CODE BEGIN FD_LOCAL_FUNCTIONS*/

/* USER CODE END FD_LOCAL_FUNCTIONS*/
</code></pre>

<p>程序摘抄与p2p_serverApp.c文件。</p>

<pre>
<code class="language-cpp">/* Private function prototypes -----------------------------------------------*/
static void P2P_SERVER_Switch_c_SendNotification(void);

/* USER CODE BEGIN PFP */
static void P2P_SERVER_APP_LED_BUTTON_context_Init(void);</code></pre>

<p>程序中有关键的回调函数:P2P_SERVER_Switch_c_SendNotification,这个函数在收到消息后被调用。</p>

<p>事件的执行如下:</p>

<pre>
<code class="language-cpp">case P2P_SERVER_LED_C_WRITE_NO_RESP_EVT:
      /* USER CODE BEGIN Service1Char1_WRITE_NO_RESP_EVT */
      if(p_Notification-&gt;DataTransfered.p_Payload == 0x01)
      {
      BSP_LED_On(LED_BLUE);
      APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 ON\n");
      P2P_SERVER_APP_Context.LedControl.Led1 = 0x01; /* LED1 ON */
      }
      if(p_Notification-&gt;DataTransfered.p_Payload == 0x00)
      {
      BSP_LED_Off(LED_BLUE);
      APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 OFF\n");
      P2P_SERVER_APP_Context.LedControl.Led1 = 0x00; /* LED1 OFF */
      }
      /* USER CODE END Service1Char1_WRITE_NO_RESP_EVT */
      break;</code></pre>

<p>这里含有一个开关控制:P2P_SERVER_SWITCH_C_NOTIFY_ENABLED_EVT可以扩展该函数。</p>

<p>&nbsp;</p>
页: [1]
查看完整版本: 【NUCLEO-WB09KE】BLE应用架构与分析