# BLE_Peripheral_Lite
使用的例程
![1_BLE_Peripheral_Lite_例程](/data/attachment/forum/202411/05/235828yic2bcazbzcw8i22.png.thumb.jpg?rand=2341.0023126874903)
本例程演示了激活最少的蓝牙BLE外设功能的情况下进行蓝牙通讯
蓝牙Lite服务支持,仅仅激活了所需的最低功能(不包括任务序列器、定时器服务器、低功耗管理器等)
测试需要使用安装了ST BLE Sensor手机app应用
连接后,BLE_Peripheral_Lite可以从客户端接收写入消息并向其发送通知
# 程序功能流程
1. 程序开始运行时,使用本地名称 HELLO!进行数据广告
2. 在广告的过程中,绿色LED灯每0.5秒缓慢闪烁一次
3. 只能手机手机应用程序开始扫描
4. 在智能手机应用程序列表中选择 HELLO!设备并连接,绿色led切换速度更快,0.1秒一次
5. 进入P2P服务器界面,然后单击LED图标以打开/关闭LED1,控制的是Nucleo板0的蓝色LED
6. 服务器Nucleo板,每约1秒向智能手机客户端发送一次通知
7. 当外围设备断开连接时,0.5秒一次的广告将重新启动,并且可以再次连接到它
我一直觉得README中应该写的是0.5s一次的广播,但是原文如下,advertising的确是广告,官方的意思应该是让板子实现了模拟广告向外界发送信息的过程
- When the Peripheral device (Nucleo board) is disconnected, advertising is restarted and it is possible to connect to it again.
# 运行中的图示
![2_Hello界面](/data/attachment/forum/202411/05/235829gan60o0ndoc64pdz.jpg.thumb.jpg?rand=9791.716739154863)
![3_控制LED灯界面](/data/attachment/forum/202411/05/235830v3t2cazs4za14tbs.jpg.thumb.jpg?rand=7980.654300361325)
![4_消息通知界面](/data/attachment/forum/202411/05/235830itdtttd48tizijut.jpg.thumb.jpg?rand=5890.085250969341)
# 代码分析
```C++
int main(void)
{
HAL_Init();
SystemClock_Config();
PeriphCommonClock_Config();
MX_GPIO_Init();
MX_RADIO_Init();
MX_RADIO_TIMER_Init();
MX_PKA_Init();
MX_APPE_Init(NULL);
while (1)
{
MX_APPE_Process();
}
}
#define CFG_LPM_SUPPORTED (0)
void MX_APPE_Process(void)
{
VTimer_Process();
BLEStack_Process();
NVM_Process();
PERIPHERAL_LITE_SERVER_Process();
#if (CFG_LPM_SUPPORTED == 1)
PERIPHERAL_LITE_SERVER_Enter_LowPowerMode();
#endif /* CFG_LPM_SUPPORTED */
}
#define ADV_TIMEOUT_MS (500)
#define CONN_TIMEOUT_MS (100)
#define NOTIFICATION_TIMEOUT_MS (1 * 1000)
void PERIPHERAL_LITE_SERVER_Process(void)
{
if (bleAppContext.restartAdv)
{
bleAppContext.restartAdv = FALSE;
APP_BLE_Procedure_Gap_Peripheral(PROC_GAP_PERIPH_ADVERTISE_START_FAST);
}
/* Notification flow every ~ 1 sec */
if (bleAppContext.is_notification_timer_expired)
{
bleAppContext.is_notification_timer_expired = FALSE;
PERIPHERAL_LITE_SERVER_Switch_c_SendNotification();
/* Restart a timer for sending notification from server to client */
HAL_RADIO_TIMER_StartVirtualTimer(&bleAppContext.Notification_mgr_timer_Id, NOTIFICATION_TIMEOUT_MS);
}
/* Led blinking rate */
if (bleAppContext.is_adv_connection_timer_expired)
{
bleAppContext.is_adv_connection_timer_expired = FALSE;
if (bleAppContext.BleApplicationContext_legacy.connectionHandle == 0xFFFF)
{
/* Start a timer for slow led blinking for advertising */
HAL_RADIO_TIMER_StartVirtualTimer(&bleAppContext.Advertising_mgr_timer_Id, ADV_TIMEOUT_MS);
}
else
{
/* Start a timer for fast led blinking for connection */
HAL_RADIO_TIMER_StartVirtualTimer(&bleAppContext.Advertising_mgr_timer_Id, CONN_TIMEOUT_MS);
}
}
}
```
可以看到主函数书中进入了循环MX_APPE_Process()
在这个函数PERIPHERAL_LITE_SERVER_Process()中不断处理Lite BLE的事件
可以看到,是由bleAppContext.is_adv_connection_timer_expired,这个标志位可以看到是否已经被连接,一定是别的地方使得这个标志位产生了变化
通过宏定义可以看到,在广告状态,就是未连接情况下,闪烁频率是500ms,连接后,闪烁频率变为100ms
```C++
uint32_t MX_APPE_Init(void *p_param)
{
UNUSED(p_param);
APP_DEBUG_SIGNAL_SET(APP_APPE_INIT);
#if (CFG_DEBUG_APP_ADV_TRACE != 0)
UTIL_ADV_TRACE_Init();
UTIL_ADV_TRACE_SetVerboseLevel(VLEVEL_L); /* functional traces*/
UTIL_ADV_TRACE_SetRegion(~0x0);
#endif
#if (CFG_LED_SUPPORTED == 1)
Led_Init();
#endif
#if (CFG_DEBUG_APP_TRACE != 0) && (CFG_DEBUG_APP_ADV_TRACE == 0)
COM_InitTypeDef COM_Init =
{
.BaudRate = 115200,
.WordLength= COM_WORDLENGTH_8B,
.StopBits = COM_STOPBITS_1,
.Parity = COM_PARITY_NONE,
.HwFlowCtl = COM_HWCONTROL_NONE
};
BSP_COM_Init(COM1, &COM_Init);
#endif
if (HW_RNG_Init() != HW_RNG_SUCCESS)
{
Error_Handler();
}
HW_AES_Init();
HW_PKA_Init();
APP_BLE_Init();
APP_DEBUG_SIGNAL_RESET(APP_APPE_INIT);
return STM32_BLE_SUCCESS;
}
void APP_BLE_Init(void)
{
ModulesInit();
BLE_Init();
bleAppContext.Device_Connection_Status = APP_BLE_IDLE;
bleAppContext.BleApplicationContext_legacy.connectionHandle = 0xFFFF;
bleAppContext.Advertising_mgr_timer_Id.callback = Adv_Connection;
bleAppContext.is_adv_connection_timer_expired = FALSE;
bleAppContext.Notification_mgr_timer_Id.callback = Notification_Flow;
bleAppContext.is_notification_timer_expired = FALSE;
bleAppContext.restartAdv = FALSE;
APP_DBG_MSG("\n");
APP_DBG_MSG("Services and Characteristics creation\n");
PERIPHERAL_LITE_SERVER_APP_Init();
APP_DBG_MSG("End of Services and Characteristics creation\n");
APP_DBG_MSG("\n");
APP_BLE_Procedure_Gap_Peripheral(PROC_GAP_PERIPH_ADVERTISE_START_FAST);
HAL_RADIO_TIMER_StartVirtualTimer(&bleAppContext.Advertising_mgr_timer_Id, ADV_TIMEOUT_MS);
bleAppContext.connIntervalFlag = 0;
return;
}
static void Adv_Connection(void *arg)
{
BSP_LED_Toggle(LED_GREEN);
bleAppContext.is_adv_connection_timer_expired = TRUE;
return;
}
```
可以看到,bleAppContext.is_adv_connection_timer_expired 标志位是在Adv_Connection函数中被改变了
Adv_Connection函数在APP_BLE_Init蓝牙的初始化中,被赋值作为了一个回调函数作为bleAppContext蓝牙app处理的上下文
并最终是由MX_APPE_Init函数调用,在主函数中被初始化,由此达到了有蓝牙连接控制LED灯闪烁的目的
# 演示视频
11月5日