蓝牙点灯
书接上回
在上篇文章我们看见了P2P服务的广播名 和 相关的UUID,所以下一步就是蓝牙发送数据了。
所以我们再次结合蓝牙 点灯!!
1 、确认数据接收处
想要使用蓝牙控制灯,我们需要知道蓝牙接到空中的数据后,会将数据传到何处,如何接收数据?

结合上图可以看到 CubeMX可知BLE是在STM32_WPAN下的,所以我们打开Keil 5的对应文件树可以看见有个叫P2P_stm.c的文件,和我们目前添加的功能相同(P2P server)所以不要怀疑直接打开!

/**
* @brief Event handler
* @param Event: Address of the buffer holding the Event
* @retval Ack: Return whether the Event has been managed or not
*/
static SVCCTL_EvtAckStatus_t PeerToPeer_Event_Handler(void *Event)
{
SVCCTL_EvtAckStatus_t return_value;
hci_event_pckt *event_pckt;
evt_blecore_aci *blecore_evt;
aci_gatt_attribute_modified_event_rp0 * attribute_modified;
P2PS_STM_App_Notification_evt_t Notification;
return_value = SVCCTL_EvtNotAck;
event_pckt = (hci_event_pckt *)(((hci_uart_pckt*)Event)->data);
switch(event_pckt->evt)
{
case HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE:
{
blecore_evt = (evt_blecore_aci*)event_pckt->data;
switch(blecore_evt->ecode)
{
case ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE:
{
attribute_modified = (aci_gatt_attribute_modified_event_rp0*)blecore_evt->data;
if(attribute_modified->Attr_Handle == (aPeerToPeerContext.P2PNotifyServerToClientCharHdle + 2))
{
/**
* Descriptor handle
*/
return_value = SVCCTL_EvtAckFlowEnable;
/**
* Notify to application
*/
if(attribute_modified->Attr_Data[0] & COMSVC_Notification)
{
Notification.P2P_Evt_Opcode = P2PS_STM__NOTIFY_ENABLED_EVT;
P2PS_STM_App_Notification(&Notification);
}
else
{
Notification.P2P_Evt_Opcode = P2PS_STM_NOTIFY_DISABLED_EVT;
P2PS_STM_App_Notification(&Notification);
}
}
........................
在P2P_stm.c的100行,可以看见以上代码。
以下是我个人 感觉 分析(不准确,仅供参考)
PeerToPeer_Event_Handler 这个函数时各个事件的处理
HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE 是蓝牙传输层的事件
ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE
GATT 是一个在蓝牙连接之上的发送和接收很短的数据段的通用规范
attribute_modified->Attr_Handle == (aPeerToPeerContext.P2PNotifyServerToClientCharHdle + 2)
Handle是用于区分不同服务的数据。举一个不正确的例子,翻遍理解,比如说 HID服务的Handle是1,P2P服务的Handle是2,那么我在接收数据时,就要区分是什么服务发送的数据,再去做相应的处理。
attribute_modified->Attr_Data[0]这个看起来就是蓝牙接收的数据
所以我认为这里就是蓝牙接收数据的地方,分析完毕,我们需要大胆的尝试,验证我们的思路!!
2、任意数据翻转IO电平
我想在接收到任意蓝牙数据后就翻转IO电平,点亮或熄灭电平,代码如下:
代码
switch(event_pckt->evt)
{
case HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE:
{
blecore_evt = (evt_blecore_aci*)event_pckt->data;
switch(blecore_evt->ecode)
{
case ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE:
{
attribute_modified = (aci_gatt_attribute_modified_event_rp0*)blecore_evt->data;
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);
实验
1、连接后,展开服务列表,点击发送服务

2、填入数据,并点击 发送

3、点击发送后,向右滑,就可以看见发送的数据。

发送数据后观察开发板上的灯,有熄灭,再次重复以上发送数据流程,可以看见灯在翻转电平,
反复亮->灭。
3、指定数据翻转电平
结合上文可知,我认为attribute_modified->Attr_Data[0]这个就是蓝牙接收到的数据
case ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE:
{
attribute_modified = (aci_gatt_attribute_modified_event_rp0*)blecore_evt->data;
if(attribute_modified->Attr_Data[0] == 0x66)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);
}
所以将代码改为以上,判断等于0x66 与否,控制翻转电平。
发送数据后观察开发板上的灯,有熄灭,再次重复以上发送数据流程,可以看见灯在翻转电平,
反复亮->灭。
至此蓝牙点灯教程完毕!!