微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI蓝牙设计交流 > 关于CC2541蓝牙从模块数据通信问题

关于CC2541蓝牙从模块数据通信问题

时间:10-02 整理:3721RD 点击:

江湖救急:

   请问蓝牙CC2540从模块的数据接收函数simpleProfileChangeCB,默认一次接收一个字节数据,怎样设置一次性接收多个字节数据,谢谢。

hi:

   1、你设置成一个数组就可以了,像下面这样:

{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&userDefCharProps
},

// user defined Characteristic UUID
{
{ ATT_UUID_SIZE, userDefUUID },
GATT_PERMIT_READ|GATT_PERMIT_WRITE ,
0,
(uint8 *)&userDefVal 
},

2、希望可以帮到你,祝你早日解决问题,并分享一下解决问题的方法,谢谢!

HI:mark xu1

很高兴能收到您的回复,关于您说的设置成一个数组,我这样处理不知行不行:

1 特征值设置成一个数组:

2,设置特征参数

 

3读取特征值

4 写入特征值

 

5  读数据

 

6  读数据子函数

 

mark xu1  您好,以上就是我为读取多字节的数据所做的修改,用官方安卓APP给蓝牙从模块发送一个数据,蓝牙能收到,但发送多个字节数据时,APP显示 ERROR:13,不知这样修改正确与否,刚接触蓝牙不久,期待您的回复,谢谢

大体看了一下,应该没什么问题,可以试一下

好的,谢谢,用手机APP不行,只能发送一个自己,准备用central主模块试下

另外,请取特征值的地方是不是应该这样写:

你好,应该怎么写,不是很懂你的意思。

mark xu1:

你好,还是不能解决,仍然只能收到一个字节,是不是哪里设置不正确呢?谢谢

1、我profile配置如下所示:

// 自定义的UUID的属性
static uint8 testCharProps = (GATT_PROP_READ | GATT_PROP_WRITE);
// 该数组一定要初始化
static uint8 testVal[TEST_VAL_LEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

// 自定义的UUID的属性
static uint8 othersCharProps = (GATT_PROP_READ | GATT_PROP_WRITE);
static uint8 othersVal=0;

// User defined Service Atttribute Table
static gattAttribute_t eCigAttrTbl[] =
{
// primary service
{
{ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
GATT_PERMIT_READ, /* permissions */
0, /* handle */
(uint8 *)&userDefService /* pValue */
},

//---------------------------test UUID-----------------------------------
// Characteristic Declaration for test UUID
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&testCharProps
},

// Characteristic Test UUID
{
{ ATT_UUID_SIZE, setdevnameUUID },
GATT_PERMIT_READ|GATT_PERMIT_WRITE ,
0,
(uint8 *)&testVal
},

//---------------------------others UUID-----------------------------------
// Characteristic Declaration for test UUID
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&othersCharProps
},

// Characteristic others UUID
{
{ ATT_UUID_SIZE, othersUUID },
GATT_PERMIT_READ|GATT_PERMIT_WRITE ,
0,
&testVal
},


};


/*********************************************************************
* LOCAL FUNCTIONS
*/
static uint8 userDef_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen );
static bStatus_t userDef_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint8 len, uint16 offset );

static void userDef_HandleConnStatusCB( uint16 connHandle, uint8 changeType );


/*********************************************************************
* PROFILE CALLBACKS
*/
// User Service Callbacks
CONST gattServiceCBs_t userDef_CBs =
{
userDef_ReadAttrCB, // Read callback function pointer
userDef_WriteAttrCB, // Write callback function pointer
NULL // Authorization callback function pointer
};

/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn userDef_AddService
*
* @brief Initializes the Simple Key service by registering
* GATT attributes with the GATT server.
*
* @param services - services to add. This is a bit map and can
* contain more than one service.
*
* @return Success or Failure
*/
bStatus_t eCig_AddService( uint32 services )
{
uint8 status = SUCCESS;

// Initialize Client Characteristic Configuration attributes
// 这一句可以不要,除非你想配置成notify等属性
// GATTServApp_InitCharCfg( INVALID_CONNHANDLE, userKeyConfig );

// Register with Link DB to receive link status change callback
VOID linkDB_Register( userDef_HandleConnStatusCB );

if( services & PP_ELE_CIG_SERVICE)
{
// Register attribute list and CBs with GATT Server App
status = GATTServApp_RegisterService( userDefAttrTbl,
GATT_NUM_ATTRS( userDefAttrTbl ),
&userDef_CBs );
}

return ( status );
}


/*********************************************************************
* @fn userDef_RegisterAppCBs
*
* @brief Register a callback function with the xx Service.
*
* @param pfnServiceCB - Callback function.
*
* @return None.
*/
bStatus_t eCuserDef_RegisterAppCBs(CigCBs_t *pfnServiceCB)
{
if ( pfnServiceCB )
{
userDefServiceCB = pfnServiceCB;
return ( SUCCESS );
}
else
{
return ( bleAlreadyInRequestedMode );
}
}


/*********************************************************************
* @fn userDef_SetParameter
*
* @brief Set a Eletronic cigarette Profile parameter.
*
* @param param - Profile parameter ID
* @param len - length of data to write
* @param pValue - pointer to data to write. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16 will be cast to
* uint16 pointer).
*
* @return bStatus_t
*/
bStatus_t userDef_SetParameter( uint8 param, uint8 len, void *pValue )
{
bStatus_t ret = SUCCESS;
switch ( param )
{
case PP_TEST_UUID_ATTR:
{
osal_memset( testVal, 0, TEST_VAL_LEN); // 先把数组清零
osal_memcpy(testVal, pValue, TEST_VAL_LEN); // 再把设置的值放进去
}
break;

case PP_OTHERS_UUID_ATTR : // 设置单个数据的也举个例子吧
{
if ( len == sizeof ( uint8 ) )
{
othersVal = *((uint8*)pValue);
}
else
{
ret = bleInvalidRange;
}
}
break;

default :{ ret = INVALIDPARAMETER; }
break;
}

return ( ret );
}


