本帖最后由 南来之风 于 2024-1-3 20:36 编辑
通过自定义服务,可以利用GAP与GATT协议,创建一个可通过手机app连接到BLE服务。
MCC配置BLE Stack
点击Generate后,生成的代码位于config\default\ble\service_ble\ble_my_lbs_svc.c
#include <stddef.h>
#include "gatt.h"
#include "ble_util/byte_stream.h"
#include "ble_cms/ble_my_lbs_svc.h"
// *****************************************************************************
// *****************************************************************************
// Section: Macros
// *****************************************************************************
// *****************************************************************************
/* Little Endian. */
#define UUID_MY_LBS_PRIMARY_SVC_LE 0xea, 0xce, 0xf4, 0xac, 0x3f, 0x37, 0x11, 0xee, 0xbe, 0x56, 0x02, 0x42, 0xac, 0x08, 0x23, 0x20
#define UUID_MY_LBS_CHARACTERISTIC_0_LE 0xea, 0xce, 0xf4, 0xbc, 0x3f, 0x37, 0x11, 0xee, 0xbe, 0x56, 0x02, 0x42, 0xac, 0x08, 0x23, 0x20
#define UUID_MY_LBS_CHARACTERISTIC_1_LE 0xea, 0xce, 0xf4, 0xcc, 0x3f, 0x37, 0x11, 0xee, 0xbe, 0x56, 0x02, 0x42, 0xac, 0x08, 0x23, 0x20
// *****************************************************************************
// *****************************************************************************
// Section: Local Variables
// *****************************************************************************
// *****************************************************************************
/* Primary Service Declaration */
static const uint8_t s_my_lbsSvcUuid[] = {UUID_MY_LBS_PRIMARY_SVC_LE};
static const uint16_t s_my_lbsSvcUuidLen = sizeof(s_my_lbsSvcUuid);
/* My_lbs Characteristic 0 Characteristic */
static const uint8_t s_my_lbsChar0[] = {ATT_PROP_READ|ATT_PROP_NOTIFY, UINT16_TO_BYTES(MY_LBS_HDL_CHARVAL_0), UUID_MY_LBS_CHARACTERISTIC_0_LE};
static const uint16_t s_my_lbsChar0Len = sizeof(s_my_lbsChar0);
/* My_lbs Characteristic 0 Characteristic Value */
static const uint8_t s_my_lbsUuidChar0[] = {UUID_MY_LBS_CHARACTERISTIC_0_LE};
static uint8_t s_my_lbsChar0Val[] = {};
static uint16_t s_my_lbsChar0ValLen = sizeof(s_my_lbsChar0Val);
/* My_lbs Characteristic 0 Client Characteristic Configuration Descriptor */
static uint8_t s_my_lbsCccChar0[] = {UINT16_TO_BYTES(0x0000)};
static const uint16_t s_my_lbsCccChar0Len = sizeof(s_my_lbsCccChar0);
/* My_lbs Characteristic 1 Characteristic */
static const uint8_t s_my_lbsChar1[] = {ATT_PROP_READ|ATT_PROP_WRITE_REQ, UINT16_TO_BYTES(MY_LBS_HDL_CHARVAL_1), UUID_MY_LBS_CHARACTERISTIC_1_LE};
static const uint16_t s_my_lbsChar1Len = sizeof(s_my_lbsChar1);
/* My_lbs Characteristic 1 Characteristic Value */
static const uint8_t s_my_lbsUuidChar1[] = {UUID_MY_LBS_CHARACTERISTIC_1_LE};
static uint8_t s_my_lbsChar1Val[3] = {0x00, 0xFF, 0x00};
static uint16_t s_my_lbsChar1ValLen = sizeof(s_my_lbsChar1Val);
/* Attribute list for My_lbs service */
static GATTS_Attribute_T s_my_lbsList[] = {
/* Service Declaration */
{
(uint8_t *) g_gattUuidPrimSvc,
(uint8_t *) s_my_lbsSvcUuid,
(uint16_t *) & s_my_lbsSvcUuidLen,
sizeof (s_my_lbsSvcUuid),
0,
PERMISSION_READ
},
/* Characteristic 0 Declaration */
{
(uint8_t *) g_gattUuidChar,
(uint8_t *) s_my_lbsChar0,
(uint16_t *) & s_my_lbsChar0Len,
sizeof (s_my_lbsChar0),
0,
PERMISSION_READ
},
/* Characteristic 0 Value */
{
(uint8_t *) s_my_lbsUuidChar0,
(uint8_t *) s_my_lbsChar0Val,
(uint16_t *) & s_my_lbsChar0ValLen,
sizeof(s_my_lbsChar0Val),
SETTING_MANUAL_READ_RSP|SETTING_UUID_16,
PERMISSION_READ
},
/* Client Characteristic Configuration Descriptor */
{
(uint8_t *) g_descUuidCcc,
(uint8_t *) s_my_lbsCccChar0,
(uint16_t *) & s_my_lbsCccChar0Len,
sizeof (s_my_lbsCccChar0),
SETTING_CCCD,
PERMISSION_READ|PERMISSION_WRITE
},
/* Characteristic 1 Declaration */
{
(uint8_t *) g_gattUuidChar,
(uint8_t *) s_my_lbsChar1,
(uint16_t *) & s_my_lbsChar1Len,
sizeof (s_my_lbsChar1),
0,
PERMISSION_READ
},
/* Characteristic 1 Value */
{
(uint8_t *) s_my_lbsUuidChar1,
(uint8_t *) s_my_lbsChar1Val,
(uint16_t *) & s_my_lbsChar1ValLen,
sizeof(s_my_lbsChar1Val),
SETTING_UUID_16,
PERMISSION_READ|PERMISSION_WRITE
},
};
static const GATTS_CccdSetting_T s_my_lbsCccdSetting[] =
{
{MY_LBS_HDL_CCCD_0, NOTIFICATION},
};
/* My_lbs Service structure */
static GATTS_Service_T s_my_lbsSvc =
{
NULL,
(GATTS_Attribute_T *) s_my_lbsList,
(GATTS_CccdSetting_T const *)s_my_lbsCccdSetting,
MY_LBS_START_HDL,
MY_LBS_END_HDL,
1
};
// *****************************************************************************
// *****************************************************************************
// Section: Functions
// *****************************************************************************
// *****************************************************************************
uint16_t BLE_MY_LBS_Add()
{
return GATTS_AddService(&s_my_lbsSvc, (MY_LBS_END_HDL - MY_LBS_START_HDL + 1));
}
主函数依旧非常精简:
int main ( void )
{
/* Initialize all modules */
SYS_Initialize ( NULL );
//SERCOM0_USART_Write((uint8_t *)"Hello Welcome to WBZ451 World\r\n",strlen("Hello Welcome to WBZ451 World\r\n"));
uart_**();
while ( true )
{
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks ( );
}
/* Execution should not come here during normal operation */
return ( EXIT_FAILURE );
}
特征值写服务:
特征值读服务:
订阅服务测试:
连接断开后重连功能:
void APP_BleGapEvtHandler(BLE_GAP_Event_T *p_event)
{
switch(p_event->eventId)
{
case BLE_GAP_EVT_CONNECTED:
{
/* TODO: implement your application code.*/
SERCOM0_USART_Write((uint8_t *)"Great! ^-^ Connect to GAP Center Device\r\n",strlen("Great! ^-^ Connect to GAP Center Device\r\n"));
ble_gap_connect_state = 1;
G_ConnHandle = p_event->eventField.evtConnect.connHandle;
}
break;
case BLE_GAP_EVT_DISCONNECTED:
{
/* TODO: implement your application code.*/
SERCOM0_USART_Write((uint8_t *)"Ah oh... :( Disconnect to GAP Center Device\r\n",strlen("Ah oh... :( Disconnect to GAP Center Device\r\n"));
ble_gap_connect_state = 0;
G_ConnHandle = 0;
BLE_GAP_SetAdvEnable(0x01, 0x00);
SERCOM0_USART_Write((uint8_t *)"Let me try to GAP Center Device\r\n",strlen("Let me try to GAP Center Device\r\n"));
加入上期测试的OLED,可以显示BLE的连接状态:
BLE未连接的时候:
BLE连接成功的时候:
连接过程演示:
|
|