你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32WB55 如何一次性发送和接收超过100字节的数据包?

[复制链接]
jimmy20080105 提问时间:2020-5-28 16:01 /
     大家好,我使用的开发板是“STM32WB55 Nucleo”开发板,想实现一次性发送和接收超过100个字节的数据包(数据包字节数越多越好,如果能达到250个字节就最好了)。蓝牙底层数据包默认大小大概是20字节。蓝牙协议提到的包格式中的PDU大小为2~257字节。     软件库:STM32Cube_FW_WB_V1.7.0, 使用例程:BLE_p2pServer。
     该例程主要是实现蓝牙控制LED1的亮灭。蓝牙调试助手发送0x00 0x01 --> LED1亮,0x00 0x00-->LED1灭。
但是不能接收超过2个字节的数据,蓝牙调试助手发送时显示“成功写入”,但是没有触发P2PS_STM_App_Notification()函数中的事件P2PS_STM_WRITE_EVT
  1. <blockquote>void P2PS_STM_App_Notification(P2PS_STM_App_Notification_evt_t *pNotification)
复制代码
然后我将P2PS_STM_Init() 中的 aci_gatt_add_char()函数中的Char_Value_Length改为150,请看注释。蓝牙助手发送64个字节,P2PS_STM_WRITE_EVT触发4次,每个包最大20字节。
  1. void P2PS_STM_Init(void)
  2. {

  3.   Char_UUID_t  uuid16;

  4.   /**
  5.    *        Register the event handler to the BLE controller
  6.    */
  7.   SVCCTL_RegisterSvcHandler(PeerToPeer_Event_Handler);
  8.   
  9.     /**
  10.      *  Peer To Peer Service
  11.      *
  12.      * Max_Attribute_Records = 2*no_of_char + 1
  13.      * service_max_attribute_record = 1 for Peer To Peer service +
  14.      *                                2 for P2P Write characteristic +
  15.      *                                2 for P2P Notify characteristic +
  16.      *                                1 for client char configuration descriptor +
  17.      *                                
  18.      */
  19.     COPY_P2P_SERVICE_UUID(uuid16.Char_UUID_128);
  20.     aci_gatt_add_service(UUID_TYPE_128,
  21.                       (Service_UUID_t *) &uuid16,
  22.                       PRIMARY_SERVICE,
  23.                       8,
  24.                       &(aPeerToPeerContext.PeerToPeerSvcHdle));

  25.     /**
  26.      *  Add LED Characteristic
  27.      */
  28.     COPY_P2P_WRITE_CHAR_UUID(uuid16.Char_UUID_128);
  29.     aci_gatt_add_char(aPeerToPeerContext.PeerToPeerSvcHdle,
  30.                       UUID_TYPE_128, &uuid16,
  31.                       150,//2,  //由2改为150
  32.                       CHAR_PROP_WRITE_WITHOUT_RESP|CHAR_PROP_READ,
  33.                       ATTR_PERMISSION_NONE,
  34.                       GATT_NOTIFY_ATTRIBUTE_WRITE, /* gattEvtMask */
  35.                       10, /* encryKeySize */
  36.                       1, /* isVariable */
  37.                       &(aPeerToPeerContext.P2PWriteClientToServerCharHdle));

  38.     /**
  39.      *   Add Button Characteristic
  40.      */
  41.     COPY_P2P_NOTIFY_UUID(uuid16.Char_UUID_128);
  42.     aci_gatt_add_char(aPeerToPeerContext.PeerToPeerSvcHdle,
  43.                       UUID_TYPE_128, &uuid16,
  44.                       150,//2,//由2改为150
  45.                       CHAR_PROP_NOTIFY,
  46.                       ATTR_PERMISSION_NONE,
  47.                       GATT_NOTIFY_ATTRIBUTE_WRITE, /* gattEvtMask */
  48.                       10, /* encryKeySize */
  49.                       1, /* isVariable: 1 */
  50.                       &(aPeerToPeerContext.P2PNotifyServerToClientCharHdle));

  51. #if(BLE_CFG_OTA_REBOOT_CHAR != 0)      
  52.     /**
  53.      *  Add Boot Request Characteristic
  54.      */
  55.     aci_gatt_add_char(aPeerToPeerContext.PeerToPeerSvcHdle,
  56.                       BM_UUID_LENGTH,
  57.                       (Char_UUID_t *)BM_REQ_CHAR_UUID,
  58.                       BM_REQ_CHAR_SIZE,
  59.                       CHAR_PROP_WRITE_WITHOUT_RESP,
  60.                       ATTR_PERMISSION_NONE,
  61.                       GATT_NOTIFY_ATTRIBUTE_WRITE,
  62.                       10,
  63.                       0,
  64.                       &(aPeerToPeerContext.RebootReqCharHdle));
  65. #endif   

  66.    
  67.   return;
  68. }
