CH58x/CH59x 主(central)从机(peripheral)收发数据说明

前言:在日常的BLE的使用中基本都需要实现主从机的数据交互。

一般使用手机APP和从机通信,APP枚举服务之后通过对应服务下的特征值去进行调试。

蓝牙从机:

peripheral例程:

例程中通过一个tmos任务定时1s向主机发送0x88。具体任务如下方截图

 正常任务的调用可以依据自己的需求进行调用,从机NOTIFY向主机发送数据的函数:

 1 static void peripheralChar4Notify(uint8_t *pValue, uint16_t len)
 2 {
 3     attHandleValueNoti_t noti;
 4     if(len > (peripheralMTU - 3))
 5     {
 6         PRINT("Too large noti\n");
 7         return;
 8     }
 9     noti.len = len;
10     noti.pValue = GATT_bm_alloc(peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0);
11     if(noti.pValue)
12     {
13         tmos_memcpy(noti.pValue, pValue, noti.len);
14         if(simpleProfile_Notify(peripheralConnList.connHandle, &noti) != SUCCESS)
15         {
16             GATT_bm_free((gattMsg_t *)&noti, ATT_HANDLE_VALUE_NOTI);
17         }
18     }
19 }

如需要使用read发送:

static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
                                          uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method)
{
    bStatus_t status = SUCCESS;


    // Make sure it's not a blob operation (no attributes in the profile are long)
    if(offset > 0)
    {
        return (ATT_ERR_ATTR_NOT_LONG);
    }

    if(pAttr->type.len == ATT_BT_UUID_SIZE)
    {
        // 16-bit UUID
        uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
        switch(uuid)
        {
            // No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
            // gattserverapp handles those reads

            // characteristics 1 and 2 have read permissions
            // characteritisc 3 does not have read permissions; therefore it is not
            //   included here
            // characteristic 4 does not have read permissions, but because it
            //   can be sent as a notification, it is included here
            case SIMPLEPROFILE_CHAR1_UUID:
                if(maxLen > SIMPLEPROFILE_CHAR1_LEN)
                {
                    *pLen = SIMPLEPROFILE_CHAR1_LEN;
                }
                else
                {
                    *pLen = maxLen;
                }
                tmos_memcpy(pValue, pAttr->pValue, *pLen);
                break;

接收主机write的数据:

 1 static void simpleProfileChangeCB(uint8_t paramID, uint8_t *pValue, uint16_t len)
 2 {
 3     switch(paramID)
 4     {
 5         case SIMPLEPROFILE_CHAR1:
 6         {
 7             uint8_t newValue[SIMPLEPROFILE_CHAR1_LEN];
 8             tmos_memcpy(newValue, pValue, len);
 9             PRINT("profile ChangeCB CHAR1.. \n");
10             break;
11         }
12 
13 //        case SIMPLEPROFILE_CHAR3:
14 //        {
15 //            uint8_t newValue[SIMPLEPROFILE_CHAR3_LEN];
16 //            tmos_memcpy(newValue, pValue, len);
17 //            PRINT("profile ChangeCB CHAR3..\n");
18 //            break;
19 //        }
20 
21         default:
22             // should not reach here!
23             break;
24     }
25 }

ble_uart例程:

数据接收:

发送数据:

  if(events & UART_TO_BLE_SEND_EVT)在这个事件中完成发送,这里通过接收到串口的数据然后再通过notify发送给手机APP。

二、蓝牙主机

使用手机APP时这里就不再赘述。

当使用CH5XX系列的BLE主机是,centra例程,主机读写代码:

 1     if(events & START_READ_OR_WRITE_EVT)
 2     {
 3         if(centralProcedureInProgress == FALSE)
 4         {
 5             if(centralDoWrite)
 6             {
 7                 // Do a write
 8                 attWriteReq_t req;
 9 
10                 req.cmd = FALSE;
11                 req.sig = FALSE;
12                 req.handle = centralCharHdl;
13                 req.len = 1;
14                 req.pValue = GATT_bm_alloc(centralConnHandle, ATT_WRITE_REQ, req.len, NULL, 0);
15                 if(req.pValue != NULL)
16                 {
17                     *req.pValue = centralCharVal;
18 
19                     if(GATT_WriteCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS)
20                     {
21                         centralProcedureInProgress = TRUE;
22                         centralDoWrite = !centralDoWrite;
23                         tmos_start_task(centralTaskId, START_READ_OR_WRITE_EVT, DEFAULT_READ_OR_WRITE_DELAY);
24                     }
25                     else
26                     {
27                         GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ);
28                     }
29                 }
30             }
31             else
32             {
33                 // Do a read
34                 attReadReq_t req;
35 
36                 req.handle = centralCharHdl;
37                 if(GATT_ReadCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS)
38                 {
39                     centralProcedureInProgress = TRUE;
40                     centralDoWrite = !centralDoWrite;
41                 }
42             }
43         }
44         return (events ^ START_READ_OR_WRITE_EVT);
45     }

主机接收从机notify的数据:

 需要注意的是需要先写CCCD:

    if(events & START_WRITE_CCCD_EVT)
    {
        if(centralProcedureInProgress == FALSE)
        {
            // Do a write
            attWriteReq_t req;

            req.cmd = FALSE;
            req.sig = FALSE;
            req.handle = centralCCCDHdl;
            req.len = 2;
            req.pValue = GATT_bm_alloc(centralConnHandle, ATT_WRITE_REQ, req.len, NULL, 0);
            if(req.pValue != NULL)
            {
                req.pValue[0] = 1;
                req.pValue[1] = 0;

                if(GATT_WriteCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS)
                {
                    centralProcedureInProgress = TRUE;
                }
                else
                {
                    GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ);
                }
            }
        }
        return (events ^ START_WRITE_CCCD_EVT);
    }

central目前是通过UUID去枚举从机的服务,当前的主机例程可以直接和peripheral例程直接通信,如果需要和ble_uart通信可根据ble_uart的uuid去修改主机的程序。

如果需要修改特征值可以参考CH592/CH582/CH573/CH579服务修改 - 小舟从此逝_1 - 博客园

 

posted @ 2025-04-27 13:39  小舟从此逝_1  阅读(241)  评论(0)    收藏  举报