/*********************************************************************
* @fn userDef_GetParameter
*
* @brief Get a userDef Profile parameter.
*
* @param param - Profile parameter ID
* @param pValue - pointer to data to put. This is dependent on
* the parameter ID and WILL be cast to the appropriate
* data type (example: data type of uint16 will be cast to
* uint16 pointer).
*
* @return bStatus_t
*/
bStatus_t userDef_GetParameter( uint8 param, void *pValue )
{
bStatus_t ret = SUCCESS;
switch ( param )
{
case PP_TEST_UUID_ATTR: // get test UUID value
memcpy(pValue,testVal,sizeof(testVal));
break;

case PP_OTHERS_UUID_ATTR: // get others UUID vale
*((uint8*)pValue) = othersVal;
break;


default:
ret = INVALIDPARAMETER;
break;
}

return ( ret );
}


/*********************************************************************
* @fn userDef_ReadAttrCB
*
* @brief Read an attribute.
*
* @param connHandle - connection message was received on
* @param pAttr - pointer to attribute
* @param pValue - pointer to data to be read
* @param pLen - length of data to be read
* @param offset - offset of the first octet to be read
* @param maxLen - maximum length of data to be read
*
* @return Success or Failure
*/
static uint8 userDef_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen )
{
bStatus_t status = SUCCESS;

if ( pAttr->type.len == ATT_UUID_SIZE )
{
// 128-bit UUID
// Convert the 128 bits uuid
uint16 my_uuid = UUID128_CONVER(pAttr->type.uuid); // 这是我自定义的函数

switch ( my_uuid )
{
case UUID_TEST:
{
// verify offset
if (offset >= sizeof(testVal))
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
// determine read length
*pLen = MIN(maxLen, (sizeof(testVal) - offset));

// copy data
memcpy(pValue, &testVal[offset], *pLen);
}
}
break;

case UUID_OTHERS:
{
// verify offset
if (offset > 0)
{
status = ATT_ERR_INVALID_OFFSET;
}
else{
*pLen = 1;
pValue[0] = othersVal;
}
}
break;
default:
{
// Should never get here!
*pLen = 0;
status = ATT_ERR_ATTR_NOT_FOUND;
}
break;
}
}
else
{
// 16-bit UUID
*pLen = 0;
status = SUCCESS;
}

return ( status );
}


/*********************************************************************
* @fn userDef_WriteAttrCB
*
* @brief Validate attribute data prior to a write operation
*
* @param connHandle - connection message was received on
* @param pAttr - pointer to attribute
* @param pValue - pointer to data to be written
* @param len - length of data
* @param offset - offset of the first octet to be written
* @param complete - whether this is the last packet
* @param oper - whether to validate and/or write attribute value
*
* @return Success or Failure
*/

static bStatus_t userDef_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint8 len, uint16 offset )
{
bStatus_t status = SUCCESS;
if ( pAttr->type.len == ATT_UUID_SIZE )
{
// 128-bit UUID
// Convert the 128 bits uuid
uint16 my_uuid = UUID128_CONVER(pAttr->type.uuid); // 这是我自定义的函数

switch ( my_uuid )
{
case UUID_TEST: // device name
{
// verify offset
if (offset > 0)
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
// copy data
uint8 i;
for(i=0;i < TEST_VAL_LEN; i++)
testVal[i] = 0;

memcpy(testVal, pValue, MIN(len, TEST_VAL_LEN));
}

if ( userDefServiceCB )
userDefServiceCB->pfnAttrChange(TEST_UUID_VAL_CHG); // 这一句一定要写,不然系统不知道更改了
}
break;
case UUID_OTHERS: // set output power mode
{
// verify offset
if (offset > 0)
{
status = ATT_ERR_INVALID_OFFSET;
}
else
{
othersVal = pValue[0];
}

if ( userDefServiceCB )
{
userDefServiceCB->pfnAttrChange(OTHERS_UUID_VAL_SET);
}
}
break;

default:
// Should never get here!
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
}
else
{
// 16-bit UUID
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);

switch ( uuid )
{
case GATT_CLIENT_CHAR_CFG_UUID:
status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_NOTIFY );
/*callback ualertServiceCB()*/
break;

default:
// Should never get here!
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
}
return ( status );
}

/*********************************************************************
* @fn userDef_HandleConnStatusCB
*
* @brief Profile link status change handler function.
*
* @param connHandle - connection handle
* @param changeType - type of change
*
* @return none
*/

static void userDef_HandleConnStatusCB( uint16 connHandle, uint8 changeType )
{
// Make sure this is not loopback connection
if ( connHandle != LOOPBACK_CONNHANDLE )
{
// Reset Client Char Config if connection has dropped
if ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED ) ||
( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) &&
( !linkDB_Up( connHandle ) ) ) )
{
GATTServApp_InitCharCfg( connHandle, XXConfig ); // 如果要设置成notify,则这样写,可以参看TI例程中按键及电池电量的写法
// 这里就不详述了
}
}
}

2、附上附件,

    7801.userDefProfile.c

3、希望可以帮到你,祝你早日解决问题,并分享一下解决问题的方法,谢谢!(也可以加群:422240210)

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top