复制代码
将发送函数改为发送50个字节,请看注释,STM32WB55只能发送20个字节数据(数据:0x01~0x14)。
  1. tBleStatus P2PS_STM_App_Update_Char(uint16_t UUID, uint8_t *pPayload)
  2. {
  3.   tBleStatus result = BLE_STATUS_INVALID_PARAMS;
  4.   switch(UUID)
  5.   {
  6.     case P2P_NOTIFY_CHAR_UUID:
  7.       
  8.      result = aci_gatt_update_char_value(aPeerToPeerContext.PeerToPeerSvcHdle,
  9.                              aPeerToPeerContext.P2PNotifyServerToClientCharHdle,
  10.                               0, /* charValOffset */
  11.                                50,//2, /* charValueLen //改为50个字节
  12.                              (uint8_t *)  pPayload);
  13.    
  14.       break;

  15.     default:
  16.       break;
  17.   }

  18.   return result;
  19. }/* end P2PS_STM_Init() */
复制代码
  1. void P2PS_Send_Notification(void)
  2. {
  3.   uint8_t data[50];
  4.   for (int i=0; i<50; i++)
  5.   {
  6.     data[i] = i+1;
  7.   }
  8.   
  9.   if(P2P_Server_App_Context.ButtonControl.ButtonStatus == 0x00){
  10.     P2P_Server_App_Context.ButtonControl.ButtonStatus=0x01;
  11.   } else {
  12.     P2P_Server_App_Context.ButtonControl.ButtonStatus=0x00;
  13.   }
  14.   
  15.    if(P2P_Server_App_Context.Notification_Status){
  16.     APP_DBG_MSG("-- P2P APPLICATION SERVER  : INFORM CLIENT BUTTON 1 PUSHED \n ");
  17.     APP_DBG_MSG(" \n\r");
  18.     P2PS_STM_App_Update_Char(P2P_NOTIFY_CHAR_UUID, data);//改为发送50个字节数据
复制代码

     我还发现程序运行一段时间(大概5分钟),就提示“Fatal error:ST-Link USB communication error, Session abort!”,我调试的其他的STM32单片机很少出现过ST Link断开连接的问题。




收藏 评论4 发布时间:2020-5-28 16:01

举报

4个回答
奏奏奏 回答时间:2020-5-29 06:51:24
如果没办法,只能长数据包分拆为多包处理
之前用CAN总线传输就是这样,标准CAN总线(不算FD-CAN能到64字节每包)每包最多8个字节
设备上报MCU的(准确来说是STM32的)UID序列号,只能分拆为3包传
接收设备端再按照协议拼包,注意丢了其中1包或者包顺序错乱的容错处理
协议中必须包含一共多少包、当前是第几包、拼包后完整性校验信息

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

jimmy20080105 回答时间:2020-5-29 10:11:11
奏奏奏 发表于 2020-5-29 06:51
如果没办法,只能长数据包分拆为多包处理
之前用CAN总线传输就是这样,标准CAN总线(不算FD-CAN能到64字节 ...

谢谢您的回复。
如果分包的话,不足之处就是接收到的数据包之间的间隔是不定的。有时候是1ms,有时候会达到30ms以上了。CAN的多个数据包之间的延时小于5ms,能很好判断数据帧的成帧时间。
实际使用过程中,数据包大小在100到250字节之间。如果能不分包的话,那传输的效率就有了很大的提升,大大减小了软件设计的复杂性了。

搜狗截图20200529102604.jpg
butterflyspring 回答时间:2020-6-8 11:49:04
单次接收应该不能超过247bytes,参考如下结构体, 从AN5270 Table 365. ACI_GATT_READ_EXT_EVENT event parameters,可以读取超过247Bytes,但是数据可能通过多个ACI_GATT_READ_EXT_EVENT上报,是否有更多数据,需通过offset的bit 15来判断。

可以参考下面的例程
C:\Users\min du\STM32Cube\Repository\STM32Cube_FW_WB_V1.7.0\Projects\P-NUCLEO-WB55.Nucleo\Applications\BLE\BLE_DataThroughput

jimmy20080105 回答时间:2020-6-10 09:45:16
STM32Cube_FW_WB_V1.7.0\Projects\P-NUCLEO-WB55.Nucleo\Applications\BLE\BLE_DataThroughput:

使用该例程,手机端蓝牙助手不能发现“DT_SERVER”
STM32Cube_FW_WB_V1.3.0\Projects\P-NUCLEO-WB55.Nucleo\Applications\BLE\BLE_DataThroughput:

使用该例程,手机端蓝牙助手可以发现“DT_SERVER”。


按下开发板上的SW1键后,设备一直发送数据。直到再次按下SW1键后停止发送,SendData()--》DTS_STM_UpdateChar()返回BLE_STATUS_SUCCESS后一直请求发送,UTIL_SEQ_SetTask(1 << CFG_TASK_DATA_TRANSFER_UPDATE_ID, CFG_SCH_PRIO_0);。
但是请求发送的字节数为240字节。DataTransferServerContext.TxData.Length = DATA_NOTIFICATION_MAX_PACKET_SIZE; (240)
发送流程如下:
SendData()-》DTS_STM_UpdateChar()-》TX_Update_Char()--》
  ret = aci_gatt_update_char_value(
                                   aDataTransferContext.DataTransferSvcHdle,
                                   aDataTransferContext.DataTransferTxCharHdle,
                                   0, /* charValOffset */
                                   pDataValue->Length, /* charValueLen */  这里的Length=240,调试时确定。
                                   (uint8_t *) pDataValue->pPayload);

蓝牙调试.jpg
